Red Hat

Single Sign-On Using Security Assertion Markup Language (SAML)

This guide will show you how to create SAML Identity Providers and Service Providers, covering some core concepts so you can understand how to enable Single Sign-On to your applications using SAML.

It will show you how to add the following capabilities to your application:

  • SAML-based Single Sign-On
  • Create/Configure an Identity Provider
  • Create/Configure a Service Provider

We strongly recommend you to understand at least the core concepts of the SAML 2.0 specification.

This guide is based on some example applications provided by our quickstarts. Check the README.md file for each quickstart for more details about how to use them.

System Requirements

Make sure your environment is properly configured as follows:

  • Java 1.6 or Java 1.7
  • PicketLink Federation Quickstarts
  • JBoss Enterprise Application Platform 6 or WildFly Servers.

Check the PicketLink quickstarts repository about how to get, deploy and run them.

SAML Web Browser SSO Overview

Before reading this guide you should understand some basics about how Single Sign-On works when using SAML and PicketLink. The image below shows the required steps prior to stabilishing a SSO session for an unauthenticated user.

  1. User requests access to a resource protected by the Service Provider. Think about a Service Provider as a regular web application.

  2. The Service Provider performs a security check on behalf of the target resource.

  3. If the user is not authenticated, he will be redirected to the Identity Provider for authentication.

  4. The Identity Provider shows the login page to the user. The user provides his credentials and submit the login form.

  5. The Identity Provider queries the configured identity stores (eg.: LDAP or a database) and check if the credentials are valid.

  6. If the credentials are valid, the Identity Provider creates a session for the user and issues a SAML v2.0 assertion.

  7. The Identity Provider redirects the user back to the Service Provider sending the newly created SAML v2.0 Assertion with all security-related information about the user.

  8. The Service Provider checks the assertion to make sure it is valid.

  9. If the assertion is valid, the Service Provider will now authenticate the user locally and redirect the user to the target resource.

The steps above describe the SP-Initiated SSO mode. But PicketLink also supports the IDP-Initiated SSO mode. For more information check this documentation.

Configuring an Identity Provider

The Identity Provider or IdP, is the authoritative entity responsible for authenticating an end user and asserting an identity for that user in a trusted fashion to trusted partners.

