Monday, January 18, 2016

Java EE 7 server Liberty 9 beta 2016.1 tested for JASPIC support

IBM recently released the latest monthly beta of their modern and light weight Java EE 7 server; Liberty 9 beta 2016.1. Previous beta releases of Liberty 9 already performed quite well when it came to Java EE's portable authentication (JASPIC), but weren't perfect yet.

In this article we take a look to see if JASPIC support has improved in the latest release. To find out we executed the JASPIC tests against this latest release. For comparison the previous Liberty beta as well as the latest (snapshots) of Payara and WildFly are shown.

One thing to note is that previous downloads of recent Liberty betas were always for a full Java EE 7 server. For some inexplainable reason this month's beta is "only" a Java EE 7 web profile. Possibly this is a bug on the download page, as the size that as stated (116 mb) is not the same as the actual archive that's downloaded (94 mb).

One of Liberty's unique features is that it has a very elaborate and smooth system to install new components and their dependencies. In a way it's a bit like Maven dependency management but for the AS. With the help of this system the mysteriously missing Java EE 7 components could be installed after unpacking Liberty with the following command:

bin/installUtility install javaee-7.0
Additionally the so-called local connector was needed to run the tests. Previous betas included this as well, but it now had to be installed separately too:
bin/installUtility install localConnector-1.0

After this we could run the tests. The results are shown in the table below:

Running the Java EE 7 samples JASPIC tests
Module Test Payara 4.1.1.161-pre WildFly 10rc5 Liberty 9 beta 2016.1 Liberty 9 beta 2015.11
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
Failure
dispatching-jsf-cdi testCDIForwardViaProtectedResource
Passed
Passed
Passed
Passed
dispatching-jsf-cdi testCDIForwardViaPublicResource
Passed
Passed
Passed
Passed
dispatching-jsf-cdi testCDIIncludeViaPublicResource
Passed
Passed
Passed
Failure
dispatching-jsf-cdi testJSFwithCDIForwardViaPublicResource
Passed
Passed
Passed
Passed
dispatching-jsf-cdi testJSFwithCDIForwardViaProtectedResource
Passed
Passed
Passed
Passed
dispatching-jsf-cdi testJSFwithCDIIncludeViaPublicResource
Failure
Failure
Failure
Failure
dispatching-jsf-cdi testJSFForwardViaPublicResource
Passed
Passed
Passed
Passed
dispatching-jsf-cdi testJSFForwardViaProtectedResource
Passed
Passed
Passed
Passed
dispatching-jsf-cdi testJSFIncludeViaPublicResource
Failure
Failure
Failure
Failure
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
Failure
invoke-ejb-cdi protectedInvokeCDIFromCleanSubject
Passed
Passed
Passed
Passed
invoke-ejb-cdi protectedInvokeCDIFromValidateRequest
Passed
Passed
Failure
Failure
invoke-ejb-cdi publicInvokeCDIFromSecureResponse
Passed
Passed
Failure
Failure
invoke-ejb-cdi publicInvokeCDIFromValidateRequest
Passed
Passed
Failure
Failure
invoke-ejb-cdi publicInvokeCDIFromCleanSubject
Passed
Passed
Passed
Failure
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 testJoinSessionIsOptional
Passed
Passed
Passed
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

As can be seen Liberty's JASPIC support has again improved. Including a resource (e.g. Servlet or JSP) into the response now generally works again. Only JSF based includes are still broken, but this is likely not a Liberty problem but a JSF one.

Additionally one CDI problem was fixed; obtaining and invoking a CDI bean from a SAM's cleanSubject method. This already worked on previous betas when the request was to a protected resource, but mysteriously failed for public resources. The cleanSubject method is generally somewhat easier to support, as this method is called in response to HttpServletRequest#logout and thus happens during the so-called resource invocation (i.e. from the context of a Servlet where CDI already is mandated to be available).

