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.negotiationAS module is defined inMETA-INF/jboss-deployment-structure.xmldeployment 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.xmldeployment 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.negotiationmodule, 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 theSPNEGOLoginModuleJAAS login module and it has nameSPNEGOin 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="[email protected]" value="Admin"/> <module-option name="[email protected]" value="User"/> </mapping-module> </mapping> </security-domain>
-
The
SPNEGOsecurity domain references the second domain which is used for server authentication in the Kerberos realm. It usesKrb5LoginModulelogin 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/[email protected]"/> </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 gitUbuntu:
sudo apt-get install wget unzip openjdk-6-jdk krb5-user git mavenIf 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=localhostexport SPNEGO_TEST_DIR=/tmp/spnego-demo-testdir
mkdir $SPNEGO_TEST_DIRIf 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_DIRThe test server has hardcoded following settings:
searchBaseDn = dc=jboss,dc=org
primaryRealm = JBOSS.ORG
kdcPrincipal = krbtgt/[email protected]
The test server project is a runnable JAR file
cd $SPNEGO_TEST_DIR
java -jar kerberos-using-apacheds.jar test.ldifLaunching 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: [email protected]
dn: uid=jduke,ou=Users,dc=jboss,dc=org
userPassword: theduke
krb5PrincipalName: [email protected]
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.confCorrect configuration in krb5.conf file is necessary for client authentication (kinit) and also for correct negotiation
in a web browser.
Login to Kerberos as [email protected]
Refer to generated krb5.conf file and use kinit system tool to authenticate in Kerberos.
kinit [email protected] << EOT
secret
EOTA 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/[email protected] principal:
cd $SPNEGO_TEST_DIR
java -classpath kerberos-using-apacheds.jar \
org.jboss.test.kerberos.CreateKeytab \
HTTP/[email protected] \
httppwd \
http.keytabYou 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/[email protected]")]}]) {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"=>[("[email protected]"=>"Admin"),("[email protected]"=>"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.txtStart the configured WildFly server:
$JBOSS_HOME/bin/standalone.shYou'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
[email protected]and[email protected]should have access) - Admin page is reachable only by Admin role (only
[email protected]should have access)