Each user in the system is assigned a Subject (RHQ_SUBJECT is the DB table). The user is typically authenticated by RHQ via the JDBCLoginModule. You can use LDAP for authentication, in which case LdapLoginModule will be invoked that performs the check against the configured LDAP server, but it only does authentication checks. Authorization is performed by roles created in the RHQ database. For this reason, even users that are authenticated via LDAP will still have a Subject entity associated with him. The difference is that a LDAP user will not have a Principal entity but users that are authenticated by RHQ will have an associated Principal object.
The JAAS module (JDBCLoginModule or LDAPLoginModule) is responsible for actually authenticating the user against the appropriate backend.
The J2EE "/j_security_check" redirects to AuthenticateUserAction which has the responsibility of logging the user into the RHQ system. This class does several things. The first is that it gets the user his RHQ session, which is different than the HTTP session the web container assigns the user. It will also set up the user's HTTP session witih information the core UI needs (like user preferences). This action also redirects the user to the self-service LDAP registration form when appropriate. This LDAP registration form allows the user to create his own Subject based on his LDAP identity (this LDAP form will only be seen by users that are authenticated by LDAP).
See the LDAP Integration page for more information on LDAP support
Finally there is AuthenticationFilter which is used to make sure users are logged in and their session is still valid when going to any URL (in the case of a bookmarked URL, this ensures the user is logged in; if not, the request is redirected to the login page).
Remote clients that call into the remote EJB interface or the Web Service API must first obtain a Subject for the client's identity. They do this by directly logging into the system via SubjectManager's login method. Once a subject is obtained, it is considered logged into the RHQ system. That subject is passed explicitly to the remote API.
Server-side code then utilizes either direct authorization checks (see AuthorizationManagerBean) or they rely on RHQ's built-in security interceptor (RequiredPermissionsInterceptor) to check that the passed-in subject has the appropriate permissions. That interceptor examines the invoked method and checks any permissions it requires - which is defined if they are annnotated with either RequiredPermission or RequiredPermissions.
>>
>> -----
>> Convo
>>
>> (17:55:27) joseph: so I notice that we don't protect the uninventory functionality with MANAGE_INVENTORY
>> (17:55:38) joseph: instead, we use the resource-level perm DELETE_RESOURCE
>> (17:55:41) joseph: does that sound right?
>> (17:55:45) ghinkle: hmm
>> (17:56:17) ghinkle: I think that's consistent
>> (17:56:21) joseph: seems like we either need to use the global perm, or if we want individual resource perm we need to create UNINVENTORY_RESOURCE
>> (17:58:13) ghinkle: that might be more confusing (the latter)
>> (18:00:47) joseph: delete vs. uninventory is confusing enough
>> (18:01:11) joseph: I don't remember how many support cases and forum threads asked what the difference was
>> So it turns out that the old struts-based inventory browser didn't have UI security around this. It would allow anyone to click uninventory, and would then give you that error message page:
>>
>> "Security Alert - The page requested cannot be displayed due to insufficient permissions. Please contact your RHQ Administrator to add the necessary permissions"
>>
>> Then, when the JSF-based inventory browser was written, I made the display of the uninventory button conditional on whether the user had the global MANAGE_INVENTORY perm. For the longest time, I had been under the assumption that that was correct. It never even crossed my mind that the resource-level DELETE_RESOURCE perm was how we were protecting the SLSB method, thus I didn't think twice about using that particular global perm.
>>
>> Now, we already protect the following inventoryStatus changes behind the global perm:
>>
>> * NEW-->COMMITTED
>> * NEW-->IGNORED
>> * IGNORED-->NEW
>>
>> But the follow changes are protected behind the resource-level DELETE permission:
>>
>> * COMMITTED-->DELETED
>> * COMMITTED-->UNINVENTORIED
>>
>> So deductively it seems that our rule is:
>>
>> "global perm is used before resources are in the inventory, but afterwards the resource perm takes over"
>>
>> Though in the future we're going to want to support IGNORING resources more robustly, so I could see the point in wanting to move committed resources directly to IGNORED state (so that they don't get rediscovered and reimported, if it's a service). Which means we'll have the following transition to support:
>>
>> * COMMITTED-->IGNORED
>>
>> Following our rule above, it would seem that this new state transition should be supported, but as you can see the only guy that has ever historically been allowed to even know about of the concept of ignored resources is the inventory manager. Perhaps, in this case, we wouldn't remove ignored resources from their group memberships? If we didn't, these non-inventory manager guys that have the DELETE permission could UNIGNORE the resources visible to them?
>>
>>
>> Anyway...so my question is, do we think this is still right (having DELETE_RESOURCE protect both resource uninventory actions as well as remote resource deletions)? If so, that's fine...
>> why isn't
>>
>> COMMITTED->UNINVENTORY
>>
>> protected by the global MANAGE_INVENTORY perm? Uninventorying affects the inventory, thus I would think only the inventory manager would be allowed to do this (since presumably its the person called the inventory manager that controls what resources belong in the managed inventory).
>>
>> Similarly, when implemented, I think
>>
>> COMMITTED-->IGNORED
>>
>> should also be protected by the global MANAGE_INVENTORY because that too only affects what is in inventory (i.e. what resources are to be managed).
>>
>> Neither uninventory nor ignored state affect the actual managed resource itself - just affects what's in inventory - thus I think MANAGE_INVENTORY would be appropriate.
>>
>>
>> Keep in mind that we also have the resource factory manager, which manages creating new resources (poor-man's provisioning) and remotely deleting resources (poor-man's decommissioning). Create new bypasses the import step because resources it creates are immediately put into the COMMITTED state and then sync'ed with the agent. A remote resource deletion performs the remote delete on the agent, and then makes it look like it's removed from inventory. What I'm getting at is that this is all about inventory control, which is related to what bundles do as well...and I notice that bundles are using a global permission.
>>
>> So I think on the one hand we do have a lot of inclination to move in the direction of anything related to manipulating logical inventory (and remote physical enterprise assets) as being a global permission, but then we have some functions that are at the resource-level. Really I could go either way. I could see some organizations wanting fine-grained control (like in RHEV where each individual operation on a resource can be granted access or denied via authz), but if we make the authorization system too complex then we risk people misunderstanding how to use it appropriately / effectively.
>>
>> One idea could be to combine the concepts of resource-create, resource-delete, and bundles into a single global permission called provisioning (and in the future bare-metal provisioning would also be bucketed into this perm). This way, we have reduces all of the inventory manipulations down to two global perms:
>>
>> manage_inventory - responsible for importing automatically discovered resources into inventory, or ignoring those which users don't want RHQ to be able to manage
>> provisioning - responsible for performing remote filesystem manipulations that amount to creating or deleting enterprise assets, whose remote state will automatically get sync'ed with RHQ's logical inventory view
>>
>> Another idea might be to move to a slightly more flexible security system. Maybe for JON 6.0 we can have the best of both worlds - coarse-grained security for those that want simplicity, and fine-grained security for those that want flexibility. Windows has an authorization mode called "simple file sharing" which has only 3 options: not shared, shared with read access, shared with read/write access - in other words, it's a global permission that doesn't depend on a user's credential check. However, you can enable the "advanced file sharing" option, which allows you to give finer-grained remote access to an explicit list of authorized/credentialed users on a file-by-file basis. So perhaps we can model that in RHQ too, where users can choose to install the "simple authz" system which authorizes all inventory manipulations via one (or two) global perms, but if they choose "advanced authz" then we implement as many inventory manipulations as possible backed by individual resource-level perms.