The real challenge for JASPIC implementors is to make sure that CDI works before and after this resource invocation. Payara, GlassFish and JBoss/WildFly have succeeded in supporting this, but Liberty not yet. This support is particularly important since the upcoming Java EE Security API (JSR 375) completely depends on the ability to obtain and invoke CDI beans from the validateRequest and secureResponse methods. Unfortunately early versions of the JSR 375 API can now not be tested on Liberty.

Conclusion

Liberty is improving rapidly and already very useful to deploy portable Java EE 7 authentication modules on. Hopefully it will soon take one the last hurdles and provide full support for CDI as well.

Arjan Tijms

Wednesday, January 6, 2016

Latest versions Payara and WildFly improve Java EE 7 authentication compliance

Two months ago we looked at the state of portable authentication for GlassFish, Payara, JBoss/WildFly, WebLogic and Liberty in Java EE 7. With the exception of WebLogic 12.2.1, most servers performed pretty well, but there were still a number of bugs present.

Since then both Payara and WildFly have seen bug fixes that again reduce the number of bugs present where it concerns portable Java EE authentication. Do note that both updated servers have not had an official (supported) release yet, but pre-release resp. rc/cr builds containing those fixes can be downloaded from the vendors.

In anticipation of the final version of those Java EE 7 servers we already took a look at how they improved. The results are shown in the table below. For reference we show several older versions as well. For Payara we took the GlassFish release upon which Payara based its additional fixes, while for WildFly it's a selection of older builds. (no less than 29 builds were released for WildFly 8,9,10/EAP 7 alpha,beta).

