We're currently adopting JAAS and JACC using JBoss EAP 6.4/7.0. Just a brief explanation on how we are applying things:
we use HttpServletRequest.login(...) to authenticate
subsequently, we use HttpServletRequest.logout() to log out.
we have a LoginModule which validates the credentials and preps up the Roles.
All is well and good, however, part of my application must allow a certain set of users to be able to:
revoke someone else's Role to log into the system, and
kick out them out of any currently-active sessions.
The first part is easy, but I am having a hard time trying to figure out how I could invalidate someone's session. Is there a way I could somehow get hold of some other user's Subject/Session and invalidate it?
Much appreciated
Note on terminology:
Authentication Mechanism (AM) herein refers to any component responsible for making authentication statements pertaining to, and registering / establishing, as a result, the identity of, authenticated caller entities with / in a Java EE runtime. Such components may be specific to the Application Server (AS) or Java EE-standard; AS implementation details or types destined for extension by the Java EE application developer; deployed as part of a Java EE application or as part of the AS. One such component is your JAAS LoginModule (LM). While Identity Store (IS) appears to be the (semi-)normative term used for referring to (among other things) LMs nowadays, I wanted to reserve it for your application-specific, persistence layer (e.g. JPA #Entity) types representing your users, and thus had to establish this (ill-defined) distinction. "Why are you being vague?", you might ask, "Can't you just call an LM an LM?". Because I know nothing about JBoss LMs! In fact, I am neither a JBoss user, nor someone using JAAS in Java EE. Still, I felt like I could contribute an answer applying to the general case, hence the inevitable vagueness.
Deactivated user refers, for lack of a better term, to your "to-be-kicked-out-user", i.e., the user whose rights (groups, roles, permissions--whatever they are called in there) have been revoked in some way at the IS level.
First of all, there is no standard Java EE API that will expose the Subject or HttpSession of an arbitrary user to your code. You could theoretically record that information yourself, e.g. during authentication, but I will assume that this is not quite what you want. Furthermore, regarding the Subject specifically, while no standard explicitly forbids its (Principal / credential collection's) modification during servicing of a request on the Subject's behalf, none state that it has to be either. It is in fact not even clear whether the current authenticated caller's Subject--the one populated during authentication and retrievable via JACC's "javax.security.auth.Subject.container" PolicyContextHandler--must coincide with the data structure the runtime queries the Policy with when making authorization decisions; that is, the runtime might only provide you with a copy, use an entirely different representation of the authenticated caller internally, or anything in between. Therefore, even if you were able to modify the Subject, doing so would not necessarily affect the security context in effect.
Moving on to what can be done. Your need can be addressed either on the authentication and/or on the authorization side, with the former approach being considerably easier to employ than the later. Since you did not answer my comment, I will briefly cover both of its possible answers.
Prohibiting caller re-authentication
Once the application has deactivated the user, it must somehow instruct the AM to cease re-authenticating them on subsequent requests they issue. In order to reduce coupling, the application will typically not communicate with the AM directly, but satisfy some condition evaluated by the later instead. For instance, the application might assign some special "locked_out" right to the user, or set an HttpSession attribute. When asked to re-authenticate the deactivated user, the AM would acknowledge deactivation and refuse to re-authenticate them. Subsequently it would invalidate the user's session. How exactly it would accomplish that depends on its kind and implementation. Your LM would probably have to leverage the "javax.servlet.http.HttpServletRequest" JACC PolicyContextHandler for that purpose. A JASPIC ServerAuthModule would have immediate access to the request instance, having received it as a validateRequest argument. Some other component would perhaps have to resort to use of AS internals, or burden the application with the responsibility of session invalidation (some call-intercepting component, such as a Servlet Filter, would have to query the IS a second time and act accordingly).
The aforementioned approach obviously requires the ability to modify the functionality of the AM. Additionally, a caching AM needs to evaluate said deactivation condition before reusing its previously established authentication outcome. Lastly, as mentioned in the comment, if, at the time of a user's IS access revocation, a request on that user's behalf is in the process of being serviced (having arrived / having been authenticated prior to the occurrence of the access revocation event), servicing of that request will complete normally (unless the application requests re-authentication of that user, e.g. via HttpServletRequest#(login|authenticate).
Prohibiting caller re-authorization
While, as I mentioned in the begining, users' Subjects are not readily retrievable / modifiable, the backing Policy, against which, on JACC-compliant Java EE runtimes those get authorized, actually is. Unfortunately, the default AS-provided JACC provider (PolicyConfiguration + Policy) has a serious limitation: it only allows you to operate on Java EE roles, not on the caller Principals mapped to, i.e., "having", those roles. For example, the default provider allows you to extend the Permissions that Principals mapped to the "admin" role have; it allows you to remove the "admin" role along with all its Permissions; but it does not allow you to decide who gets to be an "admin"--at least not in a standard way.
This limitation basically leaves you with two alternatives, as far as JACC is concerned: Either have the AM add a "dummy" group Principal to each caller's Subject, with the same name as that of the respective caller Principal. Then, upon user deactivation, add (via PolicyConfiguration#addToRole) a custon Permission pertaining to the "dummy" group. Finally, check (e.g. via AccessController#checkPermission) from "application-space" code whether the user has the Permission and if so kick them out. But wait, this is utterly meaningless--why even bother using the Policy in the first place, if it is incapable of handling authorization on its own? The alternative is to author and install your own JACC provider. Doing so would give you full control over Principal-/group-to-role mappings and enable you to act pretty much however you please, authorization-wise, with that information from that point on. Writing a new provider is nontrivial though, particularly because it would have to accommodate for the authorization needs JRE-wide, not just in the scope of a single application. I doubt that your requirement justifies an amount of work that high. If you still feel like going down that path, the JACC-related articles on Arjan Tijms' blog are a great starting point.
Related
Scenario:
We want to connect to multiple AD domains to fetch AD object information.
For authentication, we want to use Kerberos.
This is done simultaneously, meaning, fetching data from multiple AD domains is expected to be done in a single request - either interchangeably or in multi-threaded environment.
The Problem:
Kerberos authentication takes time and is proving to be performance hit
So, caching the TGT credentials on the application machine would solve the issue for us
A single cache file stores only one principal TGT. So to support multiple domains, we have to persist multiple cache files and dynamically choose which cache file to be used for current context creation.
This is indeed a valid solution, but the problem is about the security concerns: How?
We are caching the TGT using kinit in different cache files, but the drawback of this solution is that, if the security of the application machine is compromised, then those TGTs could be utilized by any different applications for authentication (we want the lifetime of the TGTs to be more)
So, is there a way where we can utilize an in-memory cache? I am aware of the MEMORY: ccache configuration in the krb.conf file, but again, how can that solve the issue of caching multiple principal TGTs? I haven't tried this solution, but as far as I understand, the successive kinit calls would overwrite the previous principal TGT.
Would having different krb.conf files for each AD domain help us? I am yet to explore the concept of keytab, would that of any help in addressing our issue?
Please Note: I am new to this space and yet in the phase of learning the concepts along with the implementation. A few of the above points might feel like a guess work and indeed they are.
I am developing a multiplayer online game. I have the following issue:
When the user breaks his/her connection with the server, he needs to reconnect. At the first connection, during registration, the registration module produces a special ResponseDispatcher which holds the reference to the connection Channel. But if the user logs out, this Channel becomes invalid. Even though I can detect the problem and clean up resources, I have to store the reference to the registration module and Connection module to the game module, in order to renew the Channel when the user authorises and reconnects again. This creates a lot of interdependencies among modules and it gets really hard to maintain.
What I need is something like an HttpSession in Servlet Container, so that I can get the references to my channel and session resources from all modules of my server.
How is HttpSession implemented in Servlet? Is it a global hashmap storing all JSESSIONID, from which the container determines which attribute map to return? If it is a global sysmbol table, will it hit the performance (even though the time is O(1) for hashMap, there might be session modifications so it probably has to be synchronized)?
PS. Maybe some recommendations of design patterns for this case would also do.
I would recommend trying Shiro
Shiro can handle Session Management outside of a servlet container.
You may want to back Shiro with EhCache to provide proper caching and, if required, session persistence (and load balancing, etc...)
Have a look at the Facade Pattern
I'm not exactly sure what the question is. Why do you "have to store the reference to the registration module and connection module"?
Anyway there are two immediately sensible solutions to your problem.
1) Make the Registration module and Connection module Singletons. Whether this is useful depends entirely on what functionality these modules provide.
2) Make the Registration module and Connection module Persistent Entities, save them to a DataStore, complete with necessary references, and retrieve and rebuild them on reconnect.
I'm not quite sure why rolling your own session implementation would be something you want to do, what happens when the session times out?
Your design seems somewhat flawed. The player should not "still be online" if his connection goes down (this is a contradiction in terms, you cannot by definition be online if you are not connected to a network), regardless of whether this was intentional or not (you cannot know whether it is intentional or not), you have no idea whether the player is able to reconnect within a timely fashion or not, so you should assume the worst. More importantly, from a purely design aspect, getting killed by the game, because your internet connection is rubbish, is probably not something you want to deal with. If persisting data is such a costly affair you should reexamine your datastore options. Also, what happens in the scenario where the server crashes while he's offline?
We have a system that comprises of several functions and I am requested to separate some functionality from our existing system.
Basically, the system have only one user which has access to the whole system functionality, however, the requirement here is to limit the access some users have to the system.
I would appreciate some kind help in the direction i am suppose to take with this assignment.
Thanks in advance
PS if its not clear enough you can follow up by comment.
The first question you need to answer is - where do you want to keep your access information? i.e. who can access what. some options include a LDAP server, hard coding into the app, or some sort of encrypted file, etc. How you asnwer this will dictate the technology you use.
For example, if you decide to use a LDAP server, then you need to have your app setup a connection to it, prompt the user for a userid and password, logon, and retrieve their security groups. Then when you are setting up the GUI, you can query the retrieved groups to see what the user can see or access.
It's pretty much always a good idea to relate a user to one or more security groups. From there you can decide to either assign GUI functionality to individual groups, or to decouple a step further and assign function to privilages, and then define group to privilage relationships.
Java comes with JAAS which is a built in security framework. But it can take some time to get your head around and (AFAIK) is not a completely solution, just a starting point.
It also may be that you simply don't need anything as complex as LDAP and JAAS. If it's a simple app then perhaps you only need an admin id which only one or two people know the password to, and some shared other ids, in that case you can simply store the data in the app. Although this is the least flexible solution.
Finally you should make sure that the difficultly of accessing the system should match the importance of the information being stored. ie. don't put bank level security in front of editing the staff's contact information.
Are there any possible ways by which a malicious user on a web application can manipulate the input that is sent by the front-end of web application (not talking about the FORM DATA, of course) but the requests that are sent like for e.g., when I allow him to edit his profile or his content, he may manipulate the IDs (userId or the contentId) so that he may maliciously do evil with other users content? These inputs are fixed on a webpage & are not editable but still can the users manipulate them?
Is it possible that users may do harm in this manner? How can I safeguard my application against this? Besides, verifying user's identity and his contents/properties on the application prior to allowing each of his actions.
Yes of course. Anything that comes from the client can be modified and cannot be trusted at all.
You need to do server-side checks if the user is editing his own profile or something he's allowed to edit.
For things like editing the profile you could simply use the userid stored in his session though (assuming it's secure, i.e. stored server-side or in cryptographically signed cookies). Only let data go through the client if it's necessary - if the data is already available on the server, you don't even have to give the user the feeling that he might be able to tamper with it. Even though it could be used as a honey-pot - but that's not really the purpose of most webapps...
Yes, it is possible and it is a real danger.
There are two things you can do:
Implement an access control / permission system which controls which data records a user can access or modify.
Store information that is none of their business in a session object on the server.
(By the way, these are not exclusive options, ideally you should do both.)
Both solutions still leave you prone to session hijacking though, which is a different, more global problem.
I have a JSF web client and a Java client that both use the same stateless EJB layer for their application logic. I'm unsure of how to balance the need for performance (limiting the amount of data that is transported between the presentation and application layers) with security (in the sense of ensuring all decisions are made based on up to date data).
I understand that this is a subjective topic, so perhaps I can make it more objective with concrete examples:
Do I only send the username to the EJBs, and then load the User entity on each and every EJB call, or do I send the User entity from the presentation layers?
If I need more information than just the User entity (let's say I need to load an additional entity on each EJB call), do I send the username and the other entity's key and load both the entities in the application layer, or do I send both entites from the presentation layers?
What about if I need even more information for certain EJB calls (>= 3 entities)?
When does it make sense to send the actual entity instead of just its key, or is the answer never, always reload on the application layer side? Should I be worried about performance? I've heard that Hibernate (which I'm using) employs intelligent caching meaning the User entity probably won't be reloaded from the DB every time? What if my EJB methods have a very small granularity and frontend actions might sometimes cause 3 or more EJB methods to be called, with each needing to load the User entity?
A final related question: I intend on using the JAAS principal to store the username which is loaded by the EJBs. What if my Remote facade EJBs call a bunch of Local stateless EJBs that also require the user information, do I still use the JAAS principal and load the User entity in each of them as well or is there a better way?
You should consider stateful EJBs, since it sounds like the clients need non-trivial state to answer a series of requests concerning the same state from one user. That said, stateful EJBs are kind of a bear to write and configure properly.
As a matter of design, I would not have the clients send user information to the business logic layer. One, it just punts the problem over to the client, no? to load, store and send this info? also it makes me nervous from a security perspective, to let a presumably less-secure client tier feed sensitive user data to a more-secure backend-tier which then trusts and uses that info.
But, really, I think you mentioned the best approach already: Hibernate's lazy loading. You just interact with the object and let it load data on demand. To work well with Hibernate in this regard, the User object should be small, so that loading it is fairly quick, and push all the big, heavy info into child objects or other entities. Then it doesn't matter if you have to load User a lot; it's just a bit of a 'pointer' to other info.
I don't think it changes things if you use JAAS, no. Although I might say, for what I imagine your purposes are, JAAS may or may not be worthwhile. In the time it takes you to integrate, write permissions, use those permissions, deal with consequences of the SecurityManager, etc. you probably could have just written a simple permissions framework for yourself anyhow.
if you make just one EJB, make stateless session. personally i found it humbug empty interfaces