Contents


Understanding the SAML trust association interceptor for the WebSphere Application Server

Comments

IBM® WebSphere® Application Server — and the stack products that are running on top of this platform — has had a customizable authentication framework since V5.1. This framework is based on the trust association interceptor (TAI) interface, which has multiple product implementations. In 2012, the WebSphere Application Server full profile edition included a new Security Assertion Markup Language (SAML) TAI. This interface is available on WebSphere Application Server Versions 7.0, 8.0 and 8.5. (At the time of this writing, the IBM WebSphere Application Server Liberty profile does not have SAML support.) The SAML TAI is by far the most comprehensive TAI that is available to date.

In this article, you learn how you can use the SAML TAI and when it is appropriate to use the SAML TAI. You also learn how the various SAML TAI properties work together. Plus, you see the intricate path that the SAML TAI weaves through the WebSphere Application Server authorization process.

Before you read this article, you must have a firm understanding of the WebSphere Application Server authentication process (as described in the article Advanced authentication in WebSphere Application Server). You must also understand the following concepts:

  • Digital signing
  • Encryption
  • Identity assertion
  • TAIs in general

The basics: The web single sign-on use case

The SAML TAI introduces support for a new form of web single sign-on (SSO). As we say in our WebSphere Application Server security class, the term SSO is considerably overused in the industry, so we must be precise in our SSO use case.

SAML has evolved over the years. The SAML 2.0 specifications define several profiles and bindings:

  • SAML profiles describe different message exchange sequences between the parties that are involved in the SSO interaction.
  • SAML bindings describe how a particular message is bound to a certain protocol. At any step in a profile's message exchange sequence, the profile can reference one or more bindings as choices for how the messages are to be relayed.

The SAML profiles include:

  • SSO profiles
    • Web Browser SSO Profile
    • Enhanced Client or Proxy Profile
    • Identity Provider Discovery Profile
    • Single Logout Profile
    • Name Identity Management Profile
  • Artifact Resolution Profile
  • Assertion Query/Request Profile
  • Name Identifier Mapping Profile
  • SAML Attribute Profiles

The SAML bindings include:

  • SAML SOAP Binding
  • Reverse SOAP Binding
  • HTTP Redirect Binding
  • HTTP Post Binding
  • HTTP Artifact Binding
  • SAML URI Binding

WebSphere Application Server has supported the SAML SOAP Binding for the SOAP-based web services since fix pack 7.0.0.7. The SAML TAI was introduced in fix packs 7.0.0.23, 8.0.0.5, and in the base product in version 8.5.0.0. The SAML TAI supports only the combination of the Web Browser SSO Profile and the HTTP Post Binding.

As you can see, this use case is just one of many possible use cases. In fact, there are two variants. But first, you need to understand some of the actors that are involved:

  • Identity Provider (IdP)
  • Service Provider (SP), which is also known as the Relying Party (RP)

The job of the IdP is to authenticate the user (how the IdP does is not relevant) and to produce some assertions or claims about the user. These assertions are digitally signed by the IdP. The SAML specification defines the format of these assertions. The SP receives the assertions. If the SP is satisfied that the assertions came from a trusted IdP, it logs in the user based on some parts of the assertion.

Consider an example based on a real-world use case. The fictitious Unified Assurance Company (UAC) has several fictitious corporate customers, including: the Gamma Business Machine (GBM) company, the Omicron Lumber Company, and the Purple Maple Syrup Company. These four companies are in an SSO Federation. In this example, employees of these three federation members are known at the Unified Assurance Company. That is, user entries exist in the Unified Assurance Company LDAP for the external federations' employees, but no passwords for the federation members.

In this case, Unified Assurance Company wants to make an IBM WebSphere Portal system available to its external and internal users. Users from Gamma Business Machine authenticate to a system within Gamma Business Machine. Omicron Lumber users authenticate to a system in the Omicron Lumber network. And, Purple Maple Syrup users authenticate to a system that is hosted by Google. (The use of a WebSphere Portal system in this example is incidental.)

Figure 1 illustrates the details of how users who log in to their IdPs are not relevant to United Assurance. For example, Gamma Business Machine users can log in by using a login form. Omicron Lumber users automatically provide their credentials to their IdP by using SPNEGO authentication. And, Purple Syrup users authenticate to their IdP by using an SSL client certificate.

Also, notice the set of colored private/public key pairs. Each IdP has its own private key. The SP keeps a copy of all the corresponding public certificates that correspond to these private keys in its IdPTruststore.

Figure 1. SSO federation example
SSO                     federation example
SSO federation example

The Web Browser SSO Profile describes how SAML assertions can be routed through the users' browsers by using HTTP redirection. The HTTP Post Binding for the Web Browser SSO can have one of two use cases:

  • The browser request goes first to IdP.
  • The browser request goes first to the SP.

Let's call IdP use case the IdP initiated Web SSO (Figure 2).

Figure 2. IdP initiated Web SSO
IdP                     initiated Web SSO
IdP initiated Web SSO