Running the Java EE 7 samples JASPIC tests
Module Test Payara 4.1.1.161-pre GlassFish 4.1.1 WildFly 10rc5 WildFly 10rc4 WildFly 9.0.1 WildFly 8.0.0
async-authentication testBasicAsync
Passed
Passed
Passed
Passed
Passed
Failed
basic-authentication testProtectedPageNotLoggedin
Passed
Passed
Passed
Passed
Passed
Passed
basic-authentication testProtectedPageLoggedin
Passed
Passed
Passed
Passed
Passed
Passed
basic-authentication testPublicPageLoggedin
Passed
Passed
Passed
Passed
Passed
Passed
basic-authentication testPublicPageNotLoggedin
Passed
Passed
Passed
Passed
Passed
Passed
basic-authentication testPublicAccessIsStateless
Passed
Passed
Passed
Passed
Passed
Passed
basic-authentication testProtectedAccessIsStateless
Passed
Passed
Passed
Passed
Passed
Passed
basic-authentication testProtectedAccessIsStateless2
Passed
Passed
Passed
Passed
Passed
Passed
basic-authentication testProtectedThenPublicAccessIsStateless
Passed
Passed
Passed
Passed
Passed
Passed
custom-principal testProtectedPageLoggedin
Passed
Failure
Passed
Passed
Passed
Passed
custom-principal testPublicPageLoggedin
Passed
Failure
Passed
Passed
Passed
Passed
custom-principal testPublicAccessIsStateless
Passed
Passed
Passed
Passed
Passed
Passed
custom-principal testProtectedAccessIsStateless
Passed
Passed
Passed
Passed
Passed
Passed
custom-principal testProtectedAccessIsStateless2
Passed
Passed
Passed
Passed
Passed
Passed
custom-principal testProtectedThenPublicAccessIsStateless
Passed
Passed
Passed
Passed
Passed
Passed
dispatching testBasicForwardViaProtectedResource
Passed
Passed
Passed
Passed
Passed
Passed
dispatching testBasicForwardViaPublicResource
Passed
Passed
Passed
Passed
Passed
Passed
dispatching testBasicIncludeViaPublicResource
Passed
Passed
Passed
Passed
Passed
Failure
dispatching-jsf-cdi testCDIForwardViaProtectedResource
Passed
Passed
Passed
Passed
Passed
Passed
dispatching-jsf-cdi testCDIForwardViaPublicResource
Passed
Passed
Passed
Passed
Passed
Passed
dispatching-jsf-cdi testCDIIncludeViaPublicResource
Passed
Passed
Passed
Passed
Passed
Failure
dispatching-jsf-cdi testJSFwithCDIForwardViaPublicResource
Passed
Passed
Passed
Passed
Passed
Passed
dispatching-jsf-cdi testJSFwithCDIForwardViaProtectedResource
Passed
Passed
Passed
Passed
Passed
Passed
dispatching-jsf-cdi testJSFwithCDIIncludeViaPublicResource
Failure
Failure
Failure
Failure
Failure
Failure
dispatching-jsf-cdi testJSFForwardViaPublicResource
Passed
Passed
Passed
Passed
Passed
Passed
dispatching-jsf-cdi testJSFForwardViaProtectedResource
Passed
Passed
Passed
Passed
Passed
Passed
dispatching-jsf-cdi testJSFIncludeViaPublicResource
Failure
Failure
Failure
Failure
Failure
Failure
ejb-propagation publicServletCallingProtectedEJB
Passed
Passed
Passed
Passed
Passed
Failure
ejb-propagation protectedServletCallingProtectedEJB
Passed
Passed
Passed
Passed
Passed
Failure
ejb-propagation publicServletCallingPublicEJBThenLogout
Passed
Passed
Passed
Passed
Passed
Failure
ejb-propagation protectedServletCallingPublicEJB
Passed
Passed
Passed
Passed
Passed
Passed
invoke-ejb-cdi protectedInvokeCDIFromSecureResponse
Passed
Passed
Passed
Passed
Failure
Failure
invoke-ejb-cdi protectedInvokeCDIFromCleanSubject
Passed
Passed
Passed
Passed
Passed
Passed
invoke-ejb-cdi protectedInvokeCDIFromValidateRequest
Passed
Passed
Passed
Passed
Passed
Passed
invoke-ejb-cdi publicInvokeCDIFromSecureResponse
Passed
Passed
Passed
Passed
Failure
Failure
invoke-ejb-cdi publicInvokeCDIFromValidateRequest
Passed
Passed
Passed
Passed
Passed
Passed
invoke-ejb-cdi publicInvokeCDIFromCleanSubject
Passed
Passed
Passed
Passed
Passed
Passed
invoke-ejb-cdi protectedInvokeEJBFromSecureResponse
Passed
Failure
Passed
Passed
Failure
Passed
invoke-ejb-cdi protectedInvokeEJBFromCleanSubject
Passed
Passed
Passed
Passed
Passed
Passed
invoke-ejb-cdi protectedInvokeEJBFromValidateRequest
Passed
Failure
Passed
Passed
Passed
Passed
invoke-ejb-cdi publicInvokeEJBFromSecureResponse
Passed
Failure
Passed
Passed
Failure
Passed
invoke-ejb-cdi publicInvokeEJBFromValidateRequest
Passed
Failure
Passed
Passed
Passed
Passed
invoke-ejb-cdi publicInvokeEJBFromCleanSubject
Passed
Passed
Passed
Passed
Passed
Passed
jacc-propagation callingJACCWhenAuthenticated
Passed
Passed
Failure
Failure
Failure
Failure
jacc-propagation callingJACCWhenAuthenticated
Passed
Passed
Failure
Failure
Failure
Failure
jacc-propagation callingJACCWhenNotAuthenticated
Passed
Passed
Passed
Passed
Passed
Passed
lifecycle testBasicSAMMethodsCalled
Passed
Passed
Passed
Passed
Failure
Passed
lifecycle testLogout
Passed
Passed
Passed
Passed
Passed
Passed
register-session testJoinSessionIsOptional
Passed
Passed
Passed
Passed
Passed
Passed
register-session testRemembersSession
Passed
Passed
Passed
Passed
Passed
Passed
status-codes test404inResponse
Passed
Passed
Passed
Failure
Failure
Passed
status-codes test404inResponse
Passed
Passed
Passed
Failure
Failure
Passed
wrapping testResponseWrapping
Passed
Passed
Passed
Passed
Passed
Passed
wrapping testRequestWrapping
Passed
Passed
Passed
Passed
Passed
Passed

