Chapter 18. Security Assertion Markup Language (SAML2)

About SAML2
SAML (Security Assertion Markup Language) is an Oasis standard for exchanging authentication and authorization data between security domains. SAML 2.0 is an XML-based protocol that uses security tokens containing assertions to pass information about a principal (usually an end user) between an identity provider and a web service. SAML 2.0 enables web-based authentication and authorization scenarios including single sign-on (SSO). General information relating to SAML2 is located in PDF form at http://docs.oasis-open.org/security/saml/v2.0/. In Red Hat JBoss Portal, SAML2 support is provided by the PicketLink Federation. Read the documentation hosted at https://docs.jboss.org/author/display/PLINK/SAML+v2.0 for an excellent overview of what configuration is required for SAML2.
About Identity Provider (IDP)
An Identity Provider is defined by OASIS as a kind of provider that creates, maintains, and manages identity information for principals and provides principal authentication to other service providers within a federation, such as with web browser profiles. A Federation in this definition means an association comprising any number of service providers and identity providers.
About Identity Provider (IDP)
An Identity Provider is defined by OASIS as a kind of provider that creates, maintains, and manages identity information for principals and provides principal authentication to other service providers within a federation, such as with web browser profiles. A Federation in this definition means an association comprising any number of service providers and identity providers.
What is a Service Provider (SP)
A Service Provider is defined by OASIS as a role donned by a system entity, where the system entity provides services to principals or other system entities.
About Assertion
In SAML2, an assertion is a packet of security information. Each assertion contains statements used by service providers to make access-control decisions. The assertion statements provided by SAML2 include: authentication; attribute; and authorization decision statements.

18.1. Authentication in SAML2

The following workflow phases apply when Red Hat JBoss Portal is used as a SAML2 Service Provider (SP).
Work flow diagram explaining how SAML2 authenticates a user request, including how the identity provider interacts with SAML2. The phases in the diagram are described below.

Figure 18.1. SAML2 Authentication Workflow


When a user attempts to authenticate on a SAML2-enabled system, the request is handled by an authenticator that sits atop the Service Provider (SP).
If a user attempts to access a protected resource, for example http://localhost:8080/portal/dologin, the authenticator verifies whether the user has a SAML assertion known to the SP. If the user is authenticated, the authenticator redirects the user to the requested resource.
If the user is not yet authenticated, the following work flow is initiated.
Phase 1
User requests access to a protected resource.
Phase 2
The authenticator verifies whether the user has a SAML assertion known to the SP.
Phase 3
Red Hat JBoss Portal (SP) determines that it does not have a valid SAML assertion for the user.
The SAML request is encapsulated into a HttpRequest and is redirected to the Identity Provider (IDP) using the SAML Redirect Binding (sent as a Base64, URL-encoded, GET request parameter).
Phase 4
The IDP returns a login screen to the user, prompting for valid credentials.
Phase 5
The IDP receives the user credentials through a JAAS login module (SAML2ldpLoginModule). The login module sends a callback request through the REST API, back to Red Hat JBoss Portal to check the user exists in the identity store.
Phase 6
After the user is verified to exist in the identity store by the login module, the IDP authenticator issues a SAML assertion ticket that contains all roles for the user.
Phase 7
The assertion ticket is encapsulated in a HttpRequest, and is redirected back to the Service Provider (SP).
Phase 8
The SP decodes the HttpRequest. The SP login module (SAML2IntegrationLoginModule) parses the authenticated username, and determines whether the assertion is valid according to the known roles the SP has about the user.
The login module then creates an identity object for the user, and registers the user in the IdentityRegistry.
Phase 9
The user is now successfully authenticated, and is redirected back to the secure resource. The secure resource will then redirect the user to Red Hat JBoss Portal as an authenticated user.
If the user needs to authenticate against a different SP application within the same browser session, credentials are not required to re-authenticate because the user is already known to the IDP.
An example of this would include another instance of Red Hat JBoss Portal on a different host, or a completely different web application within the same IDP federation.

18.2. Configuring a Basic SAML2 Instance

18.2.1. SAML2 Configuration Scenario

This basic scenario describes how to configure the necessary configuration.properties file on each virtual host portal instance. The scenario uses a bundled test keystore, which is not suitable for production environments.

