Bug 59823 - HttpServletRequest#authenticate does not invoke JASPIC SAM
Summary: HttpServletRequest#authenticate does not invoke JASPIC SAM
Alias: None
Product: Tomcat 9
Classification: Unclassified
Component: Catalina (show other bugs)
Version: 9.0.0.M8
Hardware: PC All
: P2 normal (vote)
Target Milestone: -----
Assignee: Tomcat Developers Mailing List
Depends on:
Reported: 2016-07-07 17:12 UTC by Arjan Tijms
Modified: 2016-08-12 08:47 UTC (History)
1 user (show)


Note You need to log in before you can comment on or make changes to this bug.
Description Arjan Tijms 2016-07-07 17:12:18 UTC
When a JASPIC SAM is (programmatically) installed and subsequently HttpServletRequest#authenticate() is called the SAM is not actually being invoked.

According to 3.9.3 of the JASPIC 1.1 spec the SAM should be invoked.

I added a new test to the Java EE 7 samples project for this: https://github.com/javaee-samples/javaee7-samples/tree/master/jaspic/programmatic-authentication

To reproduce:

* Deploy .war in submodule to Tomcat 9.0.0.M8
* Request http://localhost:8080/jaspic-programmatic-authentication/public/authenticate

The result is:

This is a public servlet 
before web username: null
before web user has role "architect": false
request.authenticate outcome: false
after web username: null
after web user has role "architect": false

But should be:

This is a public servlet 
before web username: null
before web user has role "architect": false
request.authenticate outcome: true
after web username: test
after web user has role "architect": true
Comment 1 Mark Thomas 2016-08-04 16:42:01 UTC
Thanks for the report. This is fixed in 9.0.x for 9.0.0.M10 onwards and 8.5.x for 8.5.5. onwards.
Comment 2 Arjan Tijms 2016-08-04 17:41:28 UTC
Thanks for the fix Mark! :)


Just wondering, as it's not clearly described in the JASPIC spec at all, but what did you use for the return values of request.authenticate?
I noticed before that GlassFish returns false when either authentication is in progress (SEND_CONTINUE returned from SAM), authentication failed or the unauthenticated caller principal was set.
JBoss however returns false when authentication is in progress, but throws exception when authentication fails or the unauthenticated caller principal was set.

The only thing upon which they agree is that true is returned when authentication succeeded (non null caller principal set).
Comment 3 Mark Thomas 2016-08-04 18:54:10 UTC
true if AuthStatus.SUCCESS, otherwise false including AuthException (which is caught and logged).
Comment 4 Arjan Tijms 2016-08-05 20:46:26 UTC
>true if AuthStatus.SUCCESS

Is that also when a null is passed to the CallerPrincipalCallback? 

Since in that case the container will establish this unauthenticated identity (see http://docs.oracle.com/javaee/7/api/javax/security/auth/message/callback/CallerPrincipalCallback.html). This means HttpServletRequest.getUserPrincipal() will return a null.

But the JavaDoc for the return value of HttpServletRequest#authenticate says "true when non-null values were or have been established as the values returned by getUserPrincipal, getRemoteUser, and getAuthType."
Comment 5 Mark Thomas 2016-08-11 21:59:17 UTC
It was. It isn't any more.
Comment 6 Arjan Tijms 2016-08-11 22:45:56 UTC
>It was. It isn't any more.

Great! Does it return false now or is an exception thrown? (i.e. does it behave like GlassFish or like JBoss?)

JBoss' behaviour is not because of some kind of bug or oversight btw. Stuart at the time said to have read the Servlet and JASPIC specs multiple times for this case and was convinced it mandated an exception to be thrown when a null principal was set.
Comment 7 Mark Thomas 2016-08-12 08:41:29 UTC
It returns false.
Comment 8 Arjan Tijms 2016-08-12 08:47:36 UTC
>It returns false.

Ok thanks ;)

I'll start a topic for this on the Servlet/JASPIC mailing lists, see if the outcome requirements can be clarified. For now I can't add a test for this either since I'm not 100% sure what the outcome should be.