users@javaee-security-spec.java.net

[javaee-security-spec users] [jsr375-experts] Re: Working example app demonstrating identity store usage

From: arjan tijms <arjan.tijms_at_gmail.com>
Date: Tue, 15 Dec 2015 17:47:35 +0100

Hi,

Another update: I finally came around to implementing an experimental
version of the simplified SAM.

This version is based on the HttpServerAuthModule that was used in several
examples before, and which in turn was based on the one from OmniSecurity.

The difference is that instead of a base class, it's now an interface (as
previously discussed). It closely follows the methods of a SAM, but the
type implementing it is no longer a SAM itself.

For now I've defined the interface as follows:

public interface HttpAuthenticationMechanism {

    AuthStatus validateRequest(HttpServletRequest request,
HttpServletResponse response, HttpMsgContext httpMessageContext) throws
AuthException;

    default AuthStatus secureResponse(HttpServletRequest request,
HttpServletResponse response, HttpMsgContext httpMessageContext) throws
AuthException {
        return SEND_SUCCESS;
    }

    default void cleanSubject(HttpServletRequest request,
HttpServletResponse response, HttpMsgContext httpMessageContext) {
        httpMessageContext.cleanClientSubject();
    }

}

See
https://github.com/arjantijms/mechanism-to-store-x/blob/master/jsr375/src/main/java/javax/security/authenticationmechanism/http/HttpAuthenticationMechanism.java


The JSR 375 CDI extension scans for the one and only implementation of
HttpAuthenticationMechanism, and if found installs a bridge SAM for it that
calls this implementation for each method: E.g. for validateRequest it
looks like this:

public AuthStatus validateRequest(MessageInfo messageInfo, Subject
clientSubject, Subject serviceSubject) throws AuthException {
HttpMsgContext msgContext = new HttpMsgContext(handler, options,
messageInfo, clientSubject);
return CDI.current()
         .select(HttpAuthenticationMechanism.class).get()
         .validateRequest(msgContext.getRequest(),
msgContext.getResponse(), msgContext);
}

Just like the identity store, applications can now use a "sam" by only
having an implementation of HttpAuthenticationMechanism on their classpath.
The code now looks much simpler too. E.g. the example SAM used before is
simplified into this:

@RequestScoped
public class TestAuthenticationMechanism implements
HttpAuthenticationMechanism {

    @Inject
    private IdentityStore identityStore;

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

        if (request.getParameter("name") != null &&
request.getParameter("password") != null) {

            // Get the (caller) name and password from the request
            // NOTE: This is for the smallest possible example only. In
practice
            // putting the password in a request query parameter is highly
            // insecure
            String name = request.getParameter("name");
            Password password = new
Password(request.getParameter("password"));

            // Delegate the {credentials in -> identity data out} function
to
            // the Identity Store
            CredentialValidationResult result = identityStore.validate(
                new UsernamePasswordCredential(name, password));

            if (result.getStatus() == VALID) {
                // Communicate the details of the authenticated user to the
                // container. In many cases the underlying handler will
just store the details
                // and the container will actually handle the login after
we return from
                // this method.
                return httpMessageContext.notifyContainerAboutLogin(
                    result.getCallerName(), result.getCallerGroups());
            } else {
                throw new AuthException("Login failed");
            }
        }

        return httpMessageContext.doNothing();
    }

}

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

One partially unsolved problem, which I happen to have discussed with Ron
Monzillo some time ago, is how module options should neatly arrive in this
CDI enabled SAM. Currently they can be obtained from the HttpMsgContext.
Ideally though, you may want to inject them and do something in the
@PostConstruct method.

But as those module options are per SAM, and there can be multiple SAMs,
even of the same class type, I was struggling a little on how to support
that.

CDI itself has something like this with their Bean<T>, and they use a
unique ID for that that is typically set to just the classname, but can be
more eloborate if needed. Typically the values of constructor parameters
are included if the Bean<T> has one. See e.g.
https://github.com/javaserverfaces/mojarra/blob/master/jsf-ri/src/main/java/com/sun/faces/cdi/CdiProducer.java#L97

Kind regards,
Arjan Tijms






















On Mon, Dec 14, 2015 at 11:43 AM, Werner Keil <werner.keil_at_gmail.com> wrote:

> Hi,
>
> Thanks for the update. I will try it in WildFly at some point, but
> especially the current client and environment (where especially some ideas
> in the JSR like "roles allowed" found here
> https://github.com/javaee-security-spec/javaee-security-examples would be
> of interest in theory) are not even able to use WildFly or Java EE 7 and
> probably won't be for another decade, so it is not so urgent before
> codemotion.
>
> Kind Regards,
>
> Werner Keil
>
> On Mon, Dec 14, 2015 at 11:21 AM, arjan tijms <arjan.tijms_at_gmail.com>
> wrote:
>
>> Hi,
>>
>> On Mon, Dec 14, 2015 at 12:25 AM, Werner Keil <werner.keil_at_gmail.com>
>> wrote:
>>
>>> It works well in Glassfish 4, Wildfly 10 did not,
>>
>> [...]
>>
>> Yes, I did not modify it
>>>
>>
>> Again a life "proof" of how important it is that WildFly does not require
>> the modification ;)
>>
>> You're not the first one to fall into this. Quite a few people think it
>> doesn't work on JBoss, since this modification is so non-obvious.
>>
>> Or the modification is done once, and then later a new install of JBoss
>> (WildFly) is done and the modification is forgotten again (this happens all
>> the time over at the Java EE 7 samples project for the CI).
>>
>> Kind regards,
>> Arjan Tijms
>>
>>
>>
>