18.2.2. Configuring a SAML2 Service Provider

Prerequisites

  • Two available virtual hosts running on the local machine.
  • One instance of the portal deployed to a directory referred to as JPP_SP_DIST.
  • A separate instance of the portal deployed to another directory referred to as JPP_IDP_DIST.

Procedure 18.1. Configure the SAML2 SP

  • Open JPP_SP_DIST/standalone/configuration/gatein/configuration.properties and add the following configuration parameters.
    # SSO
    gatein.sso.enabled=true
    gatein.sso.callback.enabled=${gatein.sso.enabled}
    gatein.sso.login.module.enabled=${gatein.sso.enabled}
    gatein.sso.login.module.class=org.gatein.sso.agent.login.SAML2IntegrationLoginModule
    # Comment #1
    gatein.sso.filter.login.sso.url=/@@portal.container.name@@/dologin
    # Comment #2
    gatein.sso.filter.logout.class=org.gatein.sso.agent.filter.SAML2LogoutFilter
    gatein.sso.filter.initiatelogin.enabled=false
    gatein.sso.valve.enabled=true
    # Comment #3
    gatein.sso.valve.class=org.picketlink.identity.federation.bindings.tomcat.sp.ServiceProviderAuthenticator
    # Comment #4
    gatein.sso.saml.config.file=/WEB-INF/conf/sso/saml/picketlink-sp.xml
    # Comment #5
    gatein.sso.idp.host=www.idp.com
    # Comment #6 
    gatein.sso.idp.url=http://${gatein.sso.idp.host}:8080/portal/dologin
    # Comment #7
    gatein.sso.sp.url=http://www.sp.com:8080/portal/dologin
    # Comment #8 
    # WARNING: This bundled keystore is only for testing purposes. Generate and use your own keystore in production!
    gatein.sso.picketlink.keystore=/sso/saml/jbid_test_keystore.jks
    
    

Comment #1
For integration as SAML2 SP, use the login module class org.gatein.sso.agent.login.SAML2IntegrationLoginModule, which acts as a JAAS delegate from SSODelegateLoginModule.
Comment #2
The specific filter class org.gatein.sso.agent.filter.SAML2LogoutFilter is needed to enable support for SAML2 single logout. SAML2 single logout will take place and will log you out from both portal IDP and SP servers.
  1. A user clicks Sign out.
  2. SAML2LogoutFilter will redirect them to the SAML2 IDP application where they will be logged out.
  3. The IDP application will also manage the logout from all other SP applications.
  4. The user will be redirected to the portal, and logged out.
Comment #3
There is a special valve; org.picketlink.identity.federation.bindings.tomcat.sp.ServiceProviderAuthenticator provided by the Picketlink federation library. This valve manages the creation and parsing of SAMLRequest and SAMLResponse messages and so is vital for a successful SAML2 integration.
Comment #4
This element points to the location of the SAML2 SP configuration file. The path is relative to the portal WAR application. The abolute path to the file is JPP_SP_HOME/gatein/gatein.ear/portal.war/WEB-INF/conf/sso/saml/picketlink-sp.xml. For this simple scenario, there is no need to edit this file. However, in a production environment, you will likely need to generate and use your own keystore and thus you must then configure the use of those keys in this file.
Comment #5
This points to the host serving the SAML2 IDP.
Comment #6
This element points to the URL of the IDP application. This guide assumes that you will use another instance of the portal as the SAML2 IDP, so the request path will be /portal/dologin in this case.
Comment #7
This points to URL of this GateIn Portal, which will be used as SAML2 SP.
Comment #8
This points to the location of the keystore file. It is relative to the classpath of the portal WAR application. The absolute location is JPP_SP_HOME/gatein/gatein.ear/portal.war/WEB-INF/classes/sso/saml/jbid_test_keystore.jks.

18.2.3. Configuring a SAML2 Identity Provider

Prerequisites

  • Two available virtual hosts running on the local machine.
  • One instance of the portal deployed to a directory referred to as referred to as JPP_SP_DIST.
  • A separate instance of the portal deployed to another directory referred to as JPP_IDP_DIST.

