Chapter 2. How to Set Up SSO for JBoss EAP with Kerberos 2.1. Required Components You must have the following components when setting up JBoss EAP for SSO with Kerberos: A properly configured Kerberos environment A JBoss EAP instance A web application 2.1.1. About JBoss Negotiation Toolkit The JBoss Negotiation Toolkit is a debugging tool to help users debug and test authentication mechanisms before introducing an application into production. It is an unsupported tool but can be very helpful, as SPNEGO can be difficult to configure for web applications. You can download a prebuilt WAR file of the JBoss Negotiation Toolkit from the JBoss Negotiation Toolkit repository . You should download the version of JBoss Negotiation Toolkit that matches the version of JBoss Negotiation included in JBoss EAP. For example, if you are using JBoss EAP 7.1, which uses JBoss Negotiation 3.0.4.Final-redhat-1 , you should use jboss-negotiation-toolkit-3.0.4.Final.war . You can determine which version of JBoss Negotiation is being used by looking at EAP_HOME /modules/system/layers/base/org/jboss/security/negotiation/main/module.xml . 2.2. Kerberos Environment As discussed in How Does Kerberos Provide SSO for JBoss EAP? , Kerberos relies on a third party, the KDC, to provide authentication and authorization decisions. This also requires clients, for example browsers, and their host to be properly configured to authenticate with the KDC. This guide is primarily focused on how to configure JBoss EAP and its hosted web applications, so configuring the KDC and Kerberos domain are not in the scope of this document. Note The subsequent sections assume a KDC and Kerberos domain have already been set up and properly configured. 2.3. Differences from Configuring Versions JBoss EAP There are a few noticeable differences between JBoss EAP 7.2 or higher and earlier versions: The NegotiationAuthenticator valve is no longer required in the jboss-web.xml , but there still must be <security-constraint> and <login-config> elements defined in the web.xml . These are used to decide which resources are secured. The auth-method element in the <login-config> element is now a comma-separated list. The exact value SPNEGO must be there and should appear first in that list. In cases where FORM authentication is desired as a fallback, the exact value would be SPNEGO,FORM . The jboss-deployment-structure.xml file is not required when using the elytron subsystem. 2.4. Configuring the JBoss EAP Instance You can configure an application deployed to JBoss EAP to use either elytron or the legacy security subsystem, but you cannot configure it to use both. 2.4.1. Configure the Elytron Subsystem Important The following steps assume you have a working KDC, Kerberos domain, and browsers configured and working. Configure a kerberos-security-factory . Configure the system properties for Kerberos. Depending on how your environment is configured, you will need to set some of the system properties below. System Property Description java.security.krb5.kdc The host name of the KDC. java.security.krb5.realm The name of the realm. java.security.krb5.conf The path to the configuration krb5.conf file. sun.security.krb5.debug If true , debugging mode will be enabled. To configure a system property in JBoss EAP using the management CLI: Configure an Elytron security realm for assigning roles. The client's Kerberos token will provide the principal, but you need a way to map that principal to a role for your application. There are several ways to accomplish this, but this example creates a filesystem-realm , adds a user to the realm that matches the principal from the Kerberos token, and assigns roles to that user. Add a simple-role-decoder . This simple-role-decoder decodes a principal's roles from the Roles attribute. You can change this value if your roles are in a different attribute. Configure a security-domain . Configure an http-authentication-factory that uses the kerberos-security-factory . Configure an application-security-domain in the undertow subsystem: 2.4.2. Configure the Legacy Security Subsystem JBoss EAP comes with all the components necessary to use Kerberos, using SPNEGO and JBoss Negotiation, for SSO with deployed applications, but the following configuration changes need to be made: Note The management CLI commands shown assume that you are running a JBoss EAP standalone server. For more details on using the management CLI for a JBoss EAP managed domain, see the JBoss EAP Management CLI Guide . Configure the server identity, or host, security domain. This security domain authenticates the container itself to the KDC. It needs to use a login module which accepts a static login mechanism since a real user is not involved in this connection. The following example uses a static principal and references a keytab file which contains the credential. Example: Creating a Server Identity Security Domain If using the IBM JDK, the options for Kerberos module are different. The jboss.security.disable.secdomain.option system property must be set to true . See Configure relevant system properties for more information. In addition, the login module should be configured as follows: Example: IBM JDK For a complete list of options for configuring the Kerberos login module, see the JBoss EAP Login Module Reference . Configure the web application security domain. The web application security domain is used to authenticate the individual user to the KDC. There needs to be at least one login module to authenticate the user. There also must be a way to search for the roles to apply to the user. This can be accomplished in many different ways, for example by adding a <mapping> that manually maps users to roles, adding a second login module for mapping users to roles, and so on. The following shows an example web application security domain. Example: Creating a Server Identity Security Domain For a complete list of options for configuring the SPNEGO login module, see the JBoss EAP Login Module Reference . Configure relevant system properties. JBoss EAP offers the ability to configure system properties related to connecting to Kerberos servers. Depending on the KDC, Kerberos Domain, and network configuration, the following system properties may or may not be required. <system-properties> <property name="java.security.krb5.kdc" value="mykdc.mydomain"/> <property name="java.security.krb5.realm" value=" MY_REALM "/> <property name="java.security.krb5.conf" value="/path/to/krb5.conf"/> <property name="jboss.security.disable.secdomain.option" value="true"/> <property name="sun.security.krb5.debug" value="false"/> </system-properties> Property Description java.security.krb5.kdc The host name of the KDC. java.security.krb5.realm The name of the realm. java.security.krb5.conf The path to the configuration krb5.conf file. jboss.security.disable.secdomain.option When set to true , disables automatic adding of jboss.security.security_domain login module option to login modules declared in the security domain. Must be set to true when using the IBM JDK. sun.security.krb5.debug If true , debugging mode will be enabled. Note By default, each login module defined in a security domain has the jboss.security.security_domain module option added to it automatically. This option causes problems with login modules which check to make sure that only known options are defined. The IBM Kerberos login module, com.ibm.security.auth.module.Krb5LoginModule is one of these. This behavior of adding this module option can disabled by setting the jboss.security.disable.secdomain.option system property to true when starting JBoss EAP. This can be accomplished by configuring the <system-properties> , using the management CLI or management console, or by adding -Djboss.security.disable.secdomain.option=true to the startup parameters. For more information about configuring system properties, see the JBoss EAP Management CLI Guide . 2.5. Configuring the Web Application Once the security domains have been configured, the web application must be configured to use those security domains in order to enable Kerberos authentication. Once the application changes have been made, it can be deployed to the JBoss EAP instance and begin using Kerberos for authentication. The following updates must be made the application: Configure the web.xml to use the SPNEGO authentication method. The web.xml file should contain the following: A <security-constraint> with a <web-resource-collection> containing a <url-pattern> that maps to the URL pattern of the secured area. Optionally, <security-constraint> may also contain an <auth-constraint> stipulating the allowed roles. If any roles were specified in the <auth-constraint> , those roles should be defined in a <security-role> . A <login-config> containing a <auth-method> with the exact value of SPNEGO . Important The <auth-method> element expects a comma-separated list of specific values. For SPNEGO authentication to be properly configured, the exact value SPNEGO must appear in the <auth-method> element and should appear first. Incorporating additional authentication types is discussed in Adding a FORM Login as a Fallback . The <security-constraint> and <security-role> elements enable administrators to set up restricted or unrestricted areas based on URL patterns and roles. This allows resources to be secured or unsecured. Example: web.xml File <web-app> <display-name>App1</display-name> <description>App1</description> <!-- Define a security constraint that requires the Admin role to access resources --> <security-constraint> <display-name>Security Constraint on Conversation</display-name> <web-resource-collection> <web-resource-name>exampleWebApp</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>Admin</role-name> </auth-constraint> </security-constraint> <!-- Define the Login Configuration for this Application --> <login-config> <auth-method>SPNEGO</auth-method> <realm-name>SPNEGO</realm-name> </login-config> <!-- Security roles referenced by this web application --> <security-role> <description>Role required to log in to the Application</description> <role-name>Admin</role-name> </security-role> </web-app> Configure jboss-web.xml to use the configured security domain. The jboss-web.xml file should have the following: A <security-domain> to specify which security domain to use for authentication and authorization. Optionally <jacc-star-role-allow> , which enables the use of the asterisk character in role-name element in web.xml to match multiple role names. Example: jboss-web.xml File <jboss-web> <security-domain>app-spnego</security-domain> <jacc-star-role-allow>true</jacc-star-role-allow> </jboss-web> Add the JBoss Negotiation dependencies to the deployment for the legacy security subsystem. Important If you are using the elytron subsystem, you can skip this step. A web application using SPNEGO and JBoss Negotiation requires a dependency to be defined in jboss-deployment-structure.xml so that the JBoss Negotiation classes can be located. Since JBoss EAP provides all necessary JBoss Negotiation and related classes, the application just needs to declare them as dependencies to use them. Using jboss-deployment-structure.xml to Declare Dependencies <jboss-deployment-structure> <deployment> <dependencies> <module name="org.jboss.security.negotiation"/> </dependencies> </deployment> </jboss-deployment-structure> Alternatively, this dependency may be defined in a META-INF/MANIFEST.MF file instead: Using META-INF/MANIFEST.MF to Declare Dependencies Manifest-Version: 1.0 Dependencies: org.jboss.security.negotiation 2.6. Additional Considerations for Active Directory This section describes how to configure the accounts required for SPNEGO authentication to be used when JBoss EAP is running on a Microsoft Windows server, which is a part of the Active Directory domain. In this section, the host name that is used to access the server as is referred to as HOST_NAME , the realm is referred to as REALM , the domain is referred to as DOMAIN , and the server hosting the JBoss EAP instance is referred to as MACHINE_NAME .  2.6.1. Configuration for Microsoft Windows Domain Clear existing service principal mappings. On a Microsoft Windows network some mappings are created automatically. Delete the automatically created mappings to map the identity of the server to the service principal for negotiation to take place correctly. The mapping enables the web browser on the client computer to trust the server and attempt SPNEGO. The client computer verifies with the domain controller for a mapping in the form of HTTP/ HOST_NAME . The following are the steps to delete the existing mappings: List the mapping registered with the domain for the computer using the command: Delete the existing mappings using the commands: Create a host user account. Note Ensure the host user name is different from the MACHINE_NAME . In the rest of the section the host user name is referred to as USER_NAME . Define the mapping between the USER_NAME and HOST_NAME . Run the following command to configure the service principal mapping: Enter the password for the user name, when prompted. Verify the mapping by running the following command: setspn -L USER_NAME . Note If you get KrbException: Specified version of key is not available errors from the JRE, you might need to set the Key Version to 0 : -kvno 0 . Note that REALM needs to be all in uppercase, while the HOST_NAME should be all lowercase. Also, the HOST_NAME must be a FQDN, and must be a resolvable A or AAAA record, but not a CNAME record. Using -crypto all only works on Windows Server 2008 and later. For Windows Server 2003, you must specify the exact setting. Define the principal within the security domain. The principal can be defined or updated in the elytron or legacy security subsystem to HTTP/ HOST_NAME @ REALM . Important If you make any modification to any user, for example changing options or their password, you must regenerate the keytab .

Commands:
/subsystem=elytron/kerberos-security-factory=krbSF:add(principal="HTTP/host@REALM", path="/path/to/http.keytab", mechanism-oids=[1.2.840.113554.1.2.2, 1.3.6.1.5.5.2])
/system-property=java.security.krb5.conf:add(value="/path/to/krb5.conf")
/subsystem=elytron/filesystem-realm=exampleFsRealm:add(path=fs-realm-users, relative-to=jboss.server.config.dir) /subsystem=elytron/filesystem-realm=exampleFsRealm:add-identity(identity=user1@REALM) /subsystem=elytron/filesystem-realm=exampleFsRealm:add-identity-attribute(identity=user1@REALM, name=Roles, value=["Admin","Guest"])
/subsystem=elytron/simple-role-decoder=from-roles-attribute:add(attribute=Roles)
/subsystem=elytron/security-domain=exampleFsSD:add(realms=[{realm=exampleFsRealm, role-decoder=from-roles-attribute}], default-realm=exampleFsRealm, permission-mapper=default-permission-mapper)
/subsystem=elytron/http-authentication-factory=example-krb-http-auth:add(http-server-mechanism-factory=global, security-domain=exampleFsSD, mechanism-configurations=[{mechanism-name=SPNEGO, mechanism-realm-configurations=[{realm-name=exampleFsSD}], credential-security-factory=krbSF}])
/subsystem=undertow/application-security-domain=app-spnego:add(http-authentication-factory=example-krb-http-auth)
/subsystem=security/security-domain=host:add(cache-type=default) /subsystem=security/security-domain=host/authentication=classic:add() /subsystem=security/security-domain=host/authentication=classic/login-module=Kerberos:add(code=Kerberos, flag=required, module-options=[storeKey=true, refreshKrb5Config=true, useKeyTab=true, principal=host/testserver@MY_REALM, keyTab=/home/username/service.keytab, doNotPrompt=true, debug=false]) reload
/subsystem=security/security-domain=host:add(cache-type=default) /subsystem=security/security-domain=host/authentication=classic:add() /subsystem=security/security-domain=host/authentication=classic/login-module=Kerberos:add(code=Kerberos, flag=required, module-options=[principal=host/testserver@MY_REALM, keyTab="file:///root/keytab", credsType=acceptor]) reload
/subsystem=security/security-domain=app-spnego:add(cache-type=default) /subsystem=security/security-domain=app-spnego/authentication=classic:add() /subsystem=security/security-domain=app-spnego/authentication=classic/login-module=SPNEGO:add(code=SPNEGO, flag=required, module-options=[serverSecurityDomain=host]) reload
<system-properties> <property name="java.security.krb5.kdc" value="mykdc.mydomain"/> <property name="java.security.krb5.realm" value=" MY_REALM "/> <property name="java.security.krb5.conf" value="/path/to/krb5.conf"/> <property name="jboss.security.disable.secdomain.option" value="true"/> <property name="sun.security.krb5.debug" value="false"/> </system-properties>
<web-app> <display-name>App1</display-name> <description>App1</description> <!-- Define a security constraint that requires the Admin role to access resources --> <security-constraint> <display-name>Security Constraint on Conversation</display-name> <web-resource-collection> <web-resource-name>exampleWebApp</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>Admin</role-name> </auth-constraint> </security-constraint> <!-- Define the Login Configuration for this Application --> <login-config> <auth-method>SPNEGO</auth-method> <realm-name>SPNEGO</realm-name> </login-config> <!-- Security roles referenced by this web application --> <security-role> <description>Role required to log in to the Application</description> <role-name>Admin</role-name> </security-role> </web-app>
<jboss-web> <security-domain>app-spnego</security-domain> <jacc-star-role-allow>true</jacc-star-role-allow> </jboss-web>
<jboss-deployment-structure> <deployment> <dependencies> <module name="org.jboss.security.negotiation"/> </dependencies> </deployment> </jboss-deployment-structure>
Manifest-Version: 1.0 Dependencies: org.jboss.security.negotiation
setspn -L MACHINE_NAME
setspn -D HTTP/ HOST_NAME MACHINE_NAME
setspn -D host/ HOST_NAME MACHINE_NAME
ktpass -princ HTTP/ HOST_NAME @ REALM -pass * [-kvno 0] -mapuser DOMAIN \ USER_NAME -out jboss.keytab -ptype KRB5_NT_PRINCIPAL -crypto all