Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Soteria HttpMessageContext.setRegisterSession() not working as expected?

I have implemented a custom HttpAuthenticationMechanism subclass to provide authentication using the Soteria/Java EE Security framework. I've got authentication working just fine. However, I've noticed that when I call HttpMessageContext.setRegisterSession(String, Set<String>) to create a Java EE Session, the behavior is not what I would expect. I am expecting that the authenticated identity be associated with the web Session, and my AuthenticationMechanism's validateRequest(HttpServletRequest req, HttpServletResponse res, HttpMessageContext ctx) method would not be called on subsequent requests. What I am observing, however, is that validateRequest() is called on every request, even if the user has already authenticated successfully.

I am able to get the behavior I want using the @AutoApplySession annotation on my AuthenticationMechanism class, but that is not the behavior I want. I'd like to choose whether or not to create a session based on the type of credential provided.

Is my understanding of the setRegisterSession() method incorrect? Or is this a bug within Soteria?

like image 668
Shadowman Avatar asked Aug 03 '18 19:08

Shadowman


2 Answers

@AutoApplySession is the new way to do this in Soteria (JSR 375). If it does not suit your needs (as you need to either remember the authenticated identity or re-authenticate for all requests during the same HTTP session based on some other credential info), validateRequest method will still be called, regardless of whether you call the HttpMessageContext'ssetRegisterSession method or not. HttpMessageContext.setRegisterSession will make the container remember the credentials but will not reuse them automatically, you still need to make the container reuse the authentication identity by doing the same thing Soteria's AutoApplySessionInterceptor does. So in your class which implements HttpAuthenticationMechanism you should add the following code before your actual authentication logic is performed in the validateRequest method:

Principal userPrincipal = request.getUserPrincipal();

if (userPrincipal != null) {   
    httpMessageContext.getHandler().handle(new Callback[] { 
                new CallerPrincipalCallback(httpMessageContext.getClientSubject(), userPrincipal) }
            );

    return AuthenticationStatus.SUCCESS; 
}

Also, see this answer by Arjan Tijms. Although it's about JASPIC not Soteria, but in this case I think it's relevant. Hope this helps.

like image 186
Julius Zaldokas Avatar answered Nov 16 '22 21:11

Julius Zaldokas


I thing you're following the incorrect source you've look at this IMPLEMENTATION.

/*  (non-Javadoc)
 *  @see javax.security.authenticationmechanism.http.HttpMessageContext#setRegisterSession(java.lang.String, java.util.Set)
 */
@Override
public void setRegisterSession(String username, Set<String> groups) {
  Jaspic.setRegisterSession(messageInfo, username, groups);
}

Under the library location:

import org.glassfish.soteria.mechanisms.jaspic.Jaspic;

From the mechanisms.

like image 38
youpilat13 Avatar answered Nov 16 '22 21:11

youpilat13