users@javaee-security-spec.java.net

[javaee-security-spec users] [jsr375-experts] Re: FORM authentication mechanism implemented

From: Darran Lofthouse <darran.lofthouse_at_redhat.com>
Date: Fri, 8 Apr 2016 16:59:51 +0100

On 08/04/16 16:23, Ivar Grimstad wrote:
> On Fri, Apr 8, 2016 at 4:36 PM arjan tijms <arjan.tijms_at_gmail.com
> <mailto:arjan.tijms_at_gmail.com>> wrote:
>
> Hi,
>
> On Fri, Apr 8, 2016 at 12:14 PM, Darran Lofthouse
> <darran.lofthouse_at_redhat.com <mailto:darran.lofthouse_at_redhat.com>>
> wrote:
>
> Yes since Undertow was included in WildFLy we have been using
> this form of splitting mechanisms.
>
>
> True, and that will see even more usage I guess when EAP 7 is released.
>
> Still, that is the somewhat older way right? Not yet the one with
> the responder that's registered?
>
>
> As a JSR for a future spec IMO this needs to be in terms of what
> is needed in the short term and the future, not about how it is
> already done.
>
>
> Opinions clearly differ there, but the umbrella platform doesn't
> give very strong guidance. I personally think standardizing what has
> proven to work is an important aspect of Java EE, but there should
> also be some forward thinking. By the time the spec is out
> (especially with the current delays), and then even more by the time
> major vendors have implemented it, it's easily 3 to 4 years later.
>
> Totally agree with you there. Standardize what's out there as well as
> think forward.
>
>
> So I'd really love to investigate this 2 phase multi-mechanism
> approach further.
>
> I haven't heard feedback from the other EG members about this very
> specific approach though, so would be great to hear what they think
> about this.
>
>
> Hope I have understood correctly... with 2 phase multi-mechanism, you
> mean support for e.g. 2 factor authentication?
> +1 to that!

No what we are talking about here is if you want multiple mechanisms to
be able to operate concurrently for same context you need to split out
the request handling phase from the challenging phase so you know if one
mechanism succeeded before you start sending challenges.

>
>
>
> Should also add this combination of mechanisms is not just
> something we have thought we can do - it is based on real demand
> from the end users of our application servers.
>
>
> This is great feedback, thanks!
>
>
> I will have a look at this example in some more detail, the
> biggest worry if mechanisms wasting resources generating
> redundant responses - although with a small API change this is
> not far off how we have it for Elytron.
>
>
> It's indeed not the idea that mechanisms are going to waste
> responses. The code sketched below was just a sketch, but it should
> work exactly like you mentioned.
>
> Kind regards,
> Arjan Tijms
>
>
>
>
>
> Instead of the mechanism populating a response the mechanism
> registers a responder during the evaluateRequest phase - if no
> mechanism successfully authenticates then the responders are called.
>
> Something like:
>
> public class MultiAuthenticationMechanism implements
> HttpAuthenticationMechanism {
> public AuthStatus validateRequest(HttpServletRequest
> request,
> HttpServletResponse response, HttpMessageContext
> httpMsgContext) {
> List<HttpServerAuthenticationMechanism> mechanisms =
> getFromSomewhere();
> List<HttpServerRequestImpl> requests = new
> ArrayList();
>
> // First phase
> for (HttpServerAuthenticationMechanism mechanism :
> mechanisms) {
> HttpServerRequestImpl httpServerRequest = new
> HttpServerRequestImpl (request);
> requests.add(httpServerRequest);
> mechanism.evaluateRequest(httpServerRequest);
>
> if (httpServerRequest.authenticationComplete() {
> SecurityIdentity identity =
> httpServerRequest.getIdentity();
> return
> httpMsgContext.notifyContainerAboutLogin(
> identity.getPrincipal(),
> toList(identity.getRoles()));
>
> }
> }
>
> // Second phase
> for (HttpServerRequestImpl httpServerRequest :
> requests) {
>
> httpServerRequest.getResponder().sendResponse(response);
> if
> (httpServerRequest.authenticationInProgress()) {
> return SEND_CONTINUE;
> }
> }
> }
>
> I don't know yet how your API exactly works, so the above is
> just a
> rough sketch ;)
>
> Kind regards,
> Arjan Tijms
>
>
>
>
>
>
> On 21/03/16 18:31, arjan tijms wrote:
>
> True, but remember the mechanism as it's defined
> now is only EDR1
> status. Much can still be changed.
>
> Time as always is a bit of the issue. I only have
> so much hours
> I can
> spend on JSR 375, and there's quite an amount of
> other things
> that also
> would be really nice to have. For instance, we also
> don't have the
> multiple identity stores done yet.
>
> As for the multiple mechanisms though, is there any
> other server or
> security framework that you know of that has this?
> Or is
> Undertow/Elytron currently the only one?
>
> To get the multiple authentication mechanisms story
> going,
> perhaps best
> to start with creating an issue at the JSR 375
> tracker and
> coding up a
> proposal for the
> https://github.com/javaee-security-spec/javaee-security-proposals
> repo?
> Do you think the multiple mechanisms could be
> implemented for the
> proposal using the current mechanism as a base?
> E.g. a single
> HttpAuthenticationMechanism implementation that
> does the 2-phased
> "try-authenticate" as you explained before?
>
> Additionally, I wonder if any of the other EG
> members have a
> particular
> opinion, idea or use case for the multiple
> mechanisms story.
> Would be
> great to collect the ideas around this.
>
> Kind regards,
> Arjan Tijms
>
>
>
>
>
> On Mon, Mar 21, 2016 at 6:53 PM, Darran Lofthouse
> <darran.lofthouse_at_redhat.com
> <mailto:darran.lofthouse_at_redhat.com>
> <mailto:darran.lofthouse_at_redhat.com
> <mailto:darran.lofthouse_at_redhat.com>>
> <mailto:darran.lofthouse_at_redhat.com
> <mailto:darran.lofthouse_at_redhat.com>
>
> <mailto:darran.lofthouse_at_redhat.com
> <mailto:darran.lofthouse_at_redhat.com>>>> wrote:
>
> 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
>
>
>
>
> --
> Darran Lofthouse - Principal Software Engineer
>
> Registered in England and Wales under Company
> Registration No. 03798903
> Directors: Michael Cunningham (US), Michael
> O'Neill(Ireland), Paul
> Argiry (US)
>
>
>
> --
> Darran Lofthouse - Principal Software Engineer
>
> Registered in England and Wales under Company Registration No.
> 03798903
> Directors: Michael Cunningham (US), Michael O'Neill(Ireland),
> Paul Argiry (US)
>

-- 
Darran Lofthouse - Principal Software Engineer
Registered in England and Wales under Company Registration No. 03798903
Directors: Michael Cunningham (US), Michael O'Neill(Ireland), Paul 
Argiry (US)