Not shown in the table, but the absolute greatest improvement since JBoss switched to its new JASPIC implementation all the way back in WildFly 8.0.0.Alpha1 is the fact that JASPIC now finally works without the need of modifying WildFly by putting a dummy fragment in its standalone.xml file. It's not 100% perfect yet as the application archive (.war) still needs what is effectively a marker file to activate JASPIC, but this is much, much preferred over having to modify a server in order to activate a standard Java EE API that should just be there. Kudos to the JBoss team and a special thanks to Jason Greene for finally making this happen!

As can be seen, WildFly has seen many improvements over the years. Along the way a few regressions were introduced, but they were fixed again and now WildFly10rc5 is almost perfect with respect to the known bugs. Role propagation to JACC however still doesn't work. Although the usage of custom JACC providers is not that high, the test in question here uses the default provider for a rather useful query; "Can the authenticated user access a given resource?", e.g. "Can Pete access http://example.com/assets/someresource?".

The top performer as of now is Payarra, which passes all tests except for one of minor importance where a JSF based resource is included by an authentication module. As mentioned in the previous report this likely has to be fixed on the JSF side of things.

If all goes well we'll see a new beta of Liberty 9 this month which should also contain a number of fixes. The most problematic server at this moment is still WebLogic, which introduced a major regression between 12.1.3 and 12.2.1. Hopefully WebLogic will fix this regression soon. We'll repeat this test again when either of those publish their latest version.

Arjan Tijms

Thursday, November 12, 2015

The state of portable authentication for GlassFish, Payara, JBoss/WildFly, WebLogic and Liberty

Almost exactly 3 years ago I took an initial look at custom container authentication in Java EE. Java EE has a dedicated API for this called JASPIC. Even though JASPIC was a mandatory part of Java EE, support at the time was not really good. In this article we'll take a look at where things were and how things are in the current crop of servers in 2015.

To begin with, there were a number of spec omissions in JASPIC 1.0 (Java EE 6). The biggest one was that in order to register a server authentication module (SAM) an application ID had to be provided. This ID could not be obtained in a portable way. The JASPIC 1.1 MR rectified this.

Other spec omissions concerned JASPIC being silent about what would need to happen with respect to HttpServletRequest#login and HttpServletRequest#logout, and with forward and includes done from a SAM. The JASPIC 1.1 MR rectified these omissions too.

With respect to the actual behaviour there were a large number of very serious problems. Most concerned the very basic stateless nature of JASPIC. A JASPIC SAM is like a Servlet Filter; it's called for every request to both public and protected resources, and doesn't automatically create a session when a caller is authenticated. What actually happened differed per server back then. Some only called the SAM for protected resources, some automatically created a session and never called the SAM again, etc.

Another class of problems concerned the life cycle. A SAM has two seemingly simple methods; "validateRequest" that has to be called before Filters and Servlets are invoked, and "secureResponse" that has to be called after. Especially this "after" was ill understood. Some servers called "validateRequest" and "secureResponse" both before the Filters right after each other, while others called "secureResponse" every time data was written to the response.

A specifically peculiar thing was that no server back then was able to wrap the request and response, even though the JASPIC spec clearly states that this is required. Accessing resources from a SAM, such as EJB beans or datasources via JNDI, or CDI beans via the bean manager was a hit or miss as well. Basically every server behaved differently there.

