In the beginning of this year and two months prior to that we looked at how well modern Java EE servers supported portable authentication (JASPIC) in Java EE. In this article we look at the current state of the union.

Originally the situation didn't looked that rosy, but since then things have been steadily improving. Since last time new versions of Payara, WildFly and Liberty have been released, while TomEE now also supports JASPIC. No new versions of Oracle's WebLogic and GlassFish were released. New tests have been added for registering a session with a custom principal and EJB propagation after register session.

The results of running the latest series of JASPIC tests are shown below:

Running the Java EE 7 samples JASPIC tests Module Test Payara 4.1.1.163 snapshot WildFly 10.0.0 Liberty 9 beta 2016.5 TomEE 7.0.0 async-authentication testBasicAsync Passed Passed Passed Passed basic-authentication testProtectedPageNotLoggedin Passed Passed Passed Passed basic-authentication testProtectedPageLoggedin Passed Passed Passed Passed basic-authentication testPublicPageLoggedin Passed Passed Passed Passed basic-authentication testPublicPageNotLoggedin Passed Passed Passed Passed basic-authentication testPublicAccessIsStateless Passed Passed Passed Passed basic-authentication testProtectedAccessIsStateless Passed Passed Passed Passed basic-authentication testProtectedAccessIsStateless2 Passed Passed Passed Passed basic-authentication testProtectedThenPublicAccessIsStateless Passed Passed Passed Passed custom-principal testProtectedPageLoggedin Passed Passed Passed Passed custom-principal testPublicPageLoggedin Passed Passed Passed Passed custom-principal testPublicAccessIsStateless Passed Passed Passed Passed custom-principal testProtectedAccessIsStateless Passed Passed Passed Passed custom-principal testProtectedAccessIsStateless2 Passed Passed Passed Passed custom-principal testProtectedThenPublicAccessIsStateless Passed Passed Passed Passed dispatching testBasicForwardViaProtectedResource Passed Passed Passed Passed dispatching testBasicForwardViaPublicResource Passed Passed Passed Passed dispatching testBasicIncludeViaPublicResource Passed Passed Passed Passed dispatching-jsf-cdi testCDIForwardViaProtectedResource Passed Passed Passed Passed dispatching-jsf-cdi testCDIForwardViaPublicResource Passed Passed Passed Passed dispatching-jsf-cdi testCDIIncludeViaPublicResource Passed Passed Passed Passed dispatching-jsf-cdi testJSFwithCDIForwardViaPublicResource Passed Passed Passed Passed dispatching-jsf-cdi testJSFwithCDIForwardViaProtectedResource Passed Passed Passed Passed dispatching-jsf-cdi testJSFwithCDIIncludeViaPublicResource Failure Failure Failure Passed dispatching-jsf-cdi testJSFForwardViaPublicResource Passed Passed Passed Passed dispatching-jsf-cdi testJSFForwardViaProtectedResource Passed Passed Passed Passed dispatching-jsf-cdi testJSFIncludeViaPublicResource Failure Failure Failure Passed ejb-propagation publicServletCallingProtectedEJB Passed Passed Passed Passed ejb-propagation protectedServletCallingProtectedEJB Passed Passed Passed Passed ejb-propagation publicServletCallingPublicEJBThenLogout Passed Passed Passed Passed ejb-propagation protectedServletCallingPublicEJB Passed Passed Passed Passed invoke-ejb-cdi protectedInvokeCDIFromSecureResponse Passed Passed Failure Passed invoke-ejb-cdi protectedInvokeCDIFromCleanSubject Passed Passed Passed Passed invoke-ejb-cdi protectedInvokeCDIFromValidateRequest Passed Passed Failure Passed invoke-ejb-cdi publicInvokeCDIFromSecureResponse Passed Passed Failure Passed invoke-ejb-cdi publicInvokeCDIFromValidateRequest Passed Passed Failure Passed invoke-ejb-cdi publicInvokeCDIFromCleanSubject Passed Passed Passed Passed invoke-ejb-cdi protectedInvokeEJBFromSecureResponse Passed Passed Passed Passed invoke-ejb-cdi protectedInvokeEJBFromCleanSubject Passed Passed Passed Passed invoke-ejb-cdi protectedInvokeEJBFromValidateRequest Passed Passed Passed Passed invoke-ejb-cdi publicInvokeEJBFromSecureResponse Passed Passed Passed Passed invoke-ejb-cdi publicInvokeEJBFromValidateRequest Passed Passed Passed Passed invoke-ejb-cdi publicInvokeEJBFromCleanSubject Passed Passed Passed Passed jacc-propagation callingJACCWhenAuthenticated Passed Failure Failure Failure jacc-propagation callingJACCWhenAuthenticated Passed Failure Failure Failure jacc-propagation callingJACCWhenNotAuthenticated Passed Passed Failure Failure lifecycle testBasicSAMMethodsCalled Passed Passed Passed Passed lifecycle testLogout Passed Passed Passed Passed register-session testRemembersSessionEJB Passed Failure Passed Passed register-session testJoinSessionIsOptional Passed Passed Failure Passed register-session testRemembersSession Passed Passed Passed Passed register-session testRemembersSessionEJB Passed Failure Passed Passed register-session testJoinSessionIsOptional Passed Passed Failure Passed register-session testRemembersSession Passed Passed Passed Passed status-codes test404inResponse Passed Passed Passed Passed status-codes test404inResponse Passed Passed Passed Passed wrapping testResponseWrapping Passed Passed Passed Passed wrapping testRequestWrapping Passed Passed Passed Passed