Procedure 18.2. Configuring the portal as a SAML2 Identity Provider

  1. Open JPP_IDP_DIST/standalone/configuration/gatein/configuration.properties and add the following configuration parameters.
    # SSO
    # Comment #1
    gatein.sso.enabled=false
    gatein.sso.valve.enabled=true
    # Comment #2
    gatein.sso.valve.class=org.gatein.sso.saml.plugin.valve.PortalIDPWebBrowserSSOValve
    # Comment #3
    gatein.sso.saml.config.file=/WEB-INF/conf/sso/saml/picketlink-idp.xml
    # Comment #4
    gatein.sso.idp.url=http://www.idp.com:8080/portal/dologin
    # Comment #5 
    gatein.sso.idp.listener.enabled=true
    # Comment #6
    gatein.sso.sp.domains=sp.com
    # Comment #7
    gatein.sso.sp.host=www.sp.com
    # Comment #8
    # WARNING: This bundled keystore is only for testing purposes. Generate and use your own keystore in production!
    gatein.sso.picketlink.keystore=/sso/saml/jbid_test_keystore.jks
    
    
    Comment #1
    In this IDP configuration, the gatein.sso.enabled parameter has been disabled.
    This is because the portal IDP does not use any external SSO provider, but will now act as an SSO provider itself (SAML2 Identity Provider) for the portal SP.
    Comment #2
    For IDP we need to use org.gatein.sso.saml.plugin.valve.PortalIDPWebBrowserSSOValve valve, which is able to handle SAML request/response messages from SP applications and react on them.
    Comment #3
    The location of configuration file is relative to the portal WAR. The absolute path is JPP_IDP_HOME/gatein/gatein.ear/portal.war/WEB-INF/conf/sso/saml/picketlink-idp.xml.
    For this simple scenario, there is no need to edit this file. However, in a production environment, you will likely need to generate and use your own keystore and thus you must then configure the use of those keys in this file.
    You will also need to manually add validating aliases in the keystore section if you have multiple SP applications on different hosts.
    Comment #4
    The URL of the portal, which will act as the SAML2 IDP.
    Comment #5
    This will enable a special session listener to clean up records about SAML tickets of expired hosts.
    Comment #6
    Comma-separated list of all SP domains to be trusted by this IDP.
    Comment #7
    Host for the portal SP. To add more SP applications, manually edit the picketlink-idp.xml file and add a ValidatingAlias element for each application.
    Comment #8
    The keystore in JPP_IDP_HOME/gatein/gatein.ear/portal.war/WEB-INF/classes/sso/saml/jbid_test_keystore.jks.
  2. Navigate to JPP_SP_DIST/bin, and start the SP instance by running:
    ./standalone.sh -b www.sp.com
  3. Navigate to JPP_IDP_DIST/bin, and start the IDP instance by running:
    ./standalone.sh -b www.idp.com

18.2.4. Testing the Configuration

Procedure 18.3. 

  1. Navigate to http://www.sp.com:8080/portal/classic and click to Sign in.
  2. From here, SAML request will be sent to www.idp.com and you will be redirected to login screen of the portal IDP instance on http://www.idp.com:8080/portal/dologin.
  3. After a successful login, the SAML response will be sent back to www.sp.com and you will be redirected to the portal on www.sp.com as a logged-in user.
  4. Now you can go to www.idp.com:8080/portal and you will see that you are logged-in as the SSO service has already logged you into this host.
  5. Return to www.sp.com:8080/portal and click Sign Out. SAML2 single log out will trigger, and you will be logged out from both portals on the IDP and SP servers.
  6. You can check that you are logged out from both www.sp.com:8080/portal and www.idp.com:8080/portal

18.3. Disabling SAML2 Single Logout

SAML2 Single logout is very powerful feature of SAML2 protocol, because triggering logout from any SP application will enforce "global" logout also from IDP and all other SP applications. It makes sense that you may not want this feature to be enabled, so logging out from JBoss Product Platform (click to Sign out link) will only logout the user from the JBoss Product Platform on www.sp.com, but user will still be logged in JPP IDP on www.idp.com and in all other SP applications.
Disabling this feature is as easy as switching an option in file GATEIN_SP_HOME/standalone/configuration/gatein/configuration.properties :
gatein.sso.filter.logout.enabled=false
Now when you click Sign out in www.sp.com, you will still be logged in JBoss Product Platform on www.idp.com . There won't be any SAML communication between SP and IDP during logout from www.sp.com.