In the IdP initiated Web SSO use case:

  1. The user starts the process by following a link to a URL at the IdP. As explained previously, the user authenticates to the IdP.
  2. Based on configuration in the IdP and the original URL provided to the IdP, a SAML response is created and sent by an HTTP Post redirect to an assertion consumer service in the SP. This SAML response is signed by the IdP.
  3. The SAML TAI consumes the SAML response and logs in the user. In this example, the user identity exists in the Unified Assurance Company LDAP. However, this is not a requirement for SAML Web SSO. A JAAS subject is created in memory, and various WebSphere Application Server security tokens are created, including an SSOToken, which is also known as the LtpaToken2. From this SSOToken, an LtpaToken2 cookie is created.
  4. After the user logs in, the request is dispatched to the assertion consumer service. It is an application for which the sole purpose is to redirect the user to the correct landing page after the user is logged in by the SAML TAI. The assertion consumer service has a Java™ EE security constraint that is defined to cause the WebSphere Application Server container security and the SAML TAI to be called. An assertion consumer service application is shipped as part of the support for the SAML TAI.
  5. The assertion consumer service redirects the user to the landing page for the application (possibly based on something in request or on configuration). In this example, this URL is:
    https://benefits-portal.uac.com/wps/myportal This HTTP redirection includes the new LtpaToken2 cookie. The browser follows the redirection and resends the LtpaToken2.
  6. The SAML TAI is called again, this time to check whether a SAML response is in the request. Although there is not, there is an LtpaToken2 cookie. Therefore, the standard Web Inbound login configuration processing occurs (described later).

A limitation of this approach is that the user must start a GET link to a URL hosted by the IdP. Consider the example where users at each of the client companies need to know their respective URL to log in to the Unified Assurance Company Portal. When each group logs in, they all log in to:
https://benefits-portal.uac.com/wps/myportal