Not directly shown in the table, but one of the biggest changes is that Liberty 9 beta 2016.5 no longer needs JASPIC to be activated in a problematic and proprietary way. Historically Liberty was one of the most problematic servers in this area. It originally required all users and groups to be made known to a Liberty specific artefact called a user registry (a kind of identity store). This requirement was later relaxed such that only groups had to be defined, but since group to role mapping was also mandatory, this stil meant defining the same group at least 3 times if no actual group mapping was needed.

In Liberty 9 beta 2016.5 all this overhead is now completely gone, and just like GlassFish and WebLogic, JASPIC just works without any activation whatsoever (with a caveat for GlassFish that by default it does require group to role mapping) . One thing to watch out for is that if you do need group to role mapping, you seemingly can't just use Liberty's role mapping file (ibm-application-bnd.xml), but also need to define the above mentioned user registry again. All other servers (that feature a role mapper) allow the mapping of groups set by a JASPIC SAM via only a single XML file. When asked about this, the Liberty lead mentioned that this is due to backwards compatibility, which does make sense. It's also not such a bad thing; if you want to use the proprietary group to role mapping feature it's only a relatively small extra step to also activate a proprietary artefact such as the user registry.

As far as JASPIC functionality goes, Liberty keeps failing the CDI related tests and the JACC ones. The JACC ones are a clear spec violation (confirmed by the JACC and JASPIC spec lead), but since it concerns a requirement that was never enforced (namely, JACC has to be available and used by default) it's likely far from trivial to just fix this. Liberty also fails a test where the authenticated user is changed during the same HTTP session. This however clashes with Liberty's protection against a session fixation attack, which for instance happens when a user logs out and without resetting the http session (specifically changing its ID) a new user logs in again. This protection can be disabled by putting <httpSession securityIntegrationEnabled="false"/> in server.xml.

As mentioned above, TomEE is new to JASPIC scene, but what an entrance it makes! In it's very first release it passed all JASPIC tests, safe the JACC ones. TomEE (as not a full Java EE 7 certified server) is however not required to support JACC at all, let alone out of the box. Since TomEE does actually support JACC it may be possible to have it pass these tests as well. Right from the start TomEE also doesn't require any explicit activation of JASPIC. It just works out of the box.

JBoss/WildFly, while still having a very good JASPIC implementation fell a tiny bit behind. It still doesn't pass all JACC tests, even though JACC is in fact available by default (a bug prevents roles to be propagated correctly). Additionally, a new bug was found that prevents roles being propagated to EJB beans when the remember session feature is used. JBoss also still requires the dummy-like marker file (jboss-web.xml) in an archive to activate JASPIC. Even though such marker file is only a small nuisance compared to having to modify the server itself, it does make JBoss the sole server now that requires such activation at all (but as mentioned above, GlassFish/Payara requires a proprietary group to role mapping file to be present).

Payara also suffered from a newly discovered bug, this one involving the combination of the remember session feature and a custom principal. This was however quickly fixed in the 4.1.1.163 branch and Payara remains one of the strongest JASPIC implementations. There's essentially only one minor failure involving a not too common case of including a JSF resource from within a SAM.

Conclusion

7 years after portable authentication was introduced in Java EE 6 and 3 years after its revision in Java EE 7, JASPIC implementations are now finally getting really compliant. There's a residu of bugs in the various implementations that still need to be fixed, and a few inconveniences to take away in some servers (JBoss' jboss-web.xml and GlassFish/Payara's glassfish-web.xml), but overal things are starting to look very good.

The one big exception remains WebLogic 12.2.1, which currently doesn't work at all after a major bug was introduced in that version that prevents basic authentication to work correctly (effectively a blocker bug that makes running all other tests rather moot)

Arjan Tijms