Finally there were big issues with interpreting how portable a SAM should exactly be, and whether the technology should "just be there", or whether some server specific configuration had to be done first. One vendor seemingly interpreted the JASPIC spec as a portable "authentication mechanism" (the artefact that interacts with the user, such as Servlet's FORM), that then delegated to a proprietary (server specific) "identity store" (the artefact that stores the user data and groups, such as LDAP or a database).

In response to this I created a series of tests, that were later donated to the Java EE 7 samples project. Subsequently I worked with all vendors and asked them to improve their JASPIC implementations. With the exception of Geronimo all vendors were very cooperative, so I'd like to take the opportunity here to give them all a big thanks for their hard work.

So after 3 years of creating tests and reporting issues, what's the current situation like? To find out I executed the JASPIC tests against the current crop of servers. The result is shown below:

Running the Java EE 7 samples JASPIC tests
Module Test GlassFish 4.1.1 Payara 4.1.1.154 JBoss EAP 7 alpha1
WildFly 10rc4
WebLogic 12.2.1 Liberty 8.5.5.7
9 beta 2015.10
lifecycle testBasicSAMMethodsCalled
Passed
Passed
Passed
Passed
Passed
lifecycle testLogout
Passed
Passed
Passed
Passed
Passed
basic-authentication testProtectedPageNotLoggedin
Passed
Passed
Passed
Passed
Passed
basic-authentication testProtectedPageLoggedin
Passed
Passed
Passed
Failure
Passed
basic-authentication testPublicPageLoggedin
Passed
Passed
Passed
Failure
Passed
basic-authentication testPublicPageNotLoggedin
Passed
Passed
Passed
Passed
Passed
basic-authentication testPublicAccessIsStateless
Passed
Passed
Passed
Failure
Passed
basic-authentication testProtectedAccessIsStateless
Passed
Passed
Passed
Passed
Passed
basic-authentication testProtectedAccessIsStateless2
Passed
Passed
Passed
Passed
Passed
basic-authentication testProtectedThenPublicAccessIsStateless
Passed
Passed
Passed
Passed
Passed
dispatching-jsf-cdi testJSFwithCDIForwardViaPublicResource
Passed
Passed
Passed
Passed
Passed
dispatching-jsf-cdi testJSFwithCDIForwardViaProtectedResource
Passed
Passed
Passed
Passed
Passed
dispatching-jsf-cdi testJSFIncludeViaPublicResource
Failure
Failure
Failure
Failure
Failure
dispatching-jsf-cdi testJSFForwardViaPublicResource
Passed
Passed
Passed
Passed
Passed
dispatching-jsf-cdi testJSFForwardViaProtectedResource
Passed
Passed
Passed
Passed
Passed
dispatching-jsf-cdi testCDIForwardViaProtectedResource
Passed
Passed
Passed
Passed
Passed
dispatching-jsf-cdi testCDIForwardViaPublicResource
Passed
Passed
Passed
Passed
Passed
dispatching-jsf-cdi testCDIIncludeViaPublicResource
Passed
Passed
Passed
Passed
Failure
dispatching-jsf-cdi testJSFwithCDIIncludeViaPublicResource
Failure
Failure
Failure
Failure
Failure
dispatching testBasicIncludeViaPublicResource
Passed
Passed
Passed
Passed
Failure
dispatching testBasicForwardViaProtectedResource
Passed
Passed
Passed
Passed
Passed
dispatching testBasicForwardViaPublicResource
Passed
Passed
Passed
Passed
Passed
custom-principal testPublicPageLoggedin
Failure
Passed
Passed
Failure
Passed
custom-principal testPublicAccessIsStateless
Passed
Passed
Passed
Failure
Passed
custom-principal testProtectedAccessIsStateless
Passed
Passed
Passed
Passed
Passed
custom-principal testProtectedAccessIsStateless2
Passed
Passed
Passed
Passed
Passed
custom-principal testProtectedThenPublicAccessIsStateless
Passed
Passed
Passed
Passed
Passed
custom-principal testProtectedPageLoggedin
Failure
Passed
Passed
Failure
Passed
invoke-ejb-cdi protectedInvokeCDIFromSecureResponse
Passed
Passed
Passed
Failure
Failure
invoke-ejb-cdi protectedInvokeCDIFromCleanSubject
Passed
Passed
Passed
Passed
Failure
invoke-ejb-cdi protectedInvokeCDIFromValidateRequest
Passed
Passed
Passed
Failure
Failure
invoke-ejb-cdi protectedInvokeEJBFromSecureResponse
Failure
Failure
Passed
Passed
Passed
invoke-ejb-cdi protectedInvokeEJBFromCleanSubject
Passed
Passed
Passed
Passed
Passed
invoke-ejb-cdi protectedInvokeEJBFromValidateRequest
Failure
Failure
Passed
Passed
Passed
invoke-ejb-cdi publicInvokeEJBFromSecureResponse
Failure
Failure
Passed
Passed
Passed
invoke-ejb-cdi publicInvokeEJBFromValidateRequest
Failure
Failure
Passed
Passed
Passed
invoke-ejb-cdi publicInvokeEJBFromCleanSubject
Passed
Passed
Passed
Passed
Passed
invoke-ejb-cdi publicInvokeCDIFromSecureResponse
Passed
Passed
Passed
Failure
Failure
invoke-ejb-cdi publicInvokeCDIFromValidateRequest
Passed
Passed
Passed
Failure
Failure
invoke-ejb-cdi publicInvokeCDIFromCleanSubject
Passed
Passed
Passed
Passed
Passed
register-session testJoinSessionIsOptional
Passed
Passed
Passed
Failure
Passed
register-session testRemembersSession
Passed
Passed
Passed
Failure
Passed
status-codes test404inResponse
Passed
Passed
Failure
Passed
Passed
status-codes test404inResponse
Passed
Passed
Failure
Passed
Passed
async-authentication testBasicAsync
Passed
Passed
Passed
Passed
Passed
ejb-propagation publicServletCallingPublicEJBThenLogout
Passed
Passed
Passed
Failure
Passed
ejb-propagation protectedServletCallingProtectedEJB
Passed
Passed
Passed
Failure
Passed
ejb-propagation protectedServletCallingPublicEJB
Passed
Passed
Passed
Failure
Passed
ejb-propagation publicServletCallingProtectedEJB
Passed
Passed
Passed
Failure
Passed
wrapping testResponseWrapping
Passed
Passed
Passed
Passed
Passed
wrapping testRequestWrapping
Passed
Passed
Passed
Passed
Passed

 

As can be seen the situation has greatly improved. With the unfortunate exception of WebLogic 12.2.1 the basics now work everywhere. WebLogic 12.2.1 is perhaps a special case as it seems to be hit by a major bug where the most basic version of authentication doesn't work anymore, while it did work in the previous version 12.1.3. The fact that "testProtectedPageLoggedin" and "testPublicPageLoggedin" fail mean that actual authentication doesn't work properly. In this specific case it appears that when a caller authenticates with name "test" and gets the role "architect", then those are not available to the application. E.g. request#getUserPrincipal() still returns null and request#isUserInRole() returns false. This unfortunately means that for the moment until this bug is fixed JASPIC can not really be used on WebLogic at all.

Looking further at the results we see that the seemingly difficult to understand "secureResponse" method is now always called at the correct moment, and wrapping the request and response that once no server was able to do is now working well in all servers.

Forwards are now supported by all servers as are logouts. Includes are supported by most servers, only Liberty seems to have some issues with these. Curiously no server is able to include a resource that uses JSF. This is likely a JSF issue (as a JSF EG member and Mojarra committer this is something I probably have to fix myself ;))