It is an online service or web application that centralizes user authentication and issues SAML Assertions. An assertion is a package of information that supplies one or more statement made by the IdP after the user was authenticated based on the information retrieved from an Identity Store (Eg.: LDAP or Database). Once the SAML Assertion is created it can be used by Service Providers (which we'll discuss later) to provide seamless authentication for users.

Let's take an example about how an IdP looks like by looking this quickstart:

In essence, this is a very simple web application. But if you look at WEB-INF/web.xml you'll notice that this application defines some security constraints and also a login configuration.

The security constraints are restricting access to all application's resources and defining which roles are allowed to access them.

<security-constraint>
  <web-resource-collection>
    <web-resource-name>Manager command</web-resource-name>
    <url-pattern>/*</url-pattern>
  </web-resource-collection>
  <auth-constraint>
    <role-name>manager</role-name>
    <role-name>Sales</role-name>
    <role-name>Employee</role-name>
  </auth-constraint>
</security-constraint>

Regarding the login configuration, the application defines FORM as the default authentication method.

<login-config>
  <auth-method>FORM</auth-method>
  <realm-name>PicketLink IDP Application</realm-name>
  <form-login-config>
    <form-login-page>/jsp/login.jsp</form-login-page>
    <form-error-page>/jsp/login-error.jsp</form-error-page>
  </form-login-config>
</login-config>

If you're familiar with JEE Security, you'll find all the configuration above pretty simple. We're just restricting access to the application resources based on some roles and enabling FORM-based authentication. In practice, all the configuration above will make the application redirect the user to a login page if he is not authenticated.

In order to properly authenticate users using LDAP, a Database or whatever, we need to configure a security domain. When using JBoss EAP or Wildfly you just need to add a security-domain configuration to your ${JBOSS_HOME}/standalone/configuration/standalone.xml as follows:

<security-domain name="idp" cache-type="default">
  <authentication>
    <login-module code="UsersRoles" flag="required">
      <module-option name="usersProperties" value="users.properties"/>
      <module-option name="rolesProperties" value="roles.properties"/>
    </login-module>
  </authentication>
</security-domain>

The security domain above is using properties files to authenticate users and load their roles. Both users.properties and roles.properties files are inside the example application at WEB-INF/classes. Usually, you would prefer to authenticate your users against LDAP or Database servers. Both JBoss EAP 6 and WildFly provide different JAAS LoginModules which you can choose accordingly with your needs. You can even write your own implementation.

To make your application use the security domain you need to add a WEB-INF/jboss-web.xml file to your deployment.

<jboss-web>
  <security-domain>idp</security-domain>
</jboss-web>

What we did so far was just enable authentication to the application. But how does the application knows how to process SAML messages ? Or how the application is configured as PicketLink Identity Provider ?

To answer those questions you need to understand the role of the PicketLink Authenticators. The authenticator is a special component provided by PicketLink that knows how to process SAML messages. Its configuration depends on the web container you're using. When using JBoss EAP 6 for example, you configure the authenticator by specifying a valve configuration to the WEB-INF/jboss-web.xml file.

<jboss-web>
  <security-domain>idp</security-domain>

  <valve>
    <class-name>org.picketlink.identity.federation.bindings.tomcat.idp.IDPWebBrowserSSOValve</class-name>
  </valve>
</jboss-web>

When using Undertow, the configuration is a little different. You enable the authenticator by configuring a Servlet Filter in WEB-INF/web.xml.

<filter>
  <filter-name>IDPFilter</filter-name>
  <filter-class>org.picketlink.identity.federation.web.filters.IDPFilter</filter-class>
</filter>

<filter-mapping>
  <filter-name>IDPFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
You may be asking why not use the IDPFilter in both cases. And you can ! But we strongly recommend JBoss EAP 6 users to use the valve. The IDPFilter was recently released and is intended for community users only. There is also an issue in JBoss EAP 6.2 that impacts the usage of IDPFilter. Later versions of EAP 6 should have this fixed.

For last, you need to provide the configuration for the IdP. This is done by adding a WEB-INF/picketlink.xml file to your deployment.

<PicketLink xmlns="urn:picketlink:identity-federation:config:2.1">
  <PicketLinkIDP xmlns="urn:picketlink:identity-federation:config:2.1">
    <IdentityURL>${idp.url::http://localhost:8080/idp/}</IdentityURL>

    <Trust>
      <Domains>localhost,jboss.com,jboss.org,amazonaws.com</Domains>
    </Trust>
  </PicketLinkIDP>

  <Handlers xmlns="urn:picketlink:identity-federation:handler:config:2.1">
    <Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2IssuerTrustHandler" />
    <Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2LogOutHandler" />
    <Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2AuthenticationHandler" />
    <Handler class="org.picketlink.identity.federation.web.handlers.saml2.RolesGenerationHandler" />
    <Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2SignatureGenerationHandler" />
    <Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2SignatureValidationHandler" />
  </Handlers>
</PicketLink>

This file is responsible to provide all the configuration for a given Identity Provider. PicketLink provides a lot of configuration options such as signature support, encryption, CLIENT_CERT/SSL authentication. For more information, please read this documentation.

Configuring a Service Provider

The Service Provider or SP, is also a regular web application that provides specific services (usually related with your business) for your users. It relies on the IdP to receive a valid SAML Assertion with all user information in order to authenticate him locally.

Let's take an example about how an SP looks like by looking this quickstart:

The configuration of a SP is pretty much the same as those used to enable an application as an IdP. You still need to define a security-constraint.

<security-constraint>
  <web-resource-collection>
    <web-resource-name>Manager command</web-resource-name>
    <url-pattern>/*</url-pattern>
  </web-resource-collection>

  <auth-constraint>
    <role-name>Manager</role-name>
  </auth-constraint>
</security-constraint>

The security constraint above is protecting all resources with role Manager. The role will be retrieved by the Service Provider by looking the statements defined in the SAML Assertion.

As mentioned before, the Service Provider receives a SAML Assertion from the IdP. We need somehow get all user information from the assertion to authenticate the user locally. PicketLink provides a specific JAAS LoginModule that knows how to process SAML Assertions and authenticate users based on that information.

<security-domain name="sp" cache-type="default">
  <authentication>
    <login-module code="org.picketlink.identity.federation.bindings.jboss.auth.SAML2LoginModule" flag="required"/>
  </authentication>
</security-domain>

When using JBoss EAP or Wildfly you just need to add a security-domain like above to your ${JBOSS_HOME}/standalone/configuration/standalone.xml. And of course, reference it from your application using the WEB-INF/jboss-web.xml file:

<jboss-web>
  <security-domain>sp</security-domain>
</jboss-web>

Service Providers also require the configuration for a specific PicketLink Authenticator in order to enable SAML processing. When using JBoss EAP 6 for example, you configure the authenticator by specifying a valve configuration to the WEB-INF/jboss-web.xml file.

<jboss-web>
  <security-domain>sp</security-domain>

  <valve>
    <class-name>org.picketlink.identity.federation.bindings.tomcat.sp.ServiceProviderAuthenticator</class-name>
  </valve>
</jboss-web>

When using Undertow, the configuration is a little different. You enable the authenticator by configuring an Undertow Servlet Extension to your deployment by adding a file /WEB-INF/classes/META-INF/services/io.undertow.servlet.ServletExtension to your deployment.

org.picketlink.identity.federation.bindings.wildfly.sp.SPServletExtension

For last, you need to provide the configuration for the SP. This is done by adding a WEB-INF/picketlink.xml file to your deployment.

<PicketLink xmlns="urn:picketlink:identity-federation:config:2.1">
  <PicketLinkSP xmlns="urn:picketlink:identity-federation:config:2.1" BindingType="POST">
    <IdentityURL>${idp.url::http://localhost:8080/idp/}</IdentityURL>

    <ServiceURL>${sales-post.url::http://localhost:8080/sales-post/}</ServiceURL>
  </PicketLinkSP>

  <Handlers xmlns="urn:picketlink:identity-federation:handler:config:2.1">
    <Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2LogOutHandler" />
    <Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2AuthenticationHandler" />
    <Handler class="org.picketlink.identity.federation.web.handlers.saml2.RolesGenerationHandler" />
  </Handlers>
</PicketLink>

This file is responsible to provide all the configuration for a given Service Provider. PicketLink provides a lot of configuration options such as signature support and encryption. For more information, please read this documentation.

Configuring PicketLink Dependencies to JBoss EAP 6 and WildFly Deployments

Before deploying your Identity Provider or Service Provider application to JBoss EAP 6 or WildFly, you need to configure the PicketLink dependency in META-INF/jboss-deployment-structure.xml. Add this file to your deployment with the following content:

  <jboss-deployment-structure>
    <deployment>
      <dependencies>
        <module name="org.picketlink"/>
      </dependencies>
    </deployment>
  </jboss-deployment-structure>

PicketLink is part of JBoss EAP 6 and WildFly via JBoss Modules. The module is located at ${JBOSS_HOME}/modules/system/layers/base/org/picketlink.

Note About the PicketLink Federation Quickstarts

The best way to get started with PicketLink SAML Support is playing with the quickstarts. There are a plenty of them, each one covering a specific SAML aspect and usage.

The PicketLink Federation quickstarts start with picketlink-federation-* prefix. You'll find a lot of information along the README.md files for each quickstart about how to deploy and run them.

You may also notice that each quickstart has its own conf directory. Usually, this directory contains only the special bits of configuration that you need to consider when enabling SAML to your applications. Currently, we're providing configurations for both JBoss Enterprise Application Platform 6 and WildFly.

All those quickstarts are ready to be deployed ! Give them a try !

Summary

Hopefully this guide helped you to understand some core concepts of PicketLink SAML Support like Identity Providers, Service Providers, how Sign Sign-On works as well how to configure any application to play one of this roles.

We covered some important and basic concepts that will help you to deep dive into some more advanced concepts of PicketLink and create more advanced and complex usecases.

Most of the things we covered in this guide are also demonstrated by the quickstarts, from where you can get much more usage examples considering different usecases.

Fell free to contribute with your own guides and help us to improve PicketLink ! Enjoy it !

back to top