users@javaee-security-spec.java.net

[javaee-security-spec users] [jsr375-experts] Interceptor based services like auto session and remember-me

From: arjan tijms <arjan.tijms_at_gmail.com>
Date: Tue, 29 Dec 2015 00:39:19 +0100

Hi,

With the authentication mechanism being CDI based, it's relatively easy to
provide extra services on top of them via annotations and CDI interceptors.

For instance, an authentication mechanism is natively stateless, yet it's
often convenient to optionally establish a session (meaning the
authentication mechanism is not called again until the user logs out).

As a proof of concept I implemented an @AutoApplySession annotation via a
CDI interceptor. Applying the annotation looks as follows:

@RequestScoped
@AutoApplySession
public class TestAuthenticationMechanism implements
HttpAuthenticationMechanism {

    @Inject
    private IdentityStore identityStore;

    @Override
    public AuthStatus validateRequest(HttpServletRequest request,
HttpServletResponse response, HttpMessageContext httpMessageContext) throws
AuthException { ... }
}

See:
https://github.com/arjantijms/mechanism-to-store-x/blob/master/app-custom-session/src/main/java/test/TestAuthenticationMechanism.java

The body of the interceptor itself is:

    @AroundInvoke
    public Object intercept(InvocationContext invocationContext) throws
Exception {

        if (isImplementationOf(invocationContext.getMethod(),
validateRequestMethod)) {

            HttpMessageContext httpMessageContext =
(HttpMessageContext)invocationContext.getParameters()[2];
            Principal userPrincipal =
httpMessageContext.getRequest().getUserPrincipal();

            if (userPrincipal != null) {

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

                return SUCCESS;
            }

            Object outcome = invocationContext.proceed();

            if (SUCCESS.equals(outcome)) {

httpMessageContext.getMessageInfo().getMap().put("javax.servlet.http.registerSession",
TRUE.toString());
            }

            return outcome;
        }

        return invocationContext.proceed();
    }

See:
https://github.com/arjantijms/mechanism-to-store-x/blob/master/jsr375/src/main/java/org/glassfish/jsr375/cdi/AutoApplySessionInterceptor.java

This particular feature is a re-imagining of existing issue
https://java.net/jira/browse/JASPIC_SPEC-20

Other features that can possibly be implemented via interceptors are a
"remember-me" and a generic "login to continue".

Remember-me has several implementation strategies for processing the
remember-me token, e.g. via a second identity store, the one and only store
recognising multiple credential types, or perhaps via an interceptor again
but this time for the one and only identity store.

A particular challenge for a generic remember-me interceptor is that you
need some way to obtain from the user if remembering is wanted, and this
can be rather different depending on the authentication mechanism (e.g.
form vs something OAuth based).

Thoughts?

Kind regards,
Arjan Tijms