Invoking resources has improved somewhat, but remains troublesome. Neither EJB beans nor CDI beans can be obtained and invoked on every server. EJB (specially those in the app scope such as java:comp, java:app, etc) work on JBoss EAP/WildFly, WebLogic and Liberty, but not on GlassFish and derivative Payara. CDI beans work in GlassFish, Payara and WildFly, but not in WebLogic and Liberty. WildFly is the one server where they both work.

The resources situation is still a spec issue as well and JASPIC 1.1 remains silent on whether this should work or not. The spec lead has clarified that even though the spec is silent on accessing EJB beans and other resources from the web component's JNDI namespaces, this is something that ought to work and GlassFish' current behaviour is just a bug. A next revision of the JASPIC spec should clarify this though. For the CDI beans no such clarification has been given, so vendors can't be asked to support this based on what the spec requires. However, accessing CDI from a SAM is very likely going to be a requirement coming from JSR 375 (Java EE security). So even though JASPIC doesn't mandate this now, it would be good if vendors already supported this in order to be prepared for Java EE 8.

Another case worth looking at is providing a custom principal from a SAM. This is a feature of JASPIC where a SAM can provide its own custom principal, e.g. org.example.MyPrincipal, which then has to be returned from request#getUserPrincipal(). This works on most servers except on GlassFish. It currently also doesn't work on WebLogic, but without further investigation it's hard to say whether it doesn't support this at all, or just because of the earlier failure of making the principal (custom or not) available.