Another limitation of this approach is that a single IdP can be used to authenticate users for multiple service providers. The Gamma Business Machine users might also use that same SSO IdP to log in to car rental systems with which their company has relationships. Yet the URLs for the Unified Assurance Company portal and the car rental systems are (to the user's point of view) hosted on the same Gamma Business Machine IdP (GBM IdP) server, which can be confusing to users.

To address these limitations, the service provider typically develops brand recognition, regardless of which federation partner the user is from. Each user clicks a link that contains the following URL:
https://benefits-portal.uac.com

The users target their browser to the service provider first, and the service provider starts the SSO process. The WebSphere Application Server SAML TAI supports this second use case. The SAML TAI is configured to redirect the users to the IdP. This use case is called the SP Redirect to IdP Web SSO use case (Figure 3).

Figure 3. SP Redirect to IdP Web SSO
SP                     Redirect to IdP Web SSO
SP Redirect to IdP Web SSO

In the SP redirect to IdP Web SSO use case:

  1. The user follows a link to the application's URL at the SP, which is the following link in this example: https://benefits-portal.uac.com/wps/myportal
  2. The SAML TAI is called twice. Because this URL is not the assertion consumer service, the TAI does not initially intercept the request. The Web Inbound configuration looks for an LtpaToken2 cookie. None is found. The SAML TAI is called a second time. Based on some data in the incoming request and the TAI configuration, the TAI returns an HTTP 302 redirect to the correct IdP. (Ways to determine which is the correct IdP for any particular request is explained later in this article.) A cookie is set by the TAI to the value of the original referrer URL, which in this example is:
    https://benefits-portal.uac.com/wps/myportal

As discussed previously, the user authenticates to the IdP.

Steps 3 through 7 are the same as steps 2 through 6 in the IdP initiated Web SSO use case.

Section 4.1.2 of the OASIS Standard shows the basic template for SSO that uses the web POST binding. Steps 1 through 4 are optional. The steps that start at step 5 in the template is what we call the IdP initiated Web SSO use case. WebSphere Application Server allows for a flow that starts at the service provider (WebSphere Application Server), without implementing the SP-initiated SSO standard flow that is defined in steps 1 through 4.

To support these standard SP-initiated SSO steps, our TAI would need to generate a SAMLRequest and then redirect the user to the IdP. The IdP would then send back a SAMLResponse, which is considered a solicited response. Before fix pack 8.0.0.12/8.5.5.6, the WebSphere Application Server SAML TAI did not support the standard SP-initiated flow. Instead, the SAML TAI did not solicit a response. It redirected the user to the IdP's login page. After the user logged in, the IdP generated a SAMLResponse. Because this SAMLResponse is not a reply based on a SAMLRequest, it is considered unsolicited. This unsolicited use case is referred to as the SP redirect to IdP Web SSO use case.

Fixpacks 8.0.0.12 and 8.5.5.7 now support SP-initiated flows by using the AuthnRequestProvider SPI. To make this work, you must write code that implements this SPI. An implementation of this SPI must populate a HashMap with four strings. Keep in mind the following tips:

  • Write the generation of a Coordinated Universal Time time that is used for issueInstance, and then ensure that the string that is created is properly formatted.
  • The generation of the request identifier is not explained. Ensure that a sufficiently random string is generated as a URL.
  • The AuthnRequest string is not shown as Base64 encoded. (The SPI programmer must perform this Base64 encoding, although the example does not reinforce doing this.)
  • The SPI defines two methods. You must implement the first method in the solution, but it is not referenced in the documentation:
    	public String getIdentityProviderOrErrorURL(HttpServletRequest arg0,
    				String arg1, String arg2, ArrayList<String> arg3)
    				throws NotImplementedException;

    This method is defined or required, but it is never called.

  • The entire issue of how to sign the AuthnRequest is omitted. If your IdP requires the AuthnRequest to be signed, your code must determine how to perform that signature before the Base64 encoding.

When you implement such a solution (the details are beyond the scope of this paper), signing the AuthnRequest is peformed by using javax.xml.crypto.dsig.* classes and the Base64 encoding by using:

	// Base64 encode the signed message
	byte[] bytes = signedAuthnMessage.getBytes();
	String encodedAuthnMessage = new String(com.ibm.ws.security.util.Base64Coder.base64Encode(bytes));

For the custom SPI implementation to be called, the SAML TAI must:

  • Refer to the full classname within the custom property sso_<n>.sp.login.error.page of the SAML TAI.
  • Place the JAR file that contains this implementation in the <WAS>/lib/ext directory.

This behavior is documented in the SAML single sign-on scenarios, features, and limitations topic for WebSphere Application Server in the IBM Knowledge Center.

The WebSphere Application Server SAML TAI

To make SAML web SSO functions available in WebSphere Application Server V8.5 (and in versions 7.0 and 8.0), the functions were implemented in a trust association interceptor. The full class name of the SAML TAI is com.ibm.ws.security.web.saml.ACSTrustAssociationInterceptor. These important points affect the SAML web SSO TAI:

  • Administrative security must be enabled.
  • The SAML TAI can be defined at the global or other security domain.
  • Application security must be enabled in the domain in which the SAML TAI is configured. Also, TAIs must be enabled, and the SAML TAI must be configured.
  • When the user logs in to WebSphere Application Server, the SAML TAI saves a copy of the SAML assertions from the POST request in the private credentials of the user's Subject (for outbound web service calls, for example).

Subject Attribute Propagation must be enabled in order for this custom (not found in the User Registry) information to propagate from server to server in the cell. Because these SAML assertions are not obtainable from the WebSphere Application Server registry, an appropriate custom cache key is defined for the Subject. (The subtle implications of Subject propagation, custom cache keys, and TAIs are beyond the scope of this paper.)

  • The SAML TAI supports multiple applications. Each application can have its own assertion consumer service URL.
  • Each application can interact with multiple IdPs. Each IdP can be configured differently.
  • The SAML TAI supports only the Web SSO Profile and the HTTP Post Binding.

Important: Only a single HTTP POST message flows from the IdP to the WebSphere Application Server SAML TAI that contains the SAML Response object within the POST body. The WebSphere Application Server SAML TAI logs the user in based on that SAML Response object, and returns an LtpaToken2 cookie. The profile and binding are suitable for arriving at an application's authenticated landing page. Subsequent interactions from the browser maintain the user's login context based on the LtpaToken2 cookie that is returned by the HTTP client, which is typically the user's browser.

Although the SAML assertions in that POST allow for a somewhat "portable" token, that portable token is immediately replaced by a WebSphere-specific LtpaToken2 cookie. This model fits well with users that use browsers. It does not fit well with other HTTP application clients that do not have a model of "login to a landing page and maintain login state by using a cookie." For example, a RESTful web service application that expects to use the full array of HTTP methods -- GET, PUT, POST, and DELETE -- must be designed to:

  1. Determine whether the application has an LtpaToken2 cookie.
  2. If none exists, get a SAML response and follow the redirected POST to the assertion consumer service so that the client application can get an LtpaToken2 cookie.
  3. Only after the first two steps are successful, perform the real web service operation that the application was trying to start in the first place.

Because of the custom cache key in the Subject and in the LtpaToken2, Subject attribute propagation must be enabled to allow the full user identity to propagate between JVMs in the WebSphere SSO cell. This method can include JMX call backs to the original server where the user logged in.

SAML TAI and the web inbound login configuration

The logic flow is refined in the Figure 4 to support the SAML TAI. It accommodates the case where the user has an LtpaToken2 cookie, and the browser POSTs to the assertion consumer service with a new SAML assertion. In this case, the original LtpaToken2 cookie must be ignored, and the user identity from the SAML assertion must be used when creating the new Subject. This change in behavior is controlled by the general custom property com.ibm.websphere.security.InvokeTAIbeforeSSO, which is given the value of the SAML TAI class (com.ibm.ws.security.web.saml.ACSTrustAssociationInterceptor):

  • If the SAML TAI is defined at the Global level, add this custom property on the Global Security page.
  • If the SAML TAI is defined within a Security domain, add this custom property on the Custom Properties of the Security domain.

Figure 4 shows the first part of the new logic flow.

Figure 4. The SAML TAI processes SAML Tokens before LtpaToken2
The SAML TAI processes SAML Tokens before LtpaToken2
The SAML TAI processes SAML Tokens before LtpaToken2

With the InvokeTAIbeforeSSO property that is properly defined, the SAML TAI is called before the SSO Token (the LtpaToken2 cookie) is examined. The checkSubject? steps in Figure 4 are explained later in this article.

To support the SP redirect to IdP Web SSO use case, the SAML TAI can potentially be called several times. That is, if no LtpaToken2 nor SAML assertion exists, the SAML TAI logic can be called when a second special security property, com.ibm.websphere.security.DeferTAItoSSO, is given the value of the SAML TAI class. This property is also defined as a custom property on the Global security page or on the custom properties of the Security domain in which the SAML TAI is enabled.

When the SP redirect to IdP Web SSO use case is examined, you can see scenarios where the SAML TAI can be called multiple times on the initial login. Figure 5 illustrates the SAML TAI support process for the SP redirect to IdP Web SSOuse case.

Figure 5. SAML TAI support for the SP redirect to IdP Web SSO use case
SAML TAI support for the SP redirect to IdP Web SSO use                     case
SAML TAI support for the SP redirect to IdP Web SSO use case

With the trace specification set to com.ibm.ws.security.web.saml.*=all, examination of the trace confirms the logic in these two flowcharts during an SP redirect to IdP Web SSO use case.

To help with this experiment, this example has two TAIs. The first one is a FakeTAI that does not intercept, but does emit a message in the log, as shown in the following code listing.

[3/20/13 16:22:49:635 EDT] 00000024 TrustAssociat A   SECJ0121I: Trust Association Init
class com.ibm.issw.security.FakeTAI loaded successfully
[3/20/13 16:22:49:640 EDT] 00000024 TrustAssociat A   SECJ0122I: Trust Association Init
Interceptor signature: 1.2
[3/20/13 16:22:49:642 EDT] 00000024 TrustAssociat A   SECJ0121I: Trust Association Init
class com.ibm.ws.security.web.saml.ACSTrustAssociationInterceptor loaded successfully
[3/20/13 16:22:49:644 EDT] 00000024 ACSTrustAssoc >  initialize Entry
…
[3/20/13 16:22:49:670 EDT] 00000024 ACSTrustAssoc <  initialize Exit
[3/20/13 16:22:49:670 EDT] 00000024 TrustAssociat A   SECJ0122I: Trust Association Init
Interceptor signature: <null>

The second one is the SAML TAI, which is called before SSO processing, as shown in the following code listing.

[3/20/13 16:22:49:673 EDT] 00000024 ACSTrustAssoc >  isFirstPass Entry
…
[3/20/13 16:22:49:674 EDT] 00000024 ACSTrustAssoc 3   Request does not contain
SAMLResponse, TAI will be skipped and deferred.
[3/20/13 16:22:49:675 EDT] 00000024 ACSTrustAssoc 3   Request is scoped to this TAI.

Next, is the SSO processing. First, the Fake TAI is called. It does not intercept. Then, the SAML TAI is called as shown in the following code listing.

[3/20/13 16:22:49:679 EDT] 00000024 SystemOut     O   FakeTAI.isTargetInterceptor()
returns 'false'
[3/20/13 16:22:49:680 EDT] 00000024 ACSTrustAssoc >  isFirstPass Entry	
…
[3/20/13 16:22:49:697 EDT] 00000024 SAMLTaiState  3   SAML TAI challenge login: Referer
URL cookie set https://oc5067386220.ibm.com:9444/HitCountWeb/HitCountServlet
[3/20/13 16:22:49:697 EDT] 00000024 ACSTrustAssoc <  createTAIErrorResult Exit
[3/20/13 16:22:49:697 EDT] 00000024 ACSTrustAssoc <  invokeTAIafterSSO Exit
[3/20/13 16:22:49:698 EDT] 00000024 ACSTrustAssoc <  negotiateValidateandEstablishTrust
Exit

The trace now processes message 3 from Figure 2 as shown in the following code listing.

[3/20/13 16:22:56:207 EDT] 00000026 ACSTrustAssoc >  isFirstPass Entry
…
[3/20/13 16:22:56:212 EDT] 00000026 ACSTrustAssoc 3   Request contains SAMLResponse,
TAI will be processed.
…
[3/20/13 16:22:56:484 EDT] 00000026 ACSTrustAssoc <  negotiateValidateandEstablishTrust
Exit

The user is logged in. An LtpaToken2 cookie is sent to the browser. Because the built-in assertion consumer service application is used, the assertion consumer service redirects the browser to the original referrer URL cookie value, which is:
https://oc5067386220.ibm.com:9444/HitCountWeb/HitCountServlet

The original referrer URL cookie is set by using the SAML TAI.

Message 6 from Figure 2 occurs and arrives next in the trace. Again, the SAML TAI is called before the LtpaToken2 cookie is examined as shown in the following code listing.

[3/20/13 16:22:56:774 EDT] 00000026 ServerCache   I   DYNA1071I: The cache provider
"default" is being used.
[3/20/13 16:22:57:627 EDT] 00000025 ACSTrustAssoc >  isFirstPass Entry
…
[3/20/13 16:22:57:627 EDT] 00000025 ACSTrustAssoc 3   Request does not contain
SAMLResponse, TAI will be skipped and deferred.
…
[3/20/13 16:22:57:628 EDT] 00000025 ACSTrustAssoc 3   Request is scoped to this TAI.

Notice that the LtpaToken2 cookie is found, and neither the Fake TAI nor the SAML TAI is called again. The HitCount application is called and reports the identity of the caller. The identity was obtained from the Subject, which was generated from the SAML Response in message 3, as shown in the following code listing.

[3/20/13 16:22:57:632 EDT] 00000025 SystemOut     O   J2EE APIs: HitCount received
request from Alice

SAML TAI properties

The implementation as a TAI enables back-porting of function into earlier versions of WebSphere Application Server. However, it does result in several TAI properties that must be defined properly for the TAI to proceed.

The SAML TAI properties are grouped into three categories as explained in SAML web SSO TAI custom properties. In addition to these details in the IBM Knowledge Center topic, keep in mind these points:

  • Global properties are applicable to all SSO partners (those partners that host IdPs) that are configured for the SAML TAI. These properties are not prefixed with sso_<id> (where <id> is an integer). Most of the Global properties can be overridden by the IdP specific equivalents.
  • Service provider properties are applicable to a service provider. They are grouped for each SSO service provider partner under a unique sso_<id>.
  • IdP properties are applicable to identity providers that are configured for the SAML TAI. To assign unique property names that identify each identity provider partner, an idp_<id> is embedded in the property name. It is then used to group the properties that are associated with each SSO IdP partner. For a particular service provider, the configured IdP properties are prefixed with sso_<id>.idp_<id^>.

Instead of explaining all of the properties, we group them together to show how they apply to solve certain problems. (Not all properties are explained here.)

IdP initiated SSO properties that are needed to complete SSO

After authentication to the IdP, the IdP redirects the browser to the appropriate assertion consumer service URL. The SAML TAI determines which (if any) service provider configuration to apply to the request.

To determine which configuration to apply, the SAML TAI matches the URL with the pattern that is defined in all sso_<n>. sp.acsUrl properties. If it finds a match, it applies all sso_<n> (service provider) properties, plus any global properties.

During processing of the SAMLResponse to the assertion consumer service application, the SAML TAI enforces matching of the AudienceRestriction element in the SAMLResponse to the sso_<n>.sp.EntityID property. If it is not set, this EntityID property takes its value from the sso_<n>.sp.acsURL property.

If the user POSTs to the assertion consumer service URL with an invalid SAML Response (perhaps issued by another IdP), the URL that is specified by the sso_<n>.acsErrorPage property is returned by a redirect.

Next, we consider the additional properties for the SP redirect to IdP Web SSO use case.

SP redirect to IdP Web SSO properties that are needed to complete SSO

Consider the case that is shown in Figure 3. A Gamma Business Machine user opens a browser to the following URL: https://benefits-portal.uac.com/wps/myportal

As described previously, the TAI does not immediately intercept because the URL is not an assertion consumer service URL. Because this request is the first one, there is no LtpaToken2 cookie. As mentioned earlier, based on some data in the incoming request, the SAML TAI returns an HTTP 302 redirect to the correct IdP. How can the SAML TAI know to redirect this request to (in this example) the GBM IdP and not one of the other IdPs?

The SAML TAI filter property, sso_<n>.sp.filter, controls how the SAML TAI determines whether a particular URL must initiate a service provider redirection to the IdP. The filter functions the same as the filter for the SPNEGO TAI. In the absence of a filter setting, all requests to Java EE protected URLs are intercepted.

You must apply the fix in APAR PM84513. This APAR addresses an issue with multiple SP configurations, each with a unique "filter" definition. The first request to the SAML TAI finds the "filter" that matches to determine which SP configuration to apply for that first request. Without this APAR, all subsequent calls to the SAML TAI continue to use the same SP configuration. Subsequent requests do not check for a matching filter condition.

If the request is intercepted based on the filter, the page that is specified by the sso_<n>.sp.login.error.page property is returned. If only a single IdP exists, this can be a URL that is usable by that single IdP. If multiple IdPs exist, each IdP for the SP configuration will have its own sso_<n>.idp_<m>.SingleSignOnUrl value. To initiate the SAML SSO, each value specifies the URL that the SAML TAI will redirect to.

Yet the problem remains: how do you determine which idp_<m> to choose? If multiple IdPs exist, the login.error.page property can point to an HTML page with multiple IdP links. A more refined solution is where the property refers to a class that implements the interface as shown in the following code listing.

import javax.servlet.http.HttpServletRequest;
import java.util.String ;
import java.util.ArrayList ;
import com.ibm.websphere.security.NotImplementedException;
import com.ibm.wsspi.security.web.saml.IdentityProviderMapping;
	
public abstract interface IdentityProviderMapping {
   public abstract String getIdentityProviderOrErrorURL(
      HttpServletRequest req,
      String errMsg,
      String acs,
      ArrayList<String> ssoUrls) throws NotImplementedException;
}

Implement this class, and place the JAR file into the <WAS>/lib/ext directory. You can perform any logic that you can imagine in your implementation. In the SampleIDPMapping.java sample source code (see the following listing), you search for either a ?idp=<URL> parameter or (if the user visited the site before) a persistent cookie called SAMLIDP.

private static final String COOKIE = "SAMLIDP";
…
// Assumes that
//   idp_1 is configured as GBM IdP
//   idp_2 is configured as Omicron Lumber IdP
//   idp_3 is configured as Purple Maple Syrup IdP
…
// Prefer URL parameter over cookies. So only look for cookies
// if URL parameter not set.
String idpValue = req.getParameter("idp");
if (idpValue==null) {
   log.finer("URL Parameter was not found, so looking for IDP cookie");
   Cookie[] cookies = req.getCookies();
   if (cookies != null) {
      for (Cookie cookie : cookies) {
         if (cookie.getName().equals(COOKIE)) {
           String cookieValue = cookie.getValue();
…
         }
      }
   }
}
…
if (idpValue.equalsIgnoreCase("omicron")) {
   // We know that ssoUrls.size() < 1 here
   log.finer("Omicron IDP requested. Returning (ssoUrls.get(1))");
   idpUrl = ssoUrls.get(1);
} else if (idpValue.equalsIgnoreCase("purple")) {
   // We know that ssoUrls.size() < 1 here
   log.finer("Purple IDP requested. Returning (ssoUrls.get(2))");
   idpUrl = ssoUrls.get(2);
} else {
   // otherwise return ssoURL[0] - default "gbm"
   log.fine("IDP requested " + idpValue +
            ". Default to gbm IDP (ssoUrls.get(0))");
   idpUrl = ssoUrls.get(0);
}

In this example, if neither a cookie nor an idp= parameter is provided, the default is the GBM IdP. Another realistic example is to determine which IdP to use, based on the client IP address (which in some situations might be meaningful data) of the incoming HttpServletRequest. We do not provide code for this second example.

How the SAML TAI knows where to redirect to after the WebSphere Application Server login

Now, the SAML TAI has processed the SAML Response when it is POSTed to the assertion consumer service, and the WebSphere Application Server security runtime logs in the user and generates a JAAS Subject. The assertion consumer service application completes one of the following actions:

  • HTTP 302 redirects the browser to the logged-in landing page.
  • Performs an internal forward to an address in the application. To use this option, the assertion consumer service URL must be part of the same web application as the forwarded-to URL. The generic assertion consumer service application is unable to perform a forward operation.
  • The SAML Response sent by the IdP can optionally include the URL that the SP should redirect to by using a SAML attribute called the RelayState.

To support the first of these options, the generic assertion consumer service application uses the sso_<n>.sp.targetUrl property. If the IdP sends RelayState, the third option is used by default. To override the RelayState sent, you can use the sso_<n>.sp.useRelayStateForTarget property. The most common SP-initiated way to specify where to redirect is through the original referrer URL cookie, called the WasSamlSpReqURL cookie.

Why SAML TAI believes the SAML assertions

You might be asking why SAML TAI believes the SAML assertions. If it doesn't, an attacker might craft a properly formed SAML Response, POST to the assertion consumer service, and become logged in as anyone the attacker chooses. The SAML TAI must confirm that the request came from a trusted IdP. That is, the SAML TAI must authenticate the IdP, which is performed by confirming the digital signature of the SAML Response.

The SAML Response includes a digital signature of the data. The signature includes a hash of the data by using the advertised algorithm in the SAML Response. The output of this hash is then encrypted with the private key held by the IdP. To validate that signature, the SP (the SAML TAI) calculates the hash of the same content and then decrypts the IdP supplied hash value (the SAML Response includes the public certificate). If they match, the SP knows that the content is not changed (known as data integrity), and that the content was generated by the holder of that private key corresponding to the public certificate. The issuer of that public certificate must be trusted.

The following properties control the signature confirmation behavior of the SAML TAI:

  • sso_<n>.sp.wantAssertionsSigned
  • sso_<n>.sp.trustAnySigner — Use with caution.
  • sso_<n>.sp.trustStore — The name of a WebSphere Application Server truststore object that contains the signer certificates for your IdPs. This name not the file name, but the object name as shown in the administrative console. The default is to use the server's default SSL configuration, which typically refers to the CellDefaultTrustStore. This default is not a good choice because adding signers to the CellDefaultTrustStore pollutes the trust space of the cell. Instead, define a separate IdpTrustStore object that contains the necessary certificates.
  • sso_<n>.sp.X509PATH — As an alternative to using a WebSphere truststore object, you can supply the path to a file that contains the intermediary certificates of the signing certificates.
  • sso_<n>.sp.CRLPATH — The name of a certificate store that contains a certificate revocation list (CRL).
  • sso_<n>.sp.trustedAlias — If your truststore contains multiple certificates, and you want to restrict which certificate from the truststore to use to validate the signature, use this property to specify it.

After it SAML TAI determined to intercept the request, it needs to ensure that the identity of the IdP is one of a set of trusted IdPs. The IdP can be identified by either of the following options:

  • A distinguished name: sso_<n>.idp_<m>.allowedIssuerDN
  • A simple name: sso_<n>.idp_<m>.allowedIssuerName

By choosing one of these properties, you avoid the common trap of accepting SAML assertions that were signed by any certificate that was issued by a signer in the truststore. These properties ensure that the assertions were signed by the IdP. They also avoid the certificate management problem that is inherent in PKI-based solutions. That is, if you save the IdP certificate in the truststore, when that certificate is renewed before expiration, you must update all truststores in which it was stored.

Setting these properties correctly and getting the signing certificates into the truststore can be tricky. The wsadmin AdminTask called importSAMLIdpMetadata can assist you in this effort.

SAML TAI and subsequent requests

After a user logs in, the login session is maintained by an LtpaToken2 cookie, which must be examined closely. Consider an example where /app1 is protected by the SAML TAI, and /app0 is not. What is the expected behavior when the user logs in, first to /app0, without SAML, and then accesses /app1?

Three modes of operation are possible based on the SAML TAI sso_<n>.sp.enforceTaiCookieproperty:

  • The default mode of operation occurs when the property has a value of true. In this case, not all LtpaToken2 cookies are equal. When a user whose Subject does not contain a SAMLResponse (because the user logged in to /app0 first) tries to access /app1, the WebSphere Application Server security run time detects that this Subject does not contain a SAMLResponse. The request is rejected, and the user is redirected to the IdP to log in.
  • If sso_<n>.sp.enforceTaiCookie=false, all Lightweight Third Party Authentication (LTPA) tokens are "equal." That is, a user who logs in to another application in the WebSphere Application Server cell without a SAML-based login can reuse that LtpaToken2 cookie for SAML TAI protected applications. In this case, the Subject's contents are not checked for a SAMLResponse, and the user is authenticated for /app1.
  • The third mode of operation strictly applies the SAML concept of AudienceRestriction to subsequent authentications. Consider whether /app1 and /app2 are both protected by the SAML TAI, but are configured to use different SSO partners, each with different AudienceRestrictions. The intention of this configuration is for the SAMLResponses to not be considered equal. With the default SAML TAI properties, the Subject is checked to contain any SAMLResponse. The sso_<n>.sp.cookieGroup property, if defined, overrides this permissive acceptance of any SAMLResponse. The cookieGroup property can be assigned a string that is added to the WebSphere Application Server Subject. For simplicity, let's call that string the Saml20TaiSsoPartners.

Consider an example with sso_1.sp.cookieGroup=app1 and sso_2.sp.cookieGroup=app2. The user logs in to /app1. On all interaction with /app1, the run time ensures that the Subject contains a SAMLResponse, and the Saml20TaiSsoPartners contains "app1." Next, the user tries to access /app2 and sends the LtpaToken2 cookie. The WebSphere Application Server security run time ensures that the associated Subject contains a SAMLResponse and checks that the Saml20TaiSsoPartners contains "app2." Because it does not, the user is redirected to the IdP configured for sso_2.

The calls to checkSubject? in Figure 4 represents the logic to implement this method.

Secure the SAML assertions

The HTTP POST to the assertion consumer service application should normally occur over an HTTPS connection. In fact, many IdPs require the connection to be over SSL. In addition to the encryption that is provided by the SSL connection, you might have a reason for encrypting the payload of the SAML Response object. Remember that the IdP redirects the request through the user's browser. By using a browser plug-in, the user can view the SAML Response as it passes through the browser. (The user cannot change the content because it causes the digital signature check to fail, but the user can still see the content.) If your use case does not require this secondary encryption, you do not need to encrypt the SAML Response.

To achieve the encryption, the SP (the SAML TAI) uses its own private/public key pair. The IdP is provided with a copy of the public key, by using a public certificate, and uses that public certificate to encrypt the content. Only a holder of the private key (the TAI) can decrypt the content. The following properties support the SAML Response encryption:

  • sso_<n>.sp.keyStore — The name of a WebSphere Application Server keystore object that contains the personal certificate for your SP. It is not the file name, but the managed object name as shown in the administration console.
  • sso_<n>.sp.keyAlias — The alias of the key in the keystore.
  • sso_<n>.sp.keyPassword — The password that is needed to access the key.
  • sso_<n>.sp.keyName — The full DN of the key that you specify to use.

The IdP needs to receive the public certificate (and any signers). Again, you can use the wsadmin AdminTask exportSAMLSpMetadata to create an XML file that can be imported by the IdP application. Depending on your IdP system, you might need to edit the resulting XML to reference only the encryption certificate information.

Customize the user identity

The IdP asserts a user to the SAML TAI. This user might exist within the WebSphere Application Server user registry, depending on your use case. The user is also either local or ephemeral. Some WebSphere products, such as IBM Business Process Manager (BPM), require all logged in users to exist in the user registry. Therefore, they must be local users.

To assert a local user, specify the SAML TAI property sso_<n>.sp.idMap = localRealm. For local users, the NameID field in the SAML Response is set as the user ID in the JAAS Subject. WebSphere Application Server completes the Subject by querying the user registry.

An ephemeral user is one who is asserted to exist, but is not backed by any entries in the underlying user store, such as the LDAP. For ephemeral users, the principalName is obtained from the attribute that is named in the sso_<n>.sp.principalName property.

To assert an ephemeral user, set the sso_<n>.sp.idMap = idAssertion property. After you set this property (the default value), you can choose from several SAML TAI properties to control which user identity is logged in. The first two identify the element in the SAML Response that is used to populate the principalName and uniqueID:

  • principalName: sso_<n>.sp.principalName
  • uniqueID: sso_<n>.sp.uniqueId

The realm to assign to the user ID is determined by the following properties:

  • sso_<n>.sp.realmName
  • sso_<n>.sp.realmNameRange
  • sso_<n>.sp.defaultRealm
  • sso_<n>.sp.useRealm

If you are using idAssertion, and none of these realm-related properties are set, the IssuerName defined in the SAML Response is the realm name used.

In addition, you can establish user identity by choosing from one of two hybrid approaches. The first hybrid approach uses the idMap value = localRealmThenAssertion. In this mode, the user identity is extracted from the SAML Response, and the user registry is searched. If the user is found in the user registry, the login proceeds as a localRealm user. If the user is not found, the login proceeds as an idAssertion user.

The second hybrid approach requires the idMap value = localRealm. It augments the group membership information that is returned from the user registry for a localRealm user with group information that is asserted in the SAML Response. Use the sso_<n>.sp.groupMap=addGroupsFromLocalRealm property for this second hybrid approach. In this approach, the group that is asserted in the SAML Response must exist in the user registry, but the user is not listed as a member of the group. This option dynamically makes the logged-in user appear to be a member of the registry group by using the SAML assertion.

In both cases, asserted groups that are not found in the user registry are ignored for WebSphere authorization purposes. However, the SAML Assertion is saved in the user's Subject and can be used for downstream assertions where those assertions might be meaningful.

Consider the example in Figure 6. Instead of asserting that the users exist in the Unified Assurance Company LDAP (localRealm), the Purple users are ephemeral. Their group membership is also asserted by using the SAML Response. In particular, their membership in UACGroup is of interest. The other groups are asserted, but are unimportant to the Unified Assurance Company application. The Unified Assurance Company web application that the users access has a security role that is bound explicitly to the Group UACGroup from an external trusted realm idp.purple.com/adfs/services/trust. You must configure your IdP to generate the appropriate group membership claims in the SAML Response.

Figure 6. Asserting ephemeral identity
Asserting ephemeral identity
Asserting ephemeral identity

Lastly, convert somewhat the user ID, principalName, and NameID that are asserted in the SAML Response before you assert the identity to WebSphere Application Server. Alternatively, consider using the identity of a different element in the SAML Response XML document if one is available. The sso_<n>.sp.userMapImpl property provides a second plug-point, an interface, for the SAML TAI where you can implement a customized user mapping class that returns the asserted user identity. The following code listing shows the userMapImpl interface.

import java.util.String ;
import com.ibm.websphere.security.NotImplementedException;
import com.ibm.websphere.security.UserMappingException;
import com.ibm.websphere.wssecurity.wssapi.token.SAMLToken;
import com.ibm.wsspi.security.web.saml.UserMapping;

public abstract interface UserMapping {
  
 public abstract String mapSAMLAssertionToName(SAMLToken samlToken)
			throws UserMappingException, NotImplementedException;
}

In the second example custom implementation, ignore the NameID element in the SAML Response, and instead establish the user identity from the DN element in the Response as shown in the following listing.

/** Standard ADFS name for a SAML attribute containing the DN. */
public static final String SAML_ATTR_DN =
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/distinguishedname";
public static final String FRIENDLYNAME = "Custom User Mapping";

public String mapSAMLAssertionToName(SAMLToken samlToken)
			throws UserMappingException, NotImplementedException {
   log.entering(CLASSNAME, "mapSAMLAssertionToName");
   String result = null;
   result = getDN(samlToken);
   log.fine(FRIENDLYNAME + " mapped to user " + result);
   log.exiting(CLASSNAME, "mapSAMLAssertionToName");
   return result;
}

public static String getDN(SAMLToken token) throws UserMappingException {
   String dn = null;
   if (token != null) {
      List<SAMLAttribute< attrList =  token.getSAMLAttributes();
      if (attrList != null  && attrList.size() < 0) {
         for (SAMLAttribute attr : attrList) {
            if (attr.getName().equals(SAML_ATTR_DN)) {
               if (attr.getStringAttributeValue().length > 0) {
                  dn = attr.getStringAttributeValue()[0];
                  log.fine("User Mapping found DN: " + dn);
                  break;
               }
            }
	…// Error checking code removed.
   return dn;
}

Set up the SAML TAI

To set up the SAML TAI, ask yourself these high-level architecture-type questions:

  1. What URLs are to be protected by SAML TAI? You need to determine which URLs (applications), if any, will cause an SP redirect to IdP Web SSO use case. The answer will be the input to the filter property.
  2. For the SP, what is the assertion consumer service URL to which the IdP will redirect?
  3. Will users be logging in as localRealm or idAssertion user IDs?
  4. Will the SAML Response be encrypted?

For each of your IdPs, you need to know:

  • The IdP vendor
  • Whether that vendor supports RelayState
  • The format that the IdP accepts for SP metadata
  • The IdP entity ID
  • Whether you have the signing certificate that is used by the IdP, including a full issuer chain

Follow these high-level administration steps for WebSphere Application Server:

  1. If you are encrypting the SAML Response, use the WebSphere Application Server administration tools to create a new keystore, called (for example) SPKeyStore:
    1. Generate a private/public key and a public certificate.
    2. Export a public certificate, possibly as SAML metadata.
  2. By using the admin tools, create a new truststore called (for example) IdPTrustStore. Install the IdP signing certificate and chains.
  3. Add the SAML TAI (ACSTrustAssociationInterceptor). Do not enable the TAIs yet.
  4. Add the TAI to the com.ibm.websphere.security.DeferTAItoSSO custom property to enable SP redirect to IdP Web SSO.
  5. Add the TAI to the com.ibm.websphere.security.InvokeTAIbeforeSSO custom property to prefer a SAML token over LtpaToken.
  6. Configure the SAML TAI properties.
  7. Install the assertion consumer service application:
    <was>/installableApps/WebSphereSamlSP.ear
  8. Enable the TAIs.

The following wsadmin AdminTasks that are related to the SAML TAI are useful:

  • AdminTask.showSAMLTAISSO()
  • AdminTask.showSAMLIdpPartner()
  • AdminTask.importSAMLIdpMetadata()
  • AdminTask.exportSAMLSpMetadata()

Useful trace specifications:

  • com.ibm.ws.security.web.saml.*
  • com.ibm.ws.security.*
  • com.ibm.ws.security.web.*=all:com.ibm.ws.wssecurity.saml.*=all
    (The trace is usually requested by WebSphere support.)

Hints and tips

When using SAML TAI, keep in mind the following guidance:

  • Don't point your browser directly at the assertion consumer service URL unless you are posting a SAML Response for it to process. Otherwise, you see the authentication challenge for that application. For the assertion consumer service that is included, this challenge is a Basic Auth challenge. If you implement your own custom assertion consumer service application, the challenge can be a form-based login.
  • If you write your own UserMapping or IdPMapping class, as shown in the code samples in this article, use Java logging to integrate this code with the WebSphere Application Server tracing infrastructure. By using this approach, you can dynamically enable or disable tracing in your code.
  • Consider the appropriate validity periods for your LtpaToken2 and SAML tokens. The default validity period for LTPA is 120 minutes. But, what happens when the SAML token is only 60 minutes? WebSphere Application Server web services can propagate the SAML token outbound by using SOAP web services that contain WS-Security SAML tokens (outside the scope of this article). This outbound web services call can fail because the SOAP service provider that receives that SAML token after it expires rightly rejects it. If your architecture includes this SAML token propagation use case, ensure that the validity time lengths for LTPA and SAML match. In fact, make the SAML lifetime slightly longer than the LTPA lifetime.

Conclusion

This article provided guidance to help systems administrators who are running IBM WebSphere Application Server understand the SAML Web TAI. You learned how it works within the existing web security run time within WebSphere Application Server and how it subtly changes that security. You also learned how the large number of custom TAI properties interact with each other and when to use these custom TAI properties (and when they are not needed). You also saw a couple of sample class implementations that show how to customize the login process.

Acknowledgment

The authors thank colleagues Jens Engelke, Barbara Jensen, Michael Whale, Simon Kapadia, Bill O'Donnell, and Chunlong Liang for their valuable input and assistance.


Downloadable resources


Related topics


Comments

Sign in or register to add and subscribe to comments.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Middleware
ArticleID=1040909
ArticleTitle=Understanding the SAML trust association interceptor for the WebSphere Application Server
publish-date=12082016