jsr375-experts@javaee-security-spec.java.net

[jsr375-experts] Re: FORM authentication mechanism implemented

From: Darran Lofthouse <darran.lofthouse_at_redhat.com>
Date: Mon, 21 Mar 2016 17:53:58 +0000

I still think there is big gap here in that multiple mechanisms will not
be able to operate concurrently.

On 13/03/16 23:58, arjan tijms wrote:
> Hi,
>
> I just implemented a clone of Servlet's FORM authentication mechanism
> using the proposed JSR 375 API. A demo app showing it can be found at
> https://github.com/javaee-security-spec/soteria/tree/master/test/app-mem-form
>
> The mechanism itself looks like this:
>
> @AutoApplySession
> @LoginToContinue
> @Typed(FormAuthenticationMechanism.class)
> public class FormAuthenticationMechanism implements
> HttpAuthenticationMechanism, LoginToContinueHolder {
> private LoginToContinue loginToContinue;
>
> @Inject
> private IdentityStore identityStore;
> @Override
> public AuthStatus validateRequest(HttpServletRequest request,
> HttpServletResponse response, HttpMessageContext httpMessageContext)
> throws AuthException {
> if ("POST".equals(request.getMethod()) &&
> request.getRequestURI().endsWith("/j_security_check")) {
> if (notNull(request.getParameter("j_username"),
> request.getParameter("j_password"))) {
>
> CredentialValidationResult result = identityStore.validate(
> new UsernamePasswordCredential(
> request.getParameter("j_username"),
> new Password(request.getParameter("j_password"))));
>
> if (result.getStatus() == VALID) {
> return httpMessageContext.notifyContainerAboutLogin(
> result.getCallerPrincipal(),
> result.getCallerGroups());
> } else {
> throw new AuthException("Login failed");
> }
> }
> }
> return httpMessageContext.doNothing();
> }
>
> See
> https://github.com/javaee-security-spec/soteria/blob/master/impl/src/main/java/org/glassfish/soteria/mechanisms/FormAuthenticationMechanism.java
>
>
> This leans heavily on the @AutoApplySession and @LoginToContinue
> interceptors, which can both be re-used by other mechanisms,
>
> The heart of the @LoginToContinue interceptor contains this code:
>
> private AuthStatus validateRequest(InvocationContext invocationContext,
> HttpServletRequest request, HttpServletResponse response,
> HttpMessageContext httpMessageContext) throws Exception {
>
> if (isOnProtectedURLWithStaleData(httpMessageContext)) {
> removeSavedRequest(request);
> }
> if (isOnInitialProtectedURL(httpMessageContext)) {
> saveRequest(request);
> return httpMessageContext.forward(
>
> getLoginToContinueAnnotation(invocationContext).loginPage());
> }
> if (isOnLoginPostback(request)) {
> AuthStatus authstatus = null;
> try {
> authstatus = (AuthStatus) invocationContext.proceed();
> } catch (AuthException e) {
> authstatus = FAILURE;
> }
> if (authstatus == SUCCESS) {
> if (httpMessageContext.getCallerPrincipal() == null) {
> return SUCCESS;
> }
> RequestData savedRequest = getSavedRequest(request);
> if (!savedRequest.matchesRequest(request)) {
> saveAuthentication(request, new
> CredentialValidationResult(
> VALID,
> httpMessageContext.getCallerPrincipal(),
> httpMessageContext.getGroups()));
> return
> httpMessageContext.redirect(savedRequest.getFullRequestURL());
> } // else return success
> } else {
> return httpMessageContext.redirect( // TODO: or forward?
> getBaseURL(request) +
>
> getLoginToContinueAnnotation(invocationContext).errorPage());
> }
> }
>
> if (isOnOriginalURLAfterAuthenticate(request)) {
> return httpMessageContext
> .withRequest(new HttpServletRequestDelegator(request,
> requestData))
> .notifyContainerAboutLogin(
> result.getCallerPrincipal(),
> result.getCallerGroups());
> }
> return httpMessageContext.doNothing();
> }
>
> See:
> https://github.com/javaee-security-spec/soteria/blob/master/impl/src/main/java/org/glassfish/soteria/cdi/LoginToContinueInterceptor.java
>
>
> FORM is a rather nasty mechanism to implement, and going for the
> re-usable parts took a little extra time, but it does show that the
> proposed mechanism API is capable of implementing a quite demanding set
> of requirements (FORM is really surprisingly demanding for such an old
> mechanism).
>
> Do note that both design and implementation are rather rough at the
> moment and could do with some refinements still. But I think this could
> work for an early draft.
>
> Kind regards,
> Arjan Tijms
>
>