users@jaspic-spec.java.net

Re: [servlet-spec users] Re: request#authenticate - start new vs continue

From: Greg Wilkins <gregw_at_webtide.com>
Date: Wed, 20 Apr 2016 20:34:34 +1000

See Inline,


On 20 April 2016 at 17:26, arjan tijms <arjan.tijms_at_gmail.com> wrote:

> Hi,
>
> On Wed, Apr 20, 2016 at 4:28 AM, Greg Wilkins <gregw_at_webtide.com> wrote:
>>
>>
>> Specifically we have a concept of deferred authentication, were
>> credentials may have been supplied (by BASIC/DIGEST headers or be a part of
>> a current session), but that have not been checked because the request did
>> not match a security constraint with authentication requirements.
>>
>> In such cases, a call to authenticate will attempt a login with the
>> credentials/session already available and thus will often be able to return
>> true and not need to start a *new* authentication interaction.
>>
>
> That's really interesting.
>
> If I understand correctly:
>
> * Caller accesses public resource and already provides header (pre-emptive
> authentication)
> * Jetty does not authenticate the caller, but remembers the header
> * Caller accesses 0 to N other public resources
> * Caller accesses public resource where applications calls
> request.authenticate
> * Jetty authenticates right away using the previously remembered header
>
> Did I understand that correctly?
>

More or less, except that it may not be a header, it may be a session or
SSL certificate etc. The point is that depending on how our loginService
is configured, authenticating can be an expensive operation (with possibly
remote calls etc.), so just because a request offers credentials or is for
a session with auth information or has a client certificate, it doesn't
mean that we go to the effort of doing the authentication. Only if an Auth
constraint is hit OR somebody subsequently calls authenticate do we
undertake that effort.


>
> If that's the case then perhaps the need for a request#authenticate method
> to express the intention (new or continue) is even bigger.
>
> Namely, another case is that a user abandons a previously entered dialog
> (could be Servlet's FORM or a custom authentication mechanisms like OAuth2
> or multi-factor, or perhaps indeed Jetty's deferred authentication), and
> then explicitly clicks a login button. If the application then calls
> request#authenticate again and there's still authentication state, it's
> hard for the authentication mechanism to determine whether new or continue
> is meant.
>
> Sometimes heuristics can be used to determine new vs continue, sometimes
> (with custom authentication mechanisms) this is not possible.
>
>
> Sorry I'm not following your example? I can see no call to authenticate()
>> in that example code?
>> Are you saying you want to authenticate without using a form target
>> of /j_security_check ??? If so, isn't that what the login API is for?
>>
>
> The login API (HttpServletRequest#login) is unfortunately very restricted.
> It only accepts username/password as credentials and when standard custom
> authentication modules (JSR 196/JASPIC) are used it doesn't work at all
> (spec mandates exception to be thrown).
>

indeed.

[snip]


> Hope it's more clear now.
>

Yes a little bit. I think you are saying you want a mechanism where the
application can plug in some credentials to the request and then call
authenticate() and for it to attempt to use those credential - if they are
wrong or insufficient, then the authentication conversation will continue
as need be.

The problem I see is the opacity of this. authenticate() currently works
because it has no idea what credential (if any) exist in the
request/session/connection, but it assumes that if they are there they were
set by a previous encounter with the configured authentication mechanism,
and thus it will know what to do.

So in your example, the application some how knows (or assumes) that
authentication is using JASPIC (I'm assuming that is what
defines IS_AUTHENTICATION and AUTH_PARAMS ??), but I think that is fragile
and/or limiting.

I think the problem is that you are trying to mix application managed
authentication with container managed authentication, and it is going to be
difficult to pass any partial results without assuming a mechanism.

or am I missing something still?

cheers


-- 
Greg Wilkins <gregw@webtide.com> CTO http://webtide.com