users@javaee-security-spec.java.net

[javaee-security-spec users] [jsr375-experts] Re: Tried JASPIC with Custom Form authentication and SecurityContext

From: arjan tijms <arjan.tijms_at_gmail.com>
Date: Thu, 7 May 2015 17:01:03 +0200

On Thu, May 7, 2015 at 4:15 PM, Rudy De Busscher <rdebusscher_at_gmail.com>
wrote:

> Thanks Arjan for some useful comments. I will have a look later on to my
> code to update it and test again.
>

You're welcome ;)



> What now happens is that when you configure a JASPIC server authentication
>> module (programmatically or at the container level), it completely replaces
>> the authentication method defined in web.xml. For clarity the
>> authentication method should therefore be completely omitted from web.xml.
>>
>>
> That was also what I found in my tests.
>

Yeah, so this is technically "correct", but from a usability/coherence
point of view it's of course not ideal.




> When a resource was called which was protected through a security
> constraint element in the web.xml, the property __
> "javax.javax.security.auth.message.MessagePolicy.isMandatory" isn't set.
> So the SAM isn't aware that is is a protected resource.
>

The key should be "javax.security.auth.message.MessagePolicy.isMandatory".
It looks like you've got a a duplicate "javax" there.

There's a convenience method available via HttpMsgContext#isProtected

If the resource is protected, then the
"javax.security.auth.message.MessagePolicy.isMandatory" key is always
present and the value if "true". However, when the resource is NOT
protected then it depends on the server what happens. Some just omit the
key, while others store the value "false" in that case.




> OK, My idea was that SAM was available during the complete
> request-response lifecycle. Wrong interpretation from my side thus.
>

The SAM itself is basically available, but the HttpMsgContext (and more
specifically the handler that it embeds) is not directly accessible. You
are however free to call HttpServletRequest#authenticate at any moment.

So this means that unlike a javax.servlet.Filter, a SAM needs to be aware
that it can be called *before* filters and the servlet are called, *while*
filters and servlets are being called, and *after*. After is a separate
method though; secureResponse. It's rare to do something there in practice.

If the SAM is called explicitly (via HttpServletRequest#authenticate)
during a request (as opposed to before) it MUST authenticate, even when the
resource from which its called is not protected.



What you can do however is *trigger* authentication by calling
>> HttpServletRequest#authenticate. You can do this at any moment during
>> request processing. This will result in the SAM(s) that you have configured
>> being called. From the SAM you then use HttpMsgContext.
>>
>> HttpServletRequest#authenticate who triggers the SAM is something that I
> wel need to check.
> My idea was that the SecurityContext looked up the IdentityStore and
> interacts directly with it.
>

The lookup of the identity store is something which has not been specified
at all by any party yet. A SAM represents the authentication mechanism, not
the identity store.

If you would do it totally in user code now then the container would not be
aware of the login, and things like @RolesAllowed and request.isUserInRole
(and variants) would not work any more.

There's only 1 API in Java EE that is capable of communicating
authentication data to the container now and that is JASPIC. See
https://wiki.shibboleth.net/confluence/display/SHIB2/Java+EE+Container-Managed+Authentication
for a rather good write up about some of the core concepts.

You can now, using standard APIs, build on this by having an optional SAM
that "does nothing" except looking up the identity store, putting in the
credentials, getting the username/roles back and communicating those to the
container.

It's an open question of how to handle the identity store only login.

With a standardized identity store, HttpServletRequest#login could be
specified as calling through to that, but then the next request the
authentication data would have to be retrieved from somewhere (e.g. the
session) and re-applied. This is where a "do nothing" SAM would come in
again anyway. Meaning, we might not need a new mechanism/API to communicate
those details to the container, just a standard implementation of a SAM for
this purpose, the availability of CDI and specifying that CDI is used to
retrieve the identity store (with a specific bean type and/or specific
annotations etc).



not-ideal -> Would call it an issue.
>

Indeed, issue https://java.net/jira/browse/JAVAEE_SECURITY_SPEC-12 to be
exact ;)

As explained in the comments of that, JAVAEE_SECURITY_SPEC-12 is intended
first and fore all to align the 4 different ways that exist now in Java EE
to get the user/caller principal.

For some reason it has been interpreted as a new way to communicate
authentication data to the container, but that's really not the idea. It's
supposed to just wrap existing APIs, and where needed make sure some of the
underlying APIs are better specified.

A platform specific implementation of it *may* compensate for container
differences in the underlying API. E.g. a GlassFish implementation could
use knowledge about what in GlassFish the EJB specific representation of
the unauthenticated identity is, and translate that to a null. Whether this
is the way is still open for discussion of course, but it may be a
relatively easy solution to do it this way.

Kind regards,
Arjan