18.4. Implementing Keystores

For secure and trusted communication, you will need your own keystores with your own keys. The default keystore is useful only for testing purposes, and must not be used in production. Separate keys for the portal SP, and for the IDP are created in this scenario. Follow the instructions to create a keystore for secured and trusted communication between SAML2 components.

Procedure 18.4. Configuring a Keystore for Secure Communication Between SP and IDP

  1. Go to JPP_SP_HOME/gatein/gatein.ear/portal.war/WEB-INF/classes/sso/saml/ directory and run the command:
    keytool -genkey -alias secure-key -keyalg RSA -keystore secure-keystore.jks
    
    You need to choose keystore password and private key password. Other values do not matter. This guide assumes that your keystore password is keystorepass and a private key password is keypass.
  2. For simplification purposes, this guide will use the same keystore for both the SP and IDP servers.
    Copy the keystore file generated in the last step to the IDP server directory; JPP_IDP_HOME/gatein/gatein.ear/portal.war/WEB-INF/classes/sso/saml/.
  3. Configure the new keystore in file JPP_SP_HOME/gatein/gatein.ear/portal.war/WEB-INF/conf/sso/saml/picketlink-sp.xml and replace existing KeyProvider definition with:
    <KeyProvider ClassName="org.picketlink.identity.federation.core.impl.KeyStoreKeyManager">
      <Auth Key="KeyStoreURL" Value="/sso/saml/secure-keystore.jks"/>
      <Auth Key="KeyStorePass" Value="keystorepass"/>
      <Auth Key="SigningKeyPass" Value="keypass"/>
      <Auth Key="SigningKeyAlias" Value="secure-key"/>
      <ValidatingAlias Key="${gatein.sso.idp.host}" Value="secure-key"/>
    </KeyProvider>
    
    
  4. Configure the keystore in JPP_IDP_HOME/gatein/gatein.ear/portal.war/WEB-INF/conf/sso/saml/picketlink-idp.xml similarly:
    <KeyProvider ClassName="org.picketlink.identity.federation.core.impl.KeyStoreKeyManager">
      <Auth Key="KeyStoreURL" Value="/sso/saml/secure-keystore.jks"/>
      <Auth Key="KeyStorePass" Value="keystorepass"/>
      <Auth Key="SigningKeyPass" Value="keypass"/>
      <Auth Key="SigningKeyAlias" Value="secure-key"/>
      <ValidatingAlias Key="${gatein.sso.sp.host}" Value="secure-key"/>
    </KeyProvider>
    
    
  5. Restart both the SP and IDP servers.
    They will now use your new keystore instead of the default jbid_test_keystore.jks.
    While an argument could be made to use certificates signed by certification authority, self-signed certificates are fine for this purpose.

18.5. Setting up PicketLink IDP using REST callback

This basic scenario describes how to configure the necessary configuration.properties file. In the following procedure, the portal is configured as the SP and the PicketLink IDP application as the IDP. Additionally, the PicketLink IDP application will be configured to use REST callback to the portal instance to authenticate users (it will use the portal as an identity store).

Prerequisites

  • One instance of the portal deployed to a directory called JPP_SP_DIST.
  • Another instance of the portal deployed to JPP_IDP_DIST. This server will run on www.idp.com and will host the PicketLink IDP application. Alternatively, if you have access to EAP 6, you can use it instead of the portal, however you will need to copy the PicketLink libraries required by the Picketlink IDP application from the portal SP instance. The libraries are located in JPP_SP_DIST/modules/org/picketlink/gatein

Important

The scenario uses a bundled test keystore, which is not suitable for production environments. For production environments, follow the instructions in Section 18.4, “Implementing Keystores” to provision a production-ready keystore.

