Hi,
JASPI make us to plug in other authentication module (for example, using openID or other mechanism to authenticate users) easier on Jetty for container-managed security. There is jetty-jaspi module in the Jetty source
code base, but I think it has not been maintained for a long time.
By making a little fix on jetty-jaspi module, I make the JASPI works well on Jetty 8. I attach the changes. I hope if I did it well, it could be merged into the next Jetty 8 release.
To use JASPI:
1.
Creating a JASPI configuration XML file for your auth module:
<?xml version="1.0" encoding="UTF-8"?>
<jaspi xmlns="http://geronimo.apache.org/xml/ns/geronimo-jaspi">
<configProvider>
<messageLayer>HTTP</messageLayer>
<appContext>/ui</appContext>
<description>description</description>
<serverAuthConfig>
<authenticationContextID>authenticationContextID2</authenticationContextID>
<protected>true</protected>
<serverAuthContext>
<serverAuthModule>
<className>org.eclipse.jetty.security.jaspi.modules.FormAuthModule</className>
<options>
org.eclipse.jetty.security.jaspi.modules.LoginPage=/secure/jaaslogin
org.eclipse.jetty.security.jaspi.modules.ErrorPage=/secure/jaaserror
</options>
</serverAuthModule>
</serverAuthContext>
</serverAuthConfig>
<persistent>true</persistent>
</configProvider>
</jaspi>
The above using the Jetty built-in FormAuthModule, if you want to use the built-in Basic or Digest auth module, the <serverAuthModule> part should be:
<serverAuthModule>
<className>org.eclipse.jetty.security.jaspi.modules.DigestAuthModule</className>
<options>
org.eclipse.jetty.security.jaspi.modules.RealmName=JAASRealm
</options>
</serverAuthModule>
Or
<serverAuthModule>
<className>org.eclipse.jetty.security.jaspi.modules.BasicAuthModule</className>
<options>
org.eclipse.jetty.security.jaspi.modules.RealmName=JAASRealm
</options>
</serverAuthModule>
Here I use the implementation of JASPI of geronimo-jaspi 2.0-SNAPSHOT from geronimo-jaspi (https://github.com/apache/geronimo-jaspi). you could use geronimo-jaspi 1.1.1 release, but you might need to implements javax.security.auth.message.config.AuthConfigProvider
(and not javax.security.auth.message.module.ServerAuthModule) and configure it in the above XML file.
2.
Configuring your AppContext to use JaspiAuthenticatorFactory. I configured it in jetty-web.xml file:
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="securityHandler">
<New class="org.eclipse.jetty.security.ConstraintSecurityHandler">
<Set name="loginService">
<New class="org.eclipse.jetty.plus.jaas.JAASLoginService">
<Set name="name">JAASRealm</Set>
<Set name="loginModuleName">jaas</Set>
</New>
</Set>
<Set name="authenticatorFactory">
<New class="org.eclipse.jetty.security.jaspi.JaspiAuthenticatorFactory" />
</Set>
</New>
</Set>
</Configure>
3.
When launching Jetty, using -Dorg.apache.geronimo.jaspic.configurationFile to tell geronimo-jaspi where to find the JASPI configuration file. The following is the jetty-maven-plugin configuration (my JASPI configuration
file is form-test-jaspi-2.xml):
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty.version}</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<webAppConfig>
<contextPath>/ui</contextPath>
<parentLoaderPriority>true</parentLoaderPriority>
</webAppConfig>
<systemProperties>
<systemProperty>
<name>java.security.auth.login.config</name>
<value>./conf/jetty/jaas.conf</value>
</systemProperty>
<systemProperty>
<name>org.apache.geronimo.jaspic.configurationFile</name>
<value>./conf/jaspi/form-test-jaspi-2.xml</value>
</systemProperty>
</configuration>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jaspi</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.components</groupId>
<artifactId>geronimo-jaspi</artifactId>
<version>2.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
In my test, I use my own JAAS login module, which configured in jaas.conf. you could use Jetty built-in login module as described in http://wiki.eclipse.org/Jetty/Feature/JAAS.
Q: what I cannot know if I did it correctly is the changes to JaspiAuthenticator. I removed the following lines at the beginning of validateRequest():
if (_allowLazyAuthentication && !mandatory)
return _deferred;
and add the following:
if ( !isMandatory( messageInfo ) )
return _deferred ;
after “if (authStatus == AuthStatus.SUCCESS)” at line 114. This make me have to add the following in validateRequest() of FormAuthModule class:
Authentication authentication = ((org.eclipse.jetty.server.Request)request).getAuthentication() ;
if (authentication instanceof Authentication.Deferred )
return AuthStatus.SEND_SUCCESS;
or the unprotected resources won’t be handled properly. This makes the auth module to have to know how Authentication.Deferred works, it is not an easier to use dependency. This might be that I do not understand DeferredAuthentication
class clearly. Your advice is appreciated.
Thanks.