Setting a response status code from a SAM (like e.g. a 404 - NOT FOUND) is something that is supported by all Servers, except for JBoss EAP/WildFly. This is currently the only unique failure for WildFly. Sort of, since it actually has already been fixed, but a build containing that fix has not yet been released.

From the outcome of the tests shown above it would seem JBoss EAP/WildFly clearly has the best JASPIC implementation, but there's one small but very important detail not shown in that table; the question whether JASPIC needs to be activated in a proprietary way. Unfortunately, JBoss EAP/WildFly indeeds needs such activation. If this activation would entail placing a special configuration file in the application archive it wouldn't be so bad, but JBoss EAP/WildFly actually requires the container to be modified before JASPIC can be used. This therefor means a SAM can not be deployed to a stock JBoss EAP/WildFly, which is very unfortunate indeed. There's a programmatic workaround available that doesn't require the container to be modified (see the activation link), but this is rather hacky and may break with every new release of JBoss EAP/WildFly.

The other server that needs server specific configuration is Liberty. Earlier versions of Liberty required all users and groups that a JASPIC SAM handles to be known by Liberty's proprietary user registry. An often downright impossible requirement in general and specifically for fully portable SAMs, and one that even violates the JASPIC spec. The current versions of Liberty have somewhat improved the situation by only requiring groups to be made known to Liberty. While still a very unfortunate requirement, it's at least possible to do this. Still, listing all the groups that an application uses in a proprietary file inside the container is a bit anti to one of the major use cases for which JASPIC is used; portable and application managed custom authentication. Instead of listing all the groups there's a workaround available where a NOOP user registry is installed and configured.

Conclusion

JBoss EAP 7/WildFly 10rc4 are almost perfect, if only JASPIC worked out of the box or could be activated from within the application archive using a configuration file. Payara 4.1.1.154 is another very good server for JASPIC. Here JASPIC works out of the box, but it suffers from a somewhat nasty bug that prevents it from using application scoped JNDI namespaces. GlassFish 4.1.1 is almost as good, but suffers from an extra bug that prevents it from using custom principals.

Liberty is quite good as well. It has slightly more bugs to fix than JBoss and Payara, but about the same as GlassFish. GlassFish can't use custom principals, Liberty can't do includes. Both can't obtain and invoke a specific bean type (for GlassFish this is EJB, for Liberty it's CDI). But above all Liberty suffers from its conflicting user registry requirement, although by far not as badly as before.

WebLogic 12.2.1 can at the moment not be recommended for JASPIC. It suffers from a severe bug that prohibits an application to use the authenticated identity, which is the core of what JASPIC does. Hopefully the WebLogic team is able to squash this particular bug soon.

All in all we've seen there's a steady and definite improvement going on for the various JASPIC implementations, but as can be seen there's still room left for improvement.

Arjan Tijms