I think that it is possible to read from the servlet spec that
getUserPrincipal should return the current principal for an unprotected
resource. Take the following quote (servlet 2.4, section 12.10):
"Being logged in to a web application corresponds precisely to there
being a valid non-null value in getUserPrincipal method"
There is no mention that this should apply only to protected resources.
So if the user is logged in, getUserPrincipal must return non-null.
Regarding your 3rd alternative (below): I don't see why you want to
re-authenticate the user, including when calling getUserPrincipal during
the request for at an unprotected resource. The realm has already
accepted the credentials, so why check them again, with the risk of a
performance degradation?
I guess my underlying assumption is that the webcontainer will track the
login state/credentials in a session, as suggested by the servlet spec
(also section 12.10).
Cheers, Jeppe
Greg Wilkins wrote:
David,
I do not believe that the servlet spec well defines the behaviour of the
getUserPrincipal() method for un-secured resources.
I raised this with the EG during the 2.4 process and pointed out that
several containers implemented this differently. Specifically I wanted
to know that if getUserPrincipal() is called for a un-securied resource
would the return be:
1) Null
2) The principal associated with the request (by session or otherwise)
that was authenticated by a previous request, but not reauthenticated for
this
request. The actual authentication of the principal may have expired or
been revoked.
3) The principal associated with the request (by session or otherwise)
that is re-authenticated with the realm for this request.
I don't believe anything in SRV 12 or the javadoc makes it clear which of these
is the correct choice (not even 12.7 as Jeppe suggests, as it is not defined
what the "security identity of a web user" is for a non secured resource.
Note that as some authentication mechanism (eg BASIC) have paths associated
with them by the browser, it is possible to have different credentials for
different paths within the same web application. For example, if a user
first authenticates at /context/auth/something, then the browser will only
present credentials for /context/auth/* and the user will not be known for
/context/other/something or in fact, different credentials may be request
and provided by the browser! So for some mechanisms, there is not
even a concept of context wide authentication.
At the time I raised the issue with the EG I was not able to get a clear
resolution (wonders of the JCP). I think I suggested having an explicit
lazy authentication ie specify that a request should be authenticated
with the realm IFF credentials are available in the session or request
and additional user interaction is not required. I'll have to dig
up my mail archives to see the reasons against this.
For now, I beleive that most containers implement lazy authentication
for non-secured requests at the time that getUserPrincipal is called.
So any credentials present in the session and/or request will be
rechecked with the realm. Thus option 3) above is the defacto status.
But what credentials are available depends greatly on the auth
mechanism used.
It also does mean that you must be careful with any filters or
interceptors that call getUserPrincipal, as that call may have
the side affect of triggering a possible expensive and remote
call to an authentication mechanism. Don't call it unless
you really need it!
cheers