Chapter 15. Simple and Protected GSSAPI Negotiation Mechanism (SPNEGO)
The Simple and Protected GSSAPI Negotiation Mechanism (SPNEGO) uses desktop credentials provided during desktop authentication to transparently authenticate a portal user through a web browser.
Let's illustrate this mechanism on a typical use case:
- A user logs into their desktop computer with a login that is governed by an Active Directory domain.
- The user launches a web browser to access a web application that is hosted on the portal and uses JBoss Negotiation.
- The browser transfers the desktop credentials to the web application.
- The portal uses background GSS messages to validate the user's Kerberos ticket with the Active Directory (or another Kerberos server).
- The user experiences a seamless sign-on into the web application.
15.1. SPNEGO Server
15.1.1. Configuring the SPNEGO Server
This section describes the steps to set up a Kerberos server on Linux. The server will then be used for SPNEGO authentication against the portal. The procedure below only describes the basic steps to configure a SPNEGO server in a Linux environment. If you are already familiar with SPNEGO, or if you are using Windows and an Active Directory domain, you can proceed to Section 15.3, “Configuring SPNEGO” to see how SPNEGO can be integrated with the portal. Kerberos setup is also dependent on your Linux distribution, so the steps can be slightly different in your environment.
Procedure 15.1. Configuring the SPNEGO Server
- Ensure correct host name to IP address mapping on the machine where Kerberos and the portal are running. For example, if the machine's IP address is
192.168.1.88and you want it to be accessed under theserver.local.networkhost name, add the following line to the /etc/hosts file:192.168.1.88 server.local.network
Note
It is not recommended you use loopback addresses. - Install Kerberos with these packages: krb5-admin-server, krb5-kdc, krb5-config, krb5-user, krb5-clients, and krb5-rsh-server.
- Edit the Kerberos configuration in the /etc/krb5.config file:
- Uncomment the following lines:
default_tgs_enctypes = rc4-hmac default_tkt_enctypes = rc4-hmac permitted_enctypes = rc4-hmac
- Add local.network as a default realm, add it to the list of realms, and remove the remaining realms. The resulting content of the file will be as follows:
[libdefaults] default_realm = LOCAL.NETWORK # The following krb5.conf variables are only for MIT Kerberos. krb4_config = /etc/krb.conf krb4_realms = /etc/krb.realms kdc_timesync = 1 ccache_type = 4 forwardable = true proxiable = true # The following encryption type specification will be used by MIT Kerberos # if uncommented. In general, the defaults in the MIT Kerberos code are # correct and overriding these specifications only serves to disable new # encryption types as they are added, creating interoperability problems. # # The only time when you might need to uncomment these lines and change # the enctypes is if you have local software that will break on ticket # caches containing ticket encryption types it doesn't know about (such as # old versions of Oracle). default_tgs_enctypes = rc4-hmac default_tkt_enctypes = rc4-hmac permitted_enctypes = rc4-hmac # The following libdefaults parameters are only for Heimdal Kerberos. v4_instance_resolve = false v4_name_convert = { host = { rcmd = host ftp = ftp } plain = { something = something-else } } fcc-mit-ticketflags = true [realms] LOCAL.NETWORK = { kdc = server.local.network admin_server = server.local.network } [domain_realm] .local.network = LOCAL.NETWORK local.network = LOCAL.NETWORK [login] krb4_convert = true krb4_get_tickets = false
- Modify KDC configuration.
- Edit the /etc/krb5kdc/kdc.conf file as shown below:
[kdcdefaults] kdc_ports = 750,88 [realms] LOCAL.NETWORK = { database_name = /var/lib/krb5kdc/principal admin_keytab = FILE:/etc/krb5.keytab acl_file = /etc/krb5kdc/kadm5.acl key_stash_file = /etc/krb5kdc/stash kdc_ports = 750,88 max_life = 10h 0m 0s max_renewable_life = 7d 0h 0m 0s master_key_type = rc4-hmac supported_enctypes = rc4-hmac:normal default_principal_flags = +preauth } [logging] kdc = FILE:/tmp/kdc.log admin_server = FILE:/tmp/kadmin.log - Create a KDC database.
sudo krb5_newrealm
- Start the KDC and Kerberos servers.
sudo /etc/init.d/krb5-kdc restart sudo /etc/init.d/krb-admin-server restart
- Add principals and create keys.
- Start an interactive
kadminsession and create the necessary principals.sudo kadmin.local
- Add the portal machine and keytab file.
addprinc -randkey HTTP/server.local.network@LOCAL.NETWORK ktadd HTTP/server.local.network@LOCAL.NETWORK
- Add the default portal user accounts and enter a password for each of them.
addprinc john addprinc demo addprinc root
- Issue the following command to test your setup:
kinit -A demo
- If everything is set up well, you are required to enter the password created for the
demouser in the previous step.Without the-Aoption, the Kerberos ticket validation would involve reverse DNS lookups, which can be difficult to debug with certain network DNS configurations. This is a production level security feature and it is not necessary to use it in a development environment. In production environment, it is recommended to avoid using the-Aoption. - After successful login to Kerberos, you can display your Kerberos ticket using the following command:
klist
- To log out and destroy your Kerberos ticket, issue the following command:
kdestroy
15.2. Configuring the SPNEGO Client
After performing the server configuration described in Section 15.1.1, “Configuring the SPNEGO Server”, you need to enable negotiated authentication in web browsers on client machines from which users will authenticate. This procedure describes how negotiated authentication can be enabled in Mozilla Firefox. For instructions on enabling negotiated authentication in a different browser, consult the browser's documentation.
Procedure 15.2. Enabling Negotiated Authentication in Mozilla Firefox
- Start Mozilla Firefox and enter
about:configinto the address field. - Search for the
network.negotiate-authpreferences and set the values as follows:network.negotiate-auth.allow-proxies = true network.negotiate-auth.delegation-uris = .local.network network.negotiate-auth.gsslib (no-value) network.negotiate-auth.trusted-uris = .local.network network.negotiate-auth.using-native-gsslib = true
15.3. Configuring SPNEGO
The portal uses JBoss Negotiation to enable SPNEGO-based desktop single sign-on for the portal. The following procedure describes how to integrate SPNEGO with the portal.
Procedure 15.3. Configuring SPNEGO Integration
- Modify the
# SSOsection of theJPP_HOME/standalone/configuration/gatein/configuration.propertiesfile, replacing the original content with the following properties:# SSO gatein.sso.enabled=true gatein.sso.callback.enabled=false gatein.sso.skip.jsp.redirection=false gatein.sso.login.module.enabled=false gatein.sso.filter.login.sso.url=/@@portal.container.name@@/dologin gatein.sso.filter.logout.enabled=false gatein.sso.filter.initiatelogin.enabled=false gatein.sso.valve.enabled=true gatein.sso.valve.class=org.gatein.sso.spnego.GateInNegotiationAuthenticator
The list below explains the meaning of individual properties:- gatein.sso.enabled
- This is a general property used to inform the portal that clicking the link will redirect users to a URL ending with the
/portal/dologinsuffix. - gatein.sso.callback.enabled
- This property can be set to
falseas REST callbacks are not required for SPNEGO integration. - gatein.sso.skip.jsp.redirection
- This property must be set to
falsefor SPNEGO integration, especially to ensure fallback to FORM authentication. - gatein.sso.login.module.enabled
- This property can be set to
falseas a different set of login modules is needed for SPNEGO integration. - gatein.sso.filter.login.sso.url
- This value ensures that clicking the link will redirect users to the
/portal/dologinURL, which is a secured URL declared in the <security-constraint> section ofJPP_HOME/gatein/gatein.ear/portal.war/WEB-INF/web.xmlfile, allowing theGateInNegotiationAuthenticatorvalve to intercept the HTTP request. - gatein.sso.filter.logout.enabled, gatein.sso.filter.initiatelogin.enabled
- These properties can be set to
falseas the logout filter and theInitiateLoginFilterare not needed for SPNEGO integration. - gatein.sso.valve.enabled
- SPNEGO integration requires a custom Tomcat valve to intercept HTTP requests for secured URLs. The
SSODelegateValveis defined in theJPP_HOME/gatein/gatein.ear/portal.war/WEB-INF/jboss-web.xmlfile and is used only if this option is set totrue. The purpose of the valve is to delegate the real work to another valve declared in thegatein.sso.valve.classproperty. This eliminates the need to edit configuration in thejboss-web.xmlfile. - gatein.sso.valve.class
- The delegate valve for SPNEGO is
org.gatein.sso.spnego.GateInNegotiationAuthenticator. It is used to establish identity of the client by exchanging several handshakes with client browser. The valve is able to obtain and parse an SPNEGO token and resend it to the JAAS layer, where login modules (especially theSPNEGOLoginModule) are able to verify the validity of the wrapped Kerberos token and establish user identity at the portal layer.
- Modify configuration of the
securitysubsystem in theJPP_HOME/standalone/configuration/standalone.xmlfile:- Rename the existing
gatein-domainsecurity domain togatein-form-auth-domain. - Add a new definition of the
gatein-domainsecurity domain. - Add a new security domain called
host. Values of the following properties need to be specified in accordance with your environment setup:- principal
- The HTTP server principal specified in your Kerberos keytab.For example,
LOCAL.NETWORKKerberos realm,server.local.networkhost, and theHTTP/server.local.network@LOCAL.NETWORKprincipal. - keyTab
- The path to the file with your Kerberos keytab.For example the
/etc/krb5.keytablocation. This file must be readable by the user under whose account the portal is executed. Generally, Kerberos keytab files can not be read by normal operating system users because they contain encrypted keys of server principals. Consult Kerberos documentation for more details. - debug
- Enabling this option adds more log messages into the portal console and log file. It is useful to have this option enabled during configuration, but it is advised to disable it in production to avoid unnecessarily large server logs.
The code extract below shows the expected result of the security domain configuration. <security-domain name="gatein-form-auth-domain" cache-type="default"> <authentication> <login-module code="org.gatein.sso.integration.SSODelegateLoginModule" flag="required"> <module-option name="enabled" value="${gatein.sso.login.module.enabled}" /> <module-option name="delegateClassName" value="${gatein.sso.login.module.class}" /> <module-option name="portalContainerName" value="portal" /> <module-option name="realmName" value="gatein-domain" /> <module-option name="password-stacking" value="useFirstPass" /> </login-module> <login-module code="org.exoplatform.services.security.j2ee.JBossAS7LoginModule" flag="required"> <module-option name="portalContainerName" value="portal"/> <module-option name="realmName" value="gatein-domain"/> </login-module> </authentication> </security-domain> <security-domain name="gatein-domain" cache-type="default"> <authentication> <login-module code="org.gatein.sso.spnego.SPNEGOLoginModule" flag="requisite"> <module-option name="password-stacking" value="useFirstPass"/> <module-option name="serverSecurityDomain" value="host"/> <module-option name="removeRealmFromPrincipal" value="true"/> <module-option name="usernamePasswordDomain" value="gatein-form-auth-domain"/> </login-module> <login-module code="org.gatein.sso.agent.login.SPNEGORolesModule" flag="required"> <module-option name="password-stacking" value="useFirstPass"/> <module-option name="portalContainerName" value="portal"/> <module-option name="realmName" value="gatein-domain"/> </login-module> </authentication> </security-domain> <security-domain name="host"> <authentication> <login-module code="com.sun.security.auth.module.Krb5LoginModule" flag="required"> <module-option name="storeKey" value="true" /> <module-option name="useKeyTab" value="true" /> <module-option name="principal" value="HTTP/server.local.network@LOCAL.NETWORK" /> <module-option name="keyTab" value="/etc/krb5.keytab" /> <module-option name="doNotPrompt" value="true" /> <module-option name="debug" value="true" /> </login-module> </authentication> </security-domain>
- While logged in as a user with read permissions for the Kerberos keytab file, start the portal using the following command:
./standalone.sh -Djava.security.krb5.realm=LOCAL.NETWORK -Djava.security.krb5.kdc=server.local.network -b server.local.network
15.4. Testing SPNEGO Configuration
Once you have performed the configuration above, you can follow this procedure to verify that the configured authentication is functional.
Procedure 15.4. Testing the SPNEGO Configuration
- Log in to Kerberos using the following command:
kinit -A demo
- In a browser, access http://server.local.network:8080/portal and click the link in the top menu of the portal. If the authentication is configured correctly, you will be automatically signed in as the
demouser. - Destroy the previously obtained Kerberos ticket using the following command:
kdestroy
- In the browser, log out and log back in. In case of correct configuration, you will be redirected to the login screen of the portal. This happens because you no longer have an active Kerberos ticket and a fall back to the standard FORM authentication occurred.
15.5. Disabling Fallback to FORM Authentication
As demonstrated in Section 15.4, “Testing SPNEGO Configuration”, users trying to sign in without a valid Kerberos ticket are automatically redirected to the portal authentication page. There, they can perform standard FORM authentication using their user name and password.
If you want to disable FORM authentication to allow only users with a valid Kerberos ticket to sign in, you need to comment out the
usernamePasswordDomain option in the SPNEGOLoginModule configuration in the JPP_HOME/standalone/configuration/standalone.xml file.
<login-module code="org.gatein.sso.spnego.SPNEGOLoginModule" flag="requisite"> <module-option name="password-stacking" value="useFirstPass"/> <module-option name="serverSecurityDomain" value="host"/> <module-option name="removeRealmFromPrincipal" value="true"/> <!--<module-option name="usernamePasswordDomain" value="gatein-form-auth-domain"/>--> </login-module>
15.6. Enabling Logging
To enable logging of events related to SPNEGO authentication, you can add the following entries to the
logging subsystem in the JPP_HOME/standalone/configuration/standalone.xml file:
<logger category="org.gatein.sso"> <level name="TRACE"/> </logger> <logger category="org.jboss.security.negotiation"> <level name="TRACE"/> </logger>
Increased logging of Kerberos events to standard output can be enabled by launching the portal with the
-Dsun.security.krb5.debug=true option.
./standalone.sh -Djava.security.krb5.realm=LOCAL.NETWORK -Djava.security.krb5.kdc=server.local.network -b server.local.network -Dsun.security.krb5.debug=true