In Java EE declaring security constraints via e.g. @RolesAllowed, programmatically checking them via e.g. HttpServletRequest#isUserInRole and triggering a container login via HttpServletRequest#login is all relatively straightforward.
Unfortunately, providing the logic for the actual authentication and role mapping/retrieval remains a cumbersome exercise. This is especially painful for simple applications which don't need elaborate security abstractions. JASPIC (JSR 196) did provide a means to make authentication modules portable in Java EE 6, but actually using those remains a fairly tedious and vendor specific process.
For instance, JBoss AS 7 requires the following steps:
- Create a named security domain outside the application in a vendor specific way, that's tied to a specific AS instance.
- Connect the JASPIC authentication module to this security domain in a vendor specific way.
- Declare in web.xml that JASPI is the realm.
- Link the (web) application itself to the global security domain using a vendor specific descriptor.
- In the vendor specific descriptor, specify an internal vendor specific class name that's internally needed to activate JASPI.
GlassFish requires the user to take different, but similar steps including interacting with a graphical UI (see http://www-02.imixs.com/roller/ralphsjavablog/entry/openid_serverauthmodule_jsr_196_with)
Not only are these steps anti ease-of-use, they are also notoriously non-portable despite JASPIC's promise of portability. Furthermore, having the authentication logic outside the application itself prohibits the developer to easily make use of application domain models and code for the authentication process (which is typical for applications that manage their users internally and don't need to integrate with an overall user directory system of e.g. an enterprise).
I therefor would like to propose standardizing how JASPIC authentication modules can be embedded in (simple) applications in a portable way, and additionally address the use case that for small/test applications even a JASPIC module is too much and something even simpler is needed. This is especially true when the application already makes use of a custom mechanism (typically a Servlet Filter) in combination with HttpServletRequest#login.
Example of simplified authentication/role mapping:
Following the presence of such simplified identity store in the application, the following should hold:
- The application is considered to be in a default security realm.
- The application will make use of this security realm (no explicit mention in web.xml required).
- Whenever a container login is triggered, MyIdentityStore is used for authentication (only username/password supported of course)
- If authentication succeeds, the String returned by getUserName will be what HttpServletRequest#getUserPrincipal.getName() and corresponding methods in EJB etc return.
- For each String inside the list returned by getApplicationRoles, methods like HttpServletRequest#isUserInRole will return true, and annotations like @RolesAllowed referencing those will be considered satisfied.
- No upfront declaration of roles in any descriptor is required.
- The roles returned by getApplicationRoles should be directly useable in the application. Specifically, things as (vendor specific) group to role mappings (such as what happens in GlassFish) should not be required.
Example of standardized installation of a JASPIC authentication module in application.xml or web.xml:
Alternatively, the presence of a JASPIC authentication module inside the application annotated with a special annotation (perhaps the same one as used for the simplified login module), can have the same effect of having the module automatically installed.
Like the standardized identity store, when such a JASPIC authentication module is declared in an application, no further configuration, role mapping or role declarations should be required, other than those that are specific for the authentication module itself.