Demo application which shows, how to get Kerberos authentication working in WildFly and JBoss Enterprise Application Platform (EAP).
The out of the box SPNEGO authentication doesn't work in WildFly versions 8 and 9 because missing integration part with Undertow (new web server component). The issue (WFLY-2553) was resolved in WildFly 10. If you need to get SPNEGO working with WildFly 8.x/9.x, try to use either servlet filter approach or this custom authenticator for WildFly.
-
new dependency on
org.jboss.security.negotiation
AS module is defined inMETA-INF/jboss-deployment-structure.xml
deployment descriptor file in the SPNEGO-enabled application<jboss-deployment-structure> <deployment> <dependencies> <module name="org.jboss.security.negotiation" /> </dependencies> </deployment> </jboss-deployment-structure>
-
We have to define which security domain will be used for authentication to the application in
WEB-INF/jboss-web.xml
deployment descriptor:<jboss-web> <security-domain>SPNEGO</security-domain> </jboss-web>
-
In case of EAP 6.x and JBoss AS7 (i.e. the versions with Tomcat based web server), you have also to use custom authenticator valve. The valve class is present in the
org.jboss.security.negotiation
module, which we introduced as dependency in the first step.<jboss-web> <security-domain>SPNEGO</security-domain> <valve> <class-name>org.jboss.security.negotiation.NegotiationAuthenticator</class-name> </valve> </jboss-web>
-
-
The security domain in server configuration (
standalone.xml
) uses theSPNEGOLoginModule
JAAS login module and it has nameSPNEGO
in this demo.<security-domain name="SPNEGO" cache-type="default"> <authentication> <login-module code="SPNEGO" flag="required"> <module-option name="serverSecurityDomain" value="host"/> </login-module> </authentication> <mapping> <mapping-module code="SimpleRoles" type="role"> <module-option name="jduke@JBOSS.ORG" value="Admin"/> <module-option name="hnelson@JBOSS.ORG" value="User"/> </mapping-module> </mapping> </security-domain>
-
The
SPNEGO
security domain references the second domain which is used for server authentication in the Kerberos realm. It usesKrb5LoginModule
login module and its name ishost
.<security-domain name="host" cache-type="default"> <authentication> <login-module code="Kerberos" flag="required"> <module-option name="storeKey" value="true"/> <module-option name="refreshKrb5Config" value="true"/> <module-option name="useKeyTab" value="true"/> <module-option name="doNotPrompt" value="true"/> <module-option name="keyTab" value="/tmp/spnego-demo-testdir/http.keytab"/> <module-option name="principal" value="HTTP/localhost@JBOSS.ORG"/> </login-module> </authentication> </security-domain>
There are several steps, which should be completed to get the demo working.
Install MIT kerberos utils, Java JDK version 6 or newer, git and Maven, unzip and wget.
Fedora:
sudo yum install wget unzip java-1.7.0-openjdk-devel krb5-workstation maven git
Ubuntu:
sudo apt-get install wget unzip openjdk-6-jdk krb5-user git maven
If you use the Firefox, go to about:config
and set following entries there:
network.negotiate-auth.delegation-uris = localhost
network.negotiate-auth.trusted-uris = localhost
If you use Chromium, then start it with following command line arguments:
chromium-browser --auth-server-whitelist=localhost --auth-negotiate-delegate-whitelist=localhost
export SPNEGO_TEST_DIR=/tmp/spnego-demo-testdir
mkdir $SPNEGO_TEST_DIR
If you don't have some Kerberos server prepared already, you can use the testing kerberos-using-apacheds project:
cd $SPNEGO_TEST_DIR
git clone git://github.com/kwart/kerberos-using-apacheds.git
cd kerberos-using-apacheds
mvn clean package
cp test.ldif target/kerberos-using-apacheds.jar $SPNEGO_TEST_DIR
The test server has hardcoded following settings:
searchBaseDn = dc=jboss,dc=org
primaryRealm = JBOSS.ORG
kdcPrincipal = krbtgt/JBOSS.ORG@JBOSS.ORG
The test server project is a runnable JAR file
cd $SPNEGO_TEST_DIR
java -jar kerberos-using-apacheds.jar test.ldif
Launching the test server also creates a krb5.conf
kerberos configuration file in the current folder. We will use it later.
There are 3 important users which you will use later in the imported test.ldif
file:
dn: uid=HTTP,ou=Users,dc=jboss,dc=org
userPassword: httppwd
krb5PrincipalName: HTTP/${hostname}@JBOSS.ORG
dn: uid=hnelson,ou=Users,dc=jboss,dc=org
userPassword: secret
krb5PrincipalName: hnelson@JBOSS.ORG
dn: uid=jduke,ou=Users,dc=jboss,dc=org
userPassword: theduke
krb5PrincipalName: jduke@JBOSS.ORG
The HTTP user is the principal of your WildFly/EAP server. The other 2 users are test client principals.
The ${hostname}
is a placeholder which will be replaced with the value of system property kerberos.bind.address
.
It this property is not defined, then the localhost
value is used.
The previous step generated krb5.conf
file. Backup your original configuration in /etc/krb5.conf
and replace it with the generated one.
mv /etc/krb5.conf /etc/krb5.conf.orig
cp $SPNEGO_TEST_DIR/krb5.conf /etc/krb5.conf
Correct configuration in krb5.conf
file is necessary for client authentication (kinit
) and also for correct negotiation
in a web browser.
Login to Kerberos as hnelson@JBOSS.ORG
Refer to generated krb5.conf
file and use kinit
system tool to authenticate in Kerberos.
kinit hnelson@JBOSS.ORG << EOT
secret
EOT
A keytab is a file containing pairs of Kerberos principals and encrypted keys derived from the Kerberos password. Keytab files can be used to log into Kerberos without being prompted for a password (e.g. authenticate without human interaction).
Use the CreateKeytab
utility from the kerberos-using-apacheds
project to generate the keytab for the HTTP/localhost@JBOSS.ORG
principal:
cd $SPNEGO_TEST_DIR
java -classpath kerberos-using-apacheds.jar \
org.jboss.test.kerberos.CreateKeytab \
HTTP/localhost@JBOSS.ORG \
httppwd \
http.keytab
You can also use some system utility such as ktutil
to generate your keytab file.
Download the latest WildFly and install it.
Configure the server using JBoss CLI:
export JBOSS_HOME=/path/to/wildflyFolder
cat << EOT > $SPNEGO_TEST_DIR/cli-commands.txt
embed-server
/subsystem=security/security-domain=host:add(cache-type=default)
/subsystem=security/security-domain=host/authentication=classic:add(login-modules=[{"code"=>"Kerberos", "flag"=>"required", "module-options"=>[ ("debug"=>"true"),("storeKey"=>"true"),("refreshKrb5Config"=>"true"),("useKeyTab"=>"true"),("doNotPrompt"=>"true"),("keyTab"=>"$SPNEGO_TEST_DIR/http.keytab"),("principal"=>"HTTP/localhost@JBOSS.ORG")]}]) {allow-resource-service-restart=true}
/subsystem=security/security-domain=SPNEGO:add(cache-type=default)
/subsystem=security/security-domain=SPNEGO/authentication=classic:add(login-modules=[{"code"=>"SPNEGO", "flag"=>"required", "module-options"=>[("serverSecurityDomain"=>"host")]}]) {allow-resource-service-restart=true}
/subsystem=security/security-domain=SPNEGO/mapping=classic:add(mapping-modules=[{"code"=>"SimpleRoles", "type"=>"role", "module-options"=>[("jduke@JBOSS.ORG"=>"Admin"),("hnelson@JBOSS.ORG"=>"User")]}]) {allow-resource-service-restart=true}
/system-property=java.security.krb5.conf:add(value="$SPNEGO_TEST_DIR/krb5.conf")
/system-property=java.security.krb5.debug:add(value=true)
/system-property=jboss.security.disable.secdomain.option:add(value=true)
EOT
"$JBOSS_HOME/jboss-cli.sh" --file=$SPNEGO_TEST_DIR/cli-commands.txt
Start the configured WildFly server:
$JBOSS_HOME/bin/standalone.sh
You've created host
and SPNEGO
security domains now. Also some kerberos authentication related system properties were added.
Use this spnego-demo
web application to test your settings.
cd $SPNEGO_TEST_DIR
git clone git://github.com/kwart/spnego-demo.git
cd spnego-demo
mvn clean package
cp target/spnego-demo.war $JBOSS_HOME/standalone/deployments
Open the application URL in your SPNEGO enabled browser
chromium-browser --auth-server-whitelist=localhost \
--auth-negotiate-delegate-whitelist=localhost http://localhost:8080/spnego-demo/
There are 3 test pages included:
- Home page is unprotected
- User page is reachable by Admin and User role (so both
jduke@JBOSS.ORG
andhnelson@JBOSS.ORG
should have access) - Admin page is reachable only by Admin role (only
jduke@JBOSS.ORG
should have access)