How to store authenticated user in JASPIC?
I developed a Security Authentication Module (SAM) and implemented the method validateRequest
. I also have a simple webapp configured to use this SAM.
In my method, validateRequest
I check the clientSubject and install CallerPrincipalCallback
with a hardcoded username and GroupPrincipalCallback
a hardcoded group name:
final CallerPrincipalCallback callerPrincipalCallback = new CallerPrincipalCallback(clientSubject, "anonymous");
final GroupPrincipalCallback groupPrincipalCallback = new GroupPrincipalCallback(clientSubject, new String[] {"user"});
try {
this.handler.handle(new Callback[] {callerPrincipalCallback, groupPrincipalCallback});
} catch (IOException | UnsupportedCallbackException e) {
logger.error(e.getMessage());
}
I noticed that every time I update my servlet in the webapp, the client object is simply empty logger.debug("Client: {}", clientSubject);
:
2015-05-05 11:21:02,200 DEBUG n.m.j.s.Saml2AuthModule [http-listener-1(2)] Client: Subject:
Is it possible to "save" the topic in some way so that the object is attached to the session and I can just skip the logging by the same user every time?
EDIT I think I found a way by manually saving it to HttpSession
: req.getSession().setAttribute("subject", user);
Not really, but it works.
source to share
Is it possible to "save" the topic in some way so that the object is attached to the session and I can just skip the logging by the same user every time?
Yes, although JASPIC was designed to be stateless, it does have the ability to semi-automatically remember the input.
This setting, however, is not much less code than just storing the details in the session and re-authenticating at the start of each request.
The way to do this is to first set a boolean on the message info card before returning SUCCESS and exit validateRequest
:
messageInfo.getMap().put("javax.servlet.http.registerSession", TRUE.toString());
Then, at the beginning of each request, your Authentication Module (SAM) is still called, but you can execute the following "protocol" to reuse the stored credentials (username + roles):
HttpServletRequest request = (HttpServletRequest) messageInfo.getRequestMessage();
Principal userPrincipal = request.getUserPrincipal();
if (userPrincipal != null) {
handler.handle(new Callback[] {
new CallerPrincipalCallback(clientSubject, userPrincipal) }
);
return SUCCESS;
}
I wrote a blog post with more details. You can find a test that uses a fully working example in a Java EE 7 project .
Unfortunately, there is no function in JASPIC to say that you don't want SAM to be called at all as long as the session (http) is valid.
If you need this feature, please vote for the following issue: https://java.net/jira/browse/JASPIC_SPEC-20
I think I found a way by manually storing it in HttpSession: req.getSession (). setAttribute ("subject", user); Not really, but it works.
A more or less "official" way is to store the username and roles within the session, then validateRequest
check at the beginning of each call to see if this data is present, and if so, pass it to two callbacks.
The method I showed above is not really similar to this one, but apart from the obvious differences (one callback versus two, getting the principal from the request and getting it from the session), the main difference is that using a semi-automatic path, the container can use any mechanism for storing data.
It can only be an attribute in the session again (a simple JASPIC implementation can certainly do this), or it can use some hidden part of the session that most containers have. This hidden part is not directly accessible to the user code, which may have some advantages.
source to share