Procedure 18.5. Configuring PicketLink IDP using REST callback

  1. Configure the portal as a SP compatible with PicketLink IDP

    Open JPP_SP_DIST/standalone/configuration/gatein/configuration.properties and add the following configuration parameters.
    # SSO
    gatein.sso.enabled=true
    gatein.sso.callback.enabled=${gatein.sso.enabled}
    gatein.sso.login.module.enabled=${gatein.sso.enabled}
    gatein.sso.login.module.class=org.gatein.sso.agent.login.SAML2IntegrationLoginModule
    gatein.sso.filter.login.sso.url=/@@portal.container.name@@/dologin
    gatein.sso.filter.logout.class=org.gatein.sso.agent.filter.SAML2LogoutFilter
    gatein.sso.filter.initiatelogin.enabled=false
    gatein.sso.valve.enabled=true
    gatein.sso.valve.class=org.picketlink.identity.federation.bindings.tomcat.sp.ServiceProviderAuthenticator
    gatein.sso.saml.config.file=/WEB-INF/conf/sso/saml/picketlink-sp.xml
    gatein.sso.idp.host=www.idp.com
    gatein.sso.idp.url=http://${gatein.sso.idp.host}:8080/idp-sig/
    gatein.sso.sp.url=http://www.sp.com:8080/portal/dologin
    # WARNING: This bundled keystore is only for testing purposes. Generate and use your own keystore in production!
    gatein.sso.picketlink.keystore=/sso/saml/jbid_test_keystore.jks
  2. Navigate to JPP_SP_DIST/bin, and start the SP instance by running:
    ./standalone.sh -b www.sp.com
  3. Configure Picketlink Identity Provider

    1. Copy JPP_DIST/gatein-sso/saml/idp-sig.war to IDP_DIST/standalone/deployments/.
    2. Create IDP_DIST/standalone/deployments/idp-sig.war.dodeploy to force the application server to deploy the idp-sig.war. This file is required because the idp-sig.war is in an exploded format, not an archive format.
    3. Create a new security domain in IDP_DIST/standalone/configuration/standalone.xml that contains the following configuration.
      <security-domain name="idp" cache-type="default">
         <authentication>
            <login-module code="org.gatein.sso.saml.plugin.SAML2IdpLoginModule" flag="required">
               <module-option name="rolesProcessing" value="STATIC"/>
               <module-option name="staticRolesList" value="manager,employee,sales"/>
               <module-option name="gateInURL" value="http://www.sp.com:8080/portal"/>
               <module-option name="httpMethod" value="POST"/>
            </login-module>
         </authentication>
      </security-domain>
  4. Start the IDP instance

    1. Navigate to IDP_DIST/bin and execute the following command:
      ./standalone.sh -b www.idp.com -Dsp.host=www.sp.com -Dsp.domains=sp.com -Dpicketlink.keystore=/jbid_test_keystore.jks
    2. Navigate to http://www.sp.com:8080/portal and click Sign in.
      You will be redirected to the idp-sig application on http://www.idp.com:8080/idp-sig/.
      You are able to log in with portal credentials because the REST callback will be sent to the portal instance on www.sp.com and it will manage user authentication.
      After authentication you will be redirected to the portal on www.sp.com and logged-in.

18.6. Additional Information for SAML2

  • Videos - You can follow some videos on the vimeo channel, where you can see SAML2 integration in action. The videos are:
    1. http://vimeo.com/45841256 - Video with basic use cases showing the portal as a SAML2 SP and as a SAML2 IDP.
    2. http://vimeo.com/45895919 - Video showing integration with Salesforce and Google Apps
  • SAML tracer is a useful plug-in to Firefox browser, which allows you to monitor HTTP requests and see wrapped SAML messages in XML format. It could be useful especially for troubleshooting. You can download plug-in here
  • Logging - Like for other SSO solutions, it may be useful to enable trace logging, for example for org.gatein.sso. In case of SAML, it is also good to enable logging for org.picketlink.identity.federation, which is the base package of the PicketLink Federation library. You can add these categories to GATEIN_HOME/standalone/configuration/standalone.xml :

    Example 18.1. Trace Logging Example

    <logger category="org.gatein.sso">
      <level name="TRACE"/>
    </logger>
    <logger category="org.picketlink.federation">
      <level name="TRACE"/>
    </logger>
    <logger category="org.jboss.security">
      <level name="TRACE"/>
    </logger>
    <logger category="org.picketbox">
      <level name="TRACE"/>
    </logger>
    <logger category="org.exoplatform.services.security">
      <level name="TRACE"/>
    </logger>