On 11/26/14 9:24 AM, arjan tijms wrote:
> Hi,
>
> Currently the Javadoc for HttpServletRequest#authenticate states the
> following for the return value:
>
> "true when non-null values were or have been established as the values
> returned by getUserPrincipal, getRemoteUser, and getAuthType. Return
> false if authentication is incomplete and the underlying login
> mechanism has committed, in the response, the message (e.g.,
> challenge) and HTTP status code to be returned to the user."
>
> See https://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServletRequest.html#authenticate(javax.servlet.http.HttpServletResponse)
>
> Simplified that's:
>
> true -> authentication has happened
> false -> authentication is in progress and something has been
> committed to the response
>
> This however leaves out one important case, and that's when the using
> code wants to pre-emptively trigger authentication, but the auth
> module decides to "do nothing" (which, depending on its policy, can be
> a valid action).
Hi Arjan,
When authenticate is called, the container authentication mechanism has
no discretion as to whether
or not authentication is to occur. IOW, the method was created to allow
the application to
be authoritative for when authentication must occur (as distinct from
the situation where the container's constraint processing system would
otherwise be authoritative - based on path base security constraints -
for establishing when authentication is to occur).
IOW calling authenticate is equivalent to calling a JSR 196 auth module
with a *mandatory* authentication policy.
The authentication method was NOT defined to support an "authenticate if
you (the container authentication mechanism) thinks it is appropriate to
do so" use case.
If you need to support that use case, you will need to define a new API.
The existing API was defined to allow frameworks such as JAX-WS and
JAX-RS to trigger authentication based on non-path based mechanisms,
such as @RolesAllowed.
> Most servlet containers I tested just return false when "nothing" has
> happened, but to the letter of the spec this seems to be not entirely
> correct.
that sounds like a bug
> At least one servlet container has tried to implement the
> spec more correctly, and has interpreted that the requirement is here
> to throw a ServletException following its Javadoc:
>
> "ServletException - if the authentication failed and the caller is
> responsible for handling the error (i.e., the underlying login
> mechanism did NOT establish the message and HTTP status code to be
> returned to the user)"
the auth mechanism should not be refusing to perform the authentication,
but it should
throw this exception under the conditions as described.
> But IMHO, this is not entirely in the spirit of the spec either.
> Authentication did not "fail" and there is no "error". The auth module
> completely within its rights chose to do nothing.
I believe you are defining a new use case/policy model for container
authentication.
The authenticate method was defined as an analogue for what happens
when there is a (path-based) authentication constraint on a resource; In
that case, the
constraint enforcement system invokes the container authentication
mechanism when an
authentication constraint must be enforced. Likewise, the caller of
authenticate has
determines (by its own means) that an authentication contraint must be
enforced, and it calls authenticate to direct the container
authentication mech. to do so.
Ron
>
> I wonder if anyone can suggest a way to improve this?
>
> Redefine the false outcome to just say authentication did not happen? I.e.
>
> return true -> authentication has happened
> return false -> authentication did not happen
>
> Or introduce a new authenticate method returning say an enum:
>
> AUTHENTICATED -> authentication has happened
> IN_PROGRESS -> authentication is incomplete
> DID_NOTHING -> auth module decided to do nothing
>
> Or ... ?
>
> Kind regards,
> Arjan Tijms