SAML assertions across WebSphere Application Server security domains

Security Assertion Markup Language (SAML) is fast becoming the technology of choice to create Single Sign-On (SSO) solutions across enterprise boundaries. This article describes how to use the SAML support in IBM® WebSphere® Application Server V7.0 Fix Pack 7 to assert SAML tokens across enterprise boundaries in different security domains, and also to make access control decisions directly using the foreign security domain user identity and custom SAML group attribute, all based on the trust relationship. Trust relationship validation is enforced via policy set binding configuration at three points to ensure authenticity and to guard against security threats. This article shows how this technology can be easier to manage and more scalable compared to the alternative identity mapping approach. This content is part of the IBM WebSphere Developer Technical Journal.

Share:

Chunlong Liang (liangch@us.ibm.com), WebSphere Web Services Developer, IBM

Chunlong Liang is a developer of Web services security on the WebSphere platform. Chunlong has been in WebSphere development for over 9 years and has developed many security features for the WebSphere platform. Prior to joining WebSphere team, Chunlong was an actuarial analyst and programmer for 6 years, and was a statistician for 3 years.



Ching-Yun (C.Y.) Chao, Ph.D. (cyc@us.ibm.com), Senior Software Engineer, IBM

Ching-Yun (C.Y.) Chao leads the IBM PureApplication System and IBM Workload Deployer security and trust framework and infrastructure design and development. When working on the WebSphere Application Server web services security development, C.Y. lead the design and development of Security Assertion Mark Language (SAML) security token and cross security domain trust support. Before working on web services security, C.Y. is lead security architect of WebSphere Application Server leading the design and development of pluggable authentication and pluggable authorization mechanism, multiple security domains, and security auditing. Prior to joining WebSphere development, C.Y. was lead architect and developer of the IBM PC server highly available system clustering project. He was awarded IBM Master Inventor in 2006 and has many patents in the area of security and high availability system clustering. C.Y. received his Ph.D. in Electrical Engineering from Northwestern University.



14 April 2010

Also available in Chinese

Introduction

Security Assertion Markup Language (SAML) is an OASIS open standard for representing and exchanging user identity, authentication, and attribute information. SAML is fast becoming the technology of choice to create Single Sign-On (SSO) solutions. For companies that want to provide business services to authorized users of their business partners, this technology can be applied in the creation of SSO solutions to federate Web services resources across enterprises.

Consider a business scenario in which you want to enable your users to access business services of partner companies. A preferred SSO behavior is for users to only be required to authenticate to your business without needing to further authenticate to the other companies. SAML tokens are used to pass user identity and attribute data by users when they access Web services resources. It is reasonable to assume that companies will not consolidate their multiple user directories into a single common user directory because of business and privacy concerns. This means SAML tokens will contain user identities from foreign security domains that are not defined in the user directory of business service providers. This article describe an approach for using the SAML support in IBM® WebSphere® Application Server V7.0 Fix Pack 7 to assert SAML tokens across multiple security domain boundaries -- and for making access control decisions directly using the foreign security domain user identity and custom SAML group attribute. You will see that asserting foreign identity and custom group attribute based on a trust relationship is easier to manage than working with identity and group mapping technologies.


SAML tokens

SAML tokens are digitally signed by a token issuer to ensure token integrity. Business service providers can verify the authenticity of user identities in SAML tokens by validating the token issuer digital signatures. Validating a token issuer digital signature is the basis of verifying the trust relationship among business partners. In addition to describing the trust model for asserting SAML tokens to create user security context in the application server run time environment, this article also includes an EJB™ 3.0 Java™ API for XML Web Services (JAX-WS) sample application to illustrate how to configure SAML assertions across security domains based on a trust relationship between SAML token issuers and Web services providers. Through this application, you will learn how to configure business services for making resource access control decisions using SAML tokens.

Using the application server SAML token assertion trust model to build SSO solutions has many advantages:

  • For users, the advantage is that they will only need to authenticate to their own security domain and will then be able to access business partner Web services resources via the trust relationship. Users do not need to manage additional accounts and authentication data of those other security domains.
  • For IT administrators, one obvious advantage is the broad third-party interoperability achieved from using standard-based SAML technology.
  • Another major advantage for IT administrators is the reduced cost of identity management when federating business resources. There is no need to consolidate company user directories, which would be a daunting task even if it was at all practical in a business situation.
  • Yet another advantage for IT administrators is that user identities in foreign security domains are preserved and can be readily included in security and business auditing records.

Unless otherwise specified, WebSphere Application Server in this article refers to WebSphere Application Server V7.0 with Fix Pack 7 (V7.0.0.7) and later.


Multiple security domain business scenario

Figure 1 is an example of a Web services federation business scenario. The diagram shows three WebSphere Application Server security domains, each of which contains its own user registry configuration. These security domains could be representing individual business units or separate companies. Users in the two security domains on the left send Web services messages to access resources of the security domain on the right. Users send their identities in SAML tokens to identify themselves to the target security domain. A Web services provider will use the SAML user identity to create a security context; for example, a JAAS subject. JAAS subjects that represent clients are needed to make resource access control.

Figure 1. Asserting SAML tokens across WebSphere Application Server security domains
Figure 1. Asserting SAML tokens across WebSphere Application Server security domains

If the three security domains share a common user directory, a Web services provider can simply map the subject identity of the received SAML tokens to a user entry in its local user directory to create a JAAS subject representing the requester. When the three security domains do not share a common user directory, a Web services provider can still map the received SAML subject identity to a user entry in the local user directory, but it will need to configure the local user directory. That each security domain has its separate user directory is a reasonable assumption when a security domain represents a separate company or a separate business unit. An administrator can create one entry in the local user directory with the same identity for every user identity of the foreign security domain and foreign user directory, which is basically a one-to-one mapping configuration. An administrator can also map every user identity of a foreign security domain to a single user entry in the local user directory, which is a many-to-one mapping. More generally, an administrator can setup many-to-many mapping, and map foreign user identities and groups to certain user identities and groups in local user directory.

Setting up identities and groups for identity mapping is tedious and has an interesting side effect. What happens if someone authenticates to the local security domain using a user ID that is intended only for identity mapping purposes? In addition, as the number of security domains grows, the mapping configuration likely will become more complicated. For business auditing purposes, it is also desirable to know the original user who accesses the resources. A method will be described shortly that completely avoids identity mapping and can naturally preserve the original user identity.

This article leverages the multiple security domain feature of WebSphere Application Server. A security domain contains a separate set of security policy and configuration data, which includes a user directory configuration. WebSphere Application Server enables multiple security domains to be configured in a cell. When global security is enabled, you can configure at least one security domain as the administrative security domain, and zero or more application security domains in a cell. The administrative security domain is used by the administrative subsystem, including the deployment manager, node agents, and the administrative console application. The administrative security domain also serves as the default security domain for application servers when no application security domain is defined. An application server can attach an application security domain to be used by all the applications deployed on that server.

Multiple security domains provide better application and user isolation. A trusted authentication realm (TAR) mechanism provides a secure and easy way to manage users and applications from a foreign security domain and access resources in the local security domains, provided that the foreign security domain is trusted by the local security domain. Foreign security domain users get to keep their identities and do not need to be verified against the local user directory. The WebSphere Application Server V7.0 implementation supports LTPA security tokens and EJB resource accesses via RMI/IIOP CSIv2 protocol. The WebSphere Application Server SAML feature extends the TAR mechanism to access resources via Web services security protocol and SAML security tokens.

Essentially, a Web services provider enables Web services requests from a foreign security domain to access it, provided that SAML tokens are issued by token issuers that are trusted by the Web services provider. JAAS subjects are credited using identity and group attribute data in SAML tokens. There is no need to access the local directory to look up any local user identity and attributes. Trusted foreign security domain user identities and groups can be assigned directly to local security roles. This mechanism does not involve configuring the local user directory and, hence, significantly simplifies the access control configuration. But how does a Web services provider verify the trust relationship?

The SAML feature in WebSphere Application Server can be configured to perform trust relationship verification at three points. The application server can verify that:

  • The digital signatures of the SAML token issuer are valid to verify the authenticity of the tokens.
  • That the specific issuer is indeed trusted to make SAML assertions of user identities.
  • The specific issuer represents a security domain whose users are trusted to enter the destination security domain.

After the trust relationship is validated, Web services providers can assert a received SAML token to create a client caller subject in the security context using the SAML token issuer name, user identity, and the optional group membership attribute. The security context creation is based on the trust relationship, and so the application server does not need to check the SAML user identity against the user registry of the local security domain. The trust relationship-based approach does not require users of the foreign security domain to be defined or be mapped to identities in the local user directory.

When all security domains involved are WebSphere Application Server, you can set up cross-security domain SAML assertion and access control entirely using policy configuration, without any additional code. However, WebSphere Application Server also supports the case where an originating security domain or SAML token issuer is not WebSphere Application Server (or any IBM product). SAML specifications do not dictate the group attribute name, and so WebSphere Application Server can be configured to use any SAML attributes to represent user identity and group, as will be described later. When a destination security domain is not WebSphere Application Server, you might be able to setup the three trust relationship validations either via configuration or through custom code, depending on the particular product, but such configuration is outside the scope of this article.

You can propagate a client caller subject that contains foreign security domain identity and group to downstream Web services using policy set and bindings configuration in one of two ways:

  • You can propagate the original SAML tokens in Web services requests to WebSphere Application Server, in which case the same trust relationship validation will apply.
  • Alternatively, you can propagate the entire client RunAs subject in Web services messages with the received SAML token already in the RunAs subject.

As a best practice, the message exchange between Web services clients and Web services providers are protected either by transport-level protection (for example, SSL) or by message level encryption and signing, or both. A blue lock icon is used in Figure 1 to indicate that message protection. All information in SAML tokens, including user identity and attributes, must be digitally signed by the SAML tokens issuer. A red lock icon is used in Figure 1 to indicate that SAML tokens are signed by their issuers. Although this article assumes that all security domains consist of a WebSphere Application Server-based system, you can apply the technique to other application servers as well. The WebSphere Application Server SAML assertion trust model is described in the next section. It is strongly recommended that you configure or program your other vendor application servers to enforce trust relationship validation accordingly.


Trust model

WebSphere Application Server can be configured to assert SAML tokens based on a trust relationship with the SAML token issuers. The application server does not need to verify the asserted SAML identity against the local user registry when creating security context asserting SAML tokens. The WebSphere Application Server trust model enforces the trust relationship validation at the three trust relationship verification points mentioned earlier. The basis of the trust relationship validation is that SAML tokens are digitally signed by the issuer.

The sample SAML 2.0 bearer token shown in Figure 2 contains a digital signature of the entire SAML token. Enveloped signature must be used when signing SAML tokens, which means an entire SAML token is covered by the embedded signature. The digital signature ds:Reference URI attribute references the SAML token ID _93B335BAA1D8B8811A1257438450816. The issuer of the SAML token uses its own private key to sign SAML tokens and includes the corresponding X.509 certificate in the tokens. The SAML token icon in the figure contains a certificate icon, which indicates the issuer certificate that is embedded in SAML tokens. Web services providers can use the public key in the embedded certificate to verify the integrity of the issuer digital signature, and the embedded certificate to verify whether the issuer is trustworthy.

Figure 2. A sample SAML 2.0 bearer token digitally signed by its issuer
Figure 2. A sample SAML 2.0 bearer token digitally signed by its issuer
  • First trust relationship verification point

    The first verification point verifies that the issuer signing certificate is indeed one that is trusted by the application server to issue SAML tokens. The application server checks the received certificate against certificates in the configured truststore. Then, the application server verifies the integrity of the received tokens by validating the SAML token digital signature using the public key in the verified issuer signing certificate. The digital signature validation ensures that information in the received SAML tokens have not been tampered with.

    At this verification point, the application server ensures that it only accepts SAML tokens from trusted issuers.

  • Second trust relationship verification point

    You can configure the application server to check both the SAML token issuer name attribute and the included signing certificate against the policy set binding configuration. For optimal results, specify the certificate owner name and the SAML token issuer name in the policy set binding configuration so that the application server can establish a linkage between the signing certificate and the issuer name. That way, the application server can ensure that the issuer name of SAML tokens that are signed by a particular token issuer (which is represented by the specified signing certificate) is consistent with the issuer name defined in the policy set binding configuration. By default, the application server uses the SAML token issuer name to represent the foreign security domain. Specifically, the application server verifies that the issuer is indeed trusted to assert users from a specific security domain only.

    This verification point is important to maintain application server runtime integrity; it ensures that when a particular SAML token issuer is compromised, the damage is confined to users from the particular security domain and cannot spread to users belonging to other security domains.

  • Third trust relationship verification point

    The application server verifies that the foreign security domain is trusted. Specifically, the SAML token issuer name is indeed defined in the list of inbound trusted authentication realms. The application server has a configuration option to trust any foreign security domain. For optimal results, explicitly specify a trusted foreign security domain in the list of trusted authentication realms.

    At this verification point, the application server ensures that SAML token assertion is only permitted for users in a trusted foreign security domain.

Subject confirmation method considerations

WebSphere Application Server supports the OASIS Web Services Security SAML Token Profile 1.1 Specification and, in particular, supports both the bearer subject confirmation method and the holder-of-key subject confirmation method:

  • Holder-of-key subject confirmation method requires the entire SAML token to be digitally signed by its issuer, among other security requirements.
  • Bearer subject confirmation does not require the application server to enforce SAML token digital signing.

The application server, by default, ensures that SAML tokens are signed for both confirmation methods. Verifying SAML token digital signature and the signer certificate are the basis of the SAML token assertion trust model, and the trust model applies to both bearer SAML tokens and holder-of-key SAML tokens. In the case of holder-of-key subject confirmation, SAML tokens are cryptographically bound to the containing SOAP messages. Therefore, Web services clients use the key defined in the SAML token to digitally sign the SOAP request message. As a result, Web services receivers can verify that the Web services client indeed knows the key and, hence, owns the SAML token. Using holder-of-key SAML tokens improves the strength of the message and the SAML token protection, but does not affect the SAML token assertion trust model.


Asserting SAML tokens

When creating security context via SAML token assertions, the application server runtime code requires the foreign security domain name, the user identity, and (optionally) user group membership data from SAML tokens.

The application server runtime extracts the SAML token issuer name from validated SAML tokens and uses it as the foreign security domain authentication realm name. (Figure 3)

Figure 3. SAML 2.0 issuer assertion example
Figure 3. SAML 2.0 issuer assertion example

By default, the user security name is either the NameIdentifier assertion for SAML 1.1 tokens (Figure 4) or the NameID assertion for SAML 2.0 tokens (Figure 5). Optionally, other SAML attributes can be configured as the user security name.

Figure 4. SAML 1.1 NameIdentifier example
Figure 4. SAML 1.1 NameIdentifier example
Figure 5. SAML 2.0 NameID example
Figure 5. SAML 2.0 NameID example

The SAML specification does not specify a standard group membership attribute. The application server provides a policy set binding configuration to specify which SAML attribute, if any, should be used to define group membership. Examples of group membership defined in the SAML 1.1 and SAML 2.0 AttributeStatement assertions are shown in Figures 6 and 7.

Figure 6. SAML 1.1 group member attribute example
Figure 6. SAML 1.1 group member attribute example
Figure 7. SAML 2.0 group membership attribute example
Figure 7. SAML 2.0 group membership attribute example

The SAML 1.1 example contains a Subject assertion in the AttributeAssertion element. This is only required by the SAML 1.1 specification.

Given the previous examples, the client caller Subject in the security context contains this user information:

  • Realm name: acme.com
  • Security name: Alice
  • Unique ID: acme.com/Alice
  • Unique group ID 1: acme.com/Acme employee
  • Unique group ID 2: acme.com/Gold membership

Asserting across WebSphere Application Server security domains

A sample Web services client application and Web services provider application are included with this article to demonstrate how to set up a policy set, binding, and trusted authentication realm configuration to assert SAML tokens across security domains. Figure 8 shows the section of the solution (circled in blue) that the sample application covers.

Figure 8. Asserting SAML tokens across security domains
Figure 8. Asserting SAML tokens across security domains

The sample application is self-contained so that you can run it with minimal effort. Typically,when you federate Web services resources (discussed later), you use a Security Token Service (STS) to authenticate users and to issue SAML tokens to authorized users. Instead of putting a dependency on an external STS, the sample application leverages the WebSphere Application Server SAML Token Factory API to create SAML tokens (which are referred to as self-issued SAML tokens in this article). To demonstrate asserting SAML tokens across security domains, the sample application needs to differentiate between at least two security domains. In order to demonstrate cross security domain assertions, two application servers must usually be configured, each in a separate security domain. To simplify the configuration for this example, the sample application demonstrates cross security domain behavior on a single application server installation. The sample application sets the SAML token issuer attribute to represent a foreign security domain when creating the self-issued SAML tokens. Thus, the user and group information in SAML tokens represent users in the foreign security domain and is not defined in the local user registry. Figure 9 illustrates elements of the sample applications.

Figure 9. Sample application demonstrating cross-security domain SAML assertions using self-issued SAML tokens
Figure 9. Sample application demonstrating cross-security domain SAML assertions using self-issued SAML tokens

An alternative approach to writing custom code is to configure policy set bindings to generate SAML token from the RunAs subject in the security context. When creating self-issued SAML token from the RunAs subject (and if the RunAs subject does not already contain a SAML token), the WebSphere Application Server V7 Fix Pack 7 implementation extracts the user identity from the WSCredential object in the RunAs Subject, but does not insert group membership information into the SAML tokens. Hence, this article uses a custom code approach to programmatically extract group information from WSCredential objects to insert into SAML tokens.

Figure 9 shows a browser user authenticating to the sample application using form-based login. A Web browser client will need to enter a user name and password to authenticate to the local user directory. The Web service client application generates a self-issued SAML token using the user identity, but otherwise asserts a pre-configured security domain realm name as token issuer and group membership data. The Web services client invokes the EJBWSProviderApp Web service by sending a SOAP message containing the self-issued SAML token. The SAML token is signed by a key that is configured to be trusted by the EJBWSProviderApp Web services provider. The EJBWSProviderApp Web services provider verifies the trust relationship at the three trust relationship verification points. EJBWSProviderApp is an EJB 3.0 bean exposed as Web services using the JAX-WS programming model. An EJB Web services implementation was chosen to demonstrate how to set up an authorization policy and how to verify the SAML assertions being used in access control decisions.

The code segment in Listing 1 shows how the sample Web services client generates self-issued SAML 2.0 tokens.

Listing 1
1. package com.ibm.wss.sample.ejbws;

2. import java.util.ArrayList;

3. import javax.security.auth.Subject;
4. import javax.servlet.ServletException;

5. import com.ibm.websphere.security.auth.WSSubject;
6. import com.ibm.websphere.security.cred.WSCredential;
7. import com.ibm.websphere.wssecurity.wssapi.token.SAMLTokenFactory;
8. import com.ibm.websphere.wssecurity.wssapi.token.SecurityToken;
9. import com.ibm.wsspi.wssecurity.saml.config.CredentialConfig;
10. import com.ibm.wsspi.wssecurity.saml.config.ProviderConfig;
11. import com.ibm.wsspi.wssecurity.saml.config.RequesterConfig;
12. import com.ibm.wsspi.wssecurity.saml.data.SAMLAttribute;
13. import com.ibm.wsspi.wssecurity.saml.data.SAMLNameID;

14. public class SamlTokenGenerator {
	
15.	public static SecurityToken getSamlToken() throws
16.    ServletException 	
17.   {
18.		SecurityToken samlToken = null;
19.		String name = getPrincipal();
20.		String[] groups = getGroups();
21.		String localRealm = getRealm();
		
22.		System.out.println("SAML principal name: " + name);
23.		try {

24.			SAMLTokenFactory samlFactory =
25.                SAMLTokenFactory.getInstance("http://docs.oasis
26.        -open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0");
			
27.			RequesterConfig reqData =
28.                      samlFactory.newBearerTokenGenerateConfig();

29.			CredentialConfig cred =
30.                         samlFactory.newCredentialConfig();
31.			reqData.setAuthenticationMethod("Password");   
32.               //Password is the authentication method
			
33.			//create SAML NameID or NameIdentifer using principal
34.               //    in Caller Subject
35.			SAMLNameID nameID = null;
36.			nameID = new
37.                       SAMLNameID(name,null,localRealm,null,null);
38.			cred.setSAMLNameID(nameID);
			
39.			//Create SAML Attributes using group memberships 
40.               //    in Caller Subject
41.			if (groups!= null && groups.length >0){
42.				ArrayList<SAMLAttribute> al = new
43.                             ArrayList<SAMLAttribute>();				
44.				SAMLAttribute sattribute = new
45.                        SAMLAttribute("Membership", groups, 
46.                        null,null /* format*/, null, null  );
47.				al.add(sattribute);
48.				cred.setSAMLAttributes(al);
49.			}
50.			ProviderConfig samlIssuerCfg =
51.                 samlFactory.newDefaultProviderConfig("acme.com");   
52.                  //acme.com is issuer name
53.			samlToken = samlFactory.newSAMLToken(cred, reqData,
54.                   samlIssuerCfg);
55.		} catch(Throwable e) {
56.			System.out.println("testNewSecurityTokenV1Bearer:
57.                caught exception: "+e.getMessage() + "\n");
58.			e.printStackTrace(System.out); 
59.		}
59.		return samlToken;
60.	}
61.	
62.	private static String getPrincipal(){
63.		String name = null;
64.		String realm = null;
65.		try {
66.			Subject subject = WSSubject.getRunAsSubject();
67.			WSCredential credential = null;
68.
69.	    	   if (subject != null ) {
70.	        	java.util.Set<Object> publicCreds =
71.                 subject.getPublicCredentials();
72.	            if (publicCreds != null && publicCreds.size() > 0)
73.	            {
74.	                java.util.Iterator<Object> publicCredIterator =
75.                      publicCreds.iterator();
76.	                while (publicCredIterator.hasNext())
77.	                {
78.	                    Object cred = publicCredIterator.next();
79.	                    if (cred != null && cred instanceof
80.                           WSCredential)
81.	                    {
82.	                       credential = (WSCredential) cred;
83.	                       name = credential.getSecurityName();
84.	                       realm = credential.getRealmName();
85.	                       break;
86.	                    }
87.	                }      
88.	            }
89.	    	   }  
90.	    	   
91.	    	   if (name != null && (name.contains(realm))){
92.	    		name =
93.               name.substring(name.indexOf(realm)+realm.length()+1);
94.	    	   }
95.		} catch (Exception e){
96.			name="UNAUTHENTICATED";
97.		}
98.		return name;
99.	}
	
100.	private static String [] getGroups() throws ServletException {
101.		String []grps = null;
102.		try {
103.	       	WSCredential credential = null;
104.	       	Subject subject = null;
105.	       	ArrayList groups = new ArrayList();
106.	    	   try {
107.	    		subject = WSSubject.getRunAsSubject();
108.	    	   } catch (Exception ex) {
109.	    		System.out.println("Exception caught upon invoking
110.                WSSubject.getCallerSubject():" + ex.getMessage());
111.	    		ex.printStackTrace(System.out);
112.	    		throw new ServletException(ex.getCause());
113.	    	   }
114.	    	   if (subject != null ) {
115.	        	java.util.Set<Object> publicCreds =
116.                 subject.getPublicCredentials();
117.	            if (publicCreds != null && publicCreds.size() > 0)
118.	            {
119.	                java.util.Iterator<Object> publicCredIterator =
120.                      publicCreds.iterator();
121.	                while (publicCredIterator.hasNext())
122.	                {
123.	                    Object cred = publicCredIterator.next();
124.	                    if (cred != null && cred instanceof
125.                              WSCredential)
126.	                    {
127.	                       credential = (WSCredential) cred;
128.	                       break;
129.	                    }
130.	                }
131.	            }
132.	    	   }
133.	    	   if (credential != null){
134.	    		groups = credential.getGroupIds();	    	
135.	    	   }

136.	    	   if (groups != null && groups.size() >0){
137.		    	String realm = credential.getRealmName();
138.	    		grps = new String[groups.size()]  ;
139.	    		groups.toArray(grps);
140.	    		for (int i=0; i<groups.size();){
141.	    			String name = grps[i];
142.	    	    	   if (name != null && name.contains(realm)){
143.	    	    		name =
144.              name.substring(name.indexOf(realm)+realm.length()+1);
145.	    	    		grps[i] = name;
146.	    	    	   }
147.	    	    	   i++;
148.	    		}
149.	    	   }
150.		} catch (Exception e){
151.    	   System.out.println("Exception caught populating groups:" 
152.                + e.getMessage());
153.    	   e.printStackTrace(System.out);
154.    	   throw new ServletException(e.getCause());
155.		}
156.		return grps;
157.	}
	
158.	private static String getRealm() throws ServletException{

159.		String realm = null;
160.		try {
161.			Subject subject = WSSubject.getRunAsSubject();
162.			WSCredential credential = null;
163.
164.	    	   if (subject != null ) {
165.	        	java.util.Set<Object> publicCreds =
166.                subject.getPublicCredentials(); 
167.	            if (publicCreds != null && publicCreds.size() > 0)
168.	            {
169.	                java.util.Iterator<Object> publicCredIterator =
170.                     publicCreds.iterator();
171.	                while (publicCredIterator.hasNext())
172.	                {
173.	                    Object cred = publicCredIterator.next();
174.	                    if (cred != null && cred instanceof
175.                          WSCredential)
176.	                    {
177.	                       credential = (WSCredential) cred;
178.	                       realm = credential.getRealmName();
179.	                       break;
180.	                    }
181.	                }
182.	            }
183.	    	   }  		
184.		} catch (Exception e){
185.		   System.out.println("Exception caught retrieving realm:"
186.               + e.getMessage());
187.    	   e.printStackTrace(System.out);
188.    	   throw new ServletException(e.getCause());
189.		}
190.		return realm;
191.	}
192. }

In Listing 1:

  • A SAMLTokenFactory instance is created at lines 24-26 to generate SAML 2.0 tokens.
  • A RequestConfig object specifies requirements of the new token.
  • The newBearerTokenGenerateConfig() call on lines 27-28 specifies that the token should require the bearer subject confirmation method.
  • Lines 50-51 sets the SAML token issuer name to be acme.com.
  • The issuer name will be used to represent the name of the security domain.
  • User identity is set by code from lines 35-38.
  • Lines 41-49 adds group membership SAML attributes.
  • Lines 53-54 generate a SAML 2.0 token with bearer confirmation and the user identity and attributes for testing.
  • At line 62, the getPrincipal() utility method extracts user security name from the RunAs subject. The getPrincipal() utility removes the realm/ prefix if the name returned from UserRegistry getSecurityName() method contains it.
  • At line 100, the getGroups() utility method extracts user groups from the RunAs subject. The format of group information in WebSphere Application Server is "group:<realm>/group_name." The getGroups() utility removes the "group:<realm>/" prefix when extracting group names.
  • At line 158, the getRealm() utility method extracts the realm attribute from the RunAs subject.

The new token will be signed. You might notice that the code does not explicitly specify that the new token should be signed because the code shown used default token issuer properties to generate the new token. The ProviderConfig object created at line 36 contains default properties, as specified in the SAMLIssuerConfig.properties file. A sample SAMLIssuerConfig.properties file for the application is listed in Figure 12. The properties file defines the default keystore, the password to open the keystore, and the private key to sign SAML tokens. These are the default values initially set in the ProviderConfig object. You can modify any of those properties using the ProviderConfig interface. (See the WebSphere Application Server Information Center for more information on the SAML Token Factory APIs.)

A copy of the cell-level properties file can be found in the $install_root/profiles/$PROFILE/config/cells$/CELLNAME/sts directory. A copy of the properties file can be defined at the server level. (See the WebSphere Application Server Information Center for more information.)

Typically, with the policy set attachment in place, the Web services security run time environment will extract user credential information from the RunAs subject in the security context to create and send SAML tokens. No custom code is needed. For the purpose of this example, however, you want to simulate SAML tokens that are created in a foreign security domain. Therefore, you must programmatically generate a self-issued SAML token and inject it to the Web services security run time environment to disable the default behavior of determining SAML tokens by using the RunAs subject. The code shown in Listing 2 does exactly that. The code saves the self-issued SAML token into the AxisService RequestContext. The Web services security runtime propagates the SAML token in the RequestContext in downstream messages when a token is found.

Listing 2
43. SAMLToken samlToken = <self-issued SAML tokens previously generated>; 
44. 
45. Map<String, Object> requestContext = ((BindingProvider) 
46.                                   servicePort).getRequestContext(); 
47. 
48. requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, serviceURL); 
49. //Put the samlToken into RequestContext 
50. requestContext.put( 
51. com.ibm.wsspi.wssecurity.saml.config.SamlConstants.SAMLTOKEN_IN_MESSAGECONTEXT, 
    samlToken);

The Web services provider side of the sample application is simple. No custom code is needed on the Web services provider side to demonstrate using SAML assertions in making access control decisions.

Configuring the application server

This section provides configuration steps for setting up the sample application, policy set, and binding configuration. These instructions assume that you are already familiar with the procedures for configuring policy set and bindings to use SAML tokens. See the WebSphere Application Server Information Center and the JAX-WS articles listed in Resources for more information.

To run the sample application included with this article and follow the next sections, you need to perform some initial configuration of the application server:

  1. Install WebSphere Application Server Version 7.0 Fix Pack 7 or higher.
  2. Download and install the sample Web services client application and Web services provider application included with this article.
  3. Follow these instructions to import the SAML 2.0 Bearer WSHTTPS default policy set from the default policy repository (Figure 10). This policy set requests a Web services client to send a SAML 2.0 token with the bearer subject confirmation method, and to protect the message by SSL.
    Figure 10. Importing SAML 2.0 Bearer WSHTTPS default policy set from the default repository
    Figure 10. Importing SAML 2.0 Bearer WSHTTPS default policy set from the default repository
  4. Assuming WebSphere Application Server global security is enabled, configure your trusted foreign security domains. The simplest way to do this is to use the Security Configuration wizard to enable administrative security. You will also need to enable application security so that the sample application can use the authenticated user subject in the security context to create a SAML token. This step involves configuring the third trust relationship verification point on the Web services provider side. This step is needed to use the application server for simulating the target security domain Web services provider. The WebSphere Application Server V7.0 authentication subsystem supports asserting user identity with a foreign realm name, and will check the foreign realm name against the list of inbound trusted authentication realms. After you complete this configuration step, WebSphere Application Server can create a client caller subject with a user identity in a foreign security realm.

    After completing the steps to configure global security, perform these steps to configure trusted security domains:

    1. From the Global Security panel, click Configure beside Available realm definitions.
    2. Click Trusted authentication realms - inbound.
    3. Choose Trust realms as indicated below (Figure 11).
    4. Click Add External Realm.
    5. Add the SAML assertion issuer name to External realm name. The SAML assertion issuer name provides information about the issuer of the SAML assertion, which is either inside the <Issuer> element in the SAML 2.0 assertion, or is the Issuer attribute in the SAML 1.1 assertion. For this example, acme.com is added as a trusted foreign realm, as shown in Figure 11.
      Figure 11. Defining SAML tokens issuer, acme.com, as a trusted authentication realm
      Figure 11. Defining SAML tokens issuer, acme.com, as a trusted authentication realm
    6. Create the user name Alice with password security in your user registry. In this test, the built-in federated repository is used as the user registry. This step is needed to use the application server to simulate the originating security domain Web services client. Adding user Alice to the user registry is necessary so that you can use a browser to authenticate and to access the protected sample application. In this example, the federated user repository is used as the local user registry and the default realm name is defaultWIMFileBasedRealm. The sample application will take an authenticated user identity to create a SAML token and set the token issue to "acme.com" to simulate a cross security domain assertion. Application security must be enabled so that the security runtime will enforce the security constraints on the application and put the authenticated user identity in the security context.
    7. Unzip the sample keystore file and sample truststore file to the directory etc\ws-security\samples, under the same profile where the sample application is installed. The keystore password is storepass, and the key password is keypass. The sample keystore file saml-provider.jceks contains an RSA private key and corresponding X.509 certificate and RSA public key. The keystore file is used to digitally sign the self-issued SAML tokens. The truststore file recipient.jceks contains the same X.509 certificate and is used by the Web services receiver to validate authenticity of SAML tokens. You can generate the keystore using the keytool command that is shipped with WebSphere Application Server (Listing 3).
      Listing 3
      keytool -genkey -alias samlissuer -keystore saml-provider.jceks -dname 
         "CN=SAMLIssuer, O=ACME" -storepass storepass -keypass keypass -storetype 
         jceks -validity 5000 -keyalg RSA

      Use the following commands to export the issuer certificate to an issuerpub.cert file and then create the recipient.jceks truststore file:
      Listing 4
      keytool -export -alias samlissuer -file issuerpub.cer -keystore 
      	saml-provider.jceks -storepass storepass -storetype jceks
      
      keytool -import -alias samlissuer -file issuerpub.cer -keystore 
      	recipient.jceks -storepass storepass -storetype jceks 
      	-keypass keypass –oprompt

      Actually, you use the saml-provider.jceks file as both keystore file and truststore file because saml-provider.jceks contains the issuer X.509 certificate, and also because this example uses a single application server installation. In general, if you are running the sample Web service client and Web services provider on two application servers in two security domains, you will want to create a trustfile that contains the issuer X.509 certificate but not the private key.
    8. Edit the properties file, SAMLIssuerConfig.properties, at $install_root/profiles/$PROFILE/config/cells$/CELLNAME/sts to set a keystore and a truststore. The keystore and other configuration data in this properties file are used by the SAML token factory to sign the SAML tokens when creating self-issued SAML tokens. The truststore file configuration is used as the default value by the SAML token factory when programmatically validating SAML tokens. The modified properties file should look like the one in Figure 12.
      Figure 12. Sample SAMLIssuerConfig.properties file
      Figure 12. Sample SAMLIssuerConfig.properties file
    For demonstration purposes, the sample application includes the SAML samlbearerAssertProvider and samlbearerAssertionClient bindings example. These two general binding examples were created from making of copy of the sample general bindings Saml Bearer Provider Sample and Saml Bearer Client Sample that are included with WebSphere Application Server. You will see how to create the two bindings files later. Basically, you modify the Saml Bearer Client Sample to generate self-issued SAML tokens instead of requesting a SAML token from an external STS. You also need to modify the Saml Bearer Provider Sample general binding to select the SAML token to represent caller identity and to enable cross security domain assertion. Rather than create these bindings yourself, you can import the sample bindings by following the instructions in the next step.
  5. To import the sample general client bindings, unzip the bindings files included with the sample application into a temporary directory, and then import them into the application server using either the importBinding command script or the Import button in the administrative console. Create a path with the .../bindings/samlbearerAssertionClient directory structure in the temporary directory.

Configuring the Web services client

To create the required general bindings (only if you choose not to import the samlbearerAssertionClient binding example), perform these steps and modify the Saml Bearer Client sample:

  1. Log in to the administrative console.
  2. Select Services in the left navigation.
  3. Expand Policy sets and select General client policy set bindings.
  4. In the General client policy set bindings dialog, select Saml Bearer Client sample, then click Copy from the collection table. Enter the name you choose; for example, samlbearerAssertionClient.
  5. Refer to the WebSphere Application Server Information Center for information on configuring client and provider bindings for the SAML bearer token to modify client bindings for the SAML 2.0 bearer token. Remove the four custom SAML token generator callback handler properties: stsURI, wstrustClientPolicy, wstrustClientBinding, and wstrustClientSoapVersion. The sample application uses self-issued SAML tokens and does not need these properties; however, you do need these properties when you request SAML tokens from an external STS. Figure 13 shows the completed client general binding.
Figure 13. Sample Web services client binding
Figure 13. Sample Web services client binding

Configure the Web services provider

  1. To create general service bindings for the SAML bearer token (again, only if you choose not to import the samlbearerAssertionProvider binding example), perform these steps to copy and modify the Saml Bearer Provider sample:
    1. Log in to the administrative console.
    2. Select Services in the left navigation.
    3. Expand Policy sets and select General provider policy set bindings.
    4. In the General provider policy set bindings dialog, select Saml Bearer Provider sample, then click Copy from the collection table. Enter a name that you choose, for example, samlbearerAssertProvider.
    5. See the WebSphere Application Server Information Center to configure client and provider bindings for the SAML bearer token. Replace the property values of the token consumer custom callback trustStorePath and trustStorePassword properties to that of the cecipiens.jceks. Figure 14 shows the completed sample general bindings.
      Figure 14. Sample Web services provider binding
      Figure 14. Sample Web services provider binding
      The truststore configuration shown in Figure 14 corresponds to the first trust relationship verification point. The SAML token consumer will verify the SAML token issuer digital signature and signer certificate against the certificate in recipient.jceks.

      Perform the next step to configure the second trust relationship verification point. Be sure to configure Web service bindings to explicitly list a trusted SAML issuer and the corresponding certificate to ensure that SAML tokens with the specified certificate can only assert user credentials in the specified issuer security domain. In other words, the SAML token consumer will verify that the issuer name in received SAML tokens matches the configured trustedIssuer, while the issuer X.509 certificate owner name matches the configured trustedSubjectDN.

    6. Add a custom property, trustedIssuer_n, to define the trusted SAML issuer name and a custom property, trustedSubjectDN_n, to define the trusted X509Certificate (where _n is an integer beginning at 1, and is increased by 1 for each different issuer). Configure both trustedIssuer_ and trustedSubjectDN_ properties (although both are optional). If a trustedIssuer property is not specified, the token consumer will not verify the issuer name in SAML tokens. If a trustedSubjectDN property is not specified, the token consumer will not verify the owner field of the received issuer X.509 certificate. Figure 15 shows an example of bindings for trusted issuer configuration.
      Figure 15. Sample Web services provider binding with SAML token issuer verification
      Figure 15. Sample Web services provider binding with SAML token issuer verification
  2. Add additional trusted partners.

    You can add more trusted issuers by increasing integer n. For example, Figure 16 shows two trusted issuers. The postfix number _n must be contiguous. If you delete a pair of properties, such as trustedIssuer_m and trustedSubjectDN_m, you must move the entries from _m+1 to _n downward one position. Leaving a gap in the sequence can lead to token consumer process errors.

    Figure 16. Configuring an additional trusted foreign security domain
    Figure 16. Configuring an additional trusted foreign security domain
  3. Configure the Web service caller bindings for cross domain SAML ID assertion.

    Go to the Caller panel, click New, and add Caller identity local part to be the SAML token you choose as the caller token. In this example, you add http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0 as the Caller identity local part.

    1. Add the Callback handler as: com.ibm.websphere.wssecurity.callbackhandler.SAMLIdAssertionCallbackHandler.
    2. Add a Callback handler custom property crossDomainIdAssertion and set its value to true. When this property is not defined, the default Web services security runtime behavior is a local identity assertion which maps SAML token user identity to a user entry in the user registry of the current security domain. When crossDomainIdAssertion property is defined and set to true, Web services security will assert the SAML token user identity and group attributes to create a caller JAAS subject to represent the user. In the case of crossDomainIdAssertion, the Web services security runtime will not access the user registry of the current security domain.
    3. Optionally, add a Callback handler custom property groupName_n (where n is a positive integer incremented by 1) to specify the SAML attribute name. This property is most useful because SAML specifications do not define a standard attribute to represent group information.

      For example, if you want group memberships to be defined by AttributeName=SecretAuthorizationGroup, then add this custom property: groupName_1=SecretAuthorizationGroup. The Web services runtime will populate the caller WSCredential object group membership using the specified attribute value of received SAML tokens. For example, if you want group memberships to be defined by AttributeName and SecretAuthorizationGroup, then add this custom property: groupName_1=SecretAuthorizationGroup. If no groupMName_n property is defined, then the WebSphere Application Server Web services security implementation automatically scans these SAML attribute assertion names: "groups," "group," "memberof," "membership," "groupmembership," "members," "groupid," "role," "roles," and uses their attribute values as the credential’s group memberships.

    4. Optionally, add a Callback handler custom property principalName_n (where n is a positive integer increments by 1) to specify the SAML token attribute to use as the caller identity. For example, if you want to use attribute email as the principal of the caller, then add this custom property: principalName_1=email. When no principalName_n property is defined, the WebSphere Application Server Web services security implementation, by default, uses the SAML NameIdentifier assertion (for SAML 1.1), or NameId (for SAML 2.0) as the principal name of the caller. Be aware that principalName_n and groupName_n are organized together with trustedIssuer_n and trustedSubjectDN_n by the Web services security runtime. In other words, groupName_n and principalName_n, if defined, specify the identity and group attributes in SAML tokens that are issued by a specific issuer, trustedIssuer_n.

      Figure 17 shows caller binding for asserting SAML tokens.

      Figure 17. Sample Web services provider caller bindings with cross security domain settings
      Figure 17. Sample Web services provider caller bindings with cross security domain settings
  4. When you add additional trusted partners, you can define additional principal and group attribute mapping rules. As shown in Figure 18, the email attribute in SAML tokens that are issued by bigCorp.com are used as the user principal name when creating caller subjects.
    Figure 18. Defining an additional principal mapping rule
    Figure 18. Defining an additional principal mapping rule

Set up the applications

  1. Install the sample application on WebSphere Application Server.
  2. Unzip the sample keystore file to the directory etc\ws-security\samples, under the same profile where the sample application is installed. The keystore password is storepass, and the key password is keypass.
  3. Attach the SAML 2.0 Bearer WSHTTPS Default policy set, then attach the client bindings, samlbearerAssertionClient, and service bindings, samlbearerAssertProvider.
  4. Configure the authorization table and grant access to foreign users from a trusted domain:
    1. From the administrative console, click Enterprise applications, then click the appropriate EJB Web service application. This example uses the testEJBWSProviderApp application. Be sure the service EJB is protected with Java Platform, Enterprise Edition (Java EE) security. The testEJBWSProviderApp application is an EJB 3.0 application, and all EJB methods are protected with roles, which are defined with security annotations.
    2. Click Security role to user/group mapping. Assign roles to users and groups in trusted foreign realms. In this sample, the SayHelloUsers security role is defined to Alice in the acme.com realm as shown in Figure 19.
      Figure 19. Granting users and groups of foreign security domains access to Java EE resources
      Figure 19. Granting users and groups of foreign security domains access to Java EE resources

Run the sample federating Web services

  1. Start a browser session, and navigate to this URL: http://localhost:9080/testEJBWSClientWeb/testEJBWSBrowserClient.jsp.
  2. When a Form Login page is presented, type Alice as the user ID, and security as the password, and then, click Logon (Figure 20).
    Figure 20. Form based login page of the sample application
    Figure 20. Form based login page of the sample application
  3. Modify the EJB Service URL, which initially shows https://localhost:9443/testEJB_HTTPRouter/HelloBeanService, to match your installation (Figure 21). You need to specify the HTTPS port because the Saml Bearer WSHTTPS default policy set enforces SSL transport level message protection.
    Figure 21. Main service page of the sample application
    Figure 21. Main service page of the sample application
  4. In a successful cross-domain ID assertion, you will receive the response shown in Figure 22.
    Figure 22. Result page of the sample application
    Figure 22. Result page of the sample application

The Web services provider is protected by EJB security roles. The authorization configuration requires requesting users to be Alice in the acme.com foreign security domain. Getting the previous result indicates that assertion of SAML tokens has been successful.

Suppose you define another user, Tom, in the local user registry but do not grant Tom@acme.com to the authorization table. You should see the authorization error shown in Figure 23 when repeating the test login as Tom.

Figure 23. Foreign user was not granted authorization.
Figure 23. Foreign user was not granted authorization.

Federating Web services resources

Through the sample Web services application, you have learned how to assert SAML tokens across security domains and how to make access control decisions using the asserted foreign user identity and group membership data. This technology can be applied to federate Web services across enterprise boundaries for companies with business partner relationships. A typical enterprise environment uses an STS to issue security tokens to authorized users. Figure 24 shows a typical business scenario.

Figure 24. Web services federation usage scenarios
Figure 24. Web services federation usage scenarios

In this business scenario, Web client users (browsers) access business services through the company portal application hosted on WebSphere Application Server. When accessing business partner Web services, the portal application puts SAML tokens that represent the Web clients in security headers of Web services messages. The portal application can be configured to obtain authentication data from Web clients to authenticate to an STS to request SAML tokens for Web clients. WebSphere Application Server provides a trust client implementation of both WS-Trust 1.3 and WS-Trust 1.2 (DRAFT version) to integrate with an external STS. To authenticate to an STS, the portal application can prompt Web client users for authentication data. The portal application can maintain authentication sessions with Web clients after the initial authentication, and use client credentials to authenticate to the STS to request SAML tokens on behalf of clients.

Possible authentication methods include using identity assertion, using self-issued SAML tokens, and using client Kerberos credentials. Web clients that have already authenticated to a Kerberos server can authenticate to the portal application using their Kerberos credentials and delegate the portal server to use their Kerberos credentials to authenticate to the STS. The STS implementation must support Kerberos authentication. WebSphere Application Server can generate self-issued SAML tokens based on the user identity in the security context. The application server can use self-issued SAML tokens to authenticate to the STS on behalf of the client to request SAML tokens, provided that the particular STS supports that usage pattern. In the case of the IBM Tivoli® Federated Identity Manager STS, the portal application might also use LTPA tokens from users to authenticate to the Tivoli STS.

Figure 25 shows a diagram of a similar scenario in which Web services client users (Java clients) access business partner Web services directly. Web services clients authenticate to the STS to request SAML tokens. They might use user ID and password, Kerberos tokens, or X.509 client certificates, if the particular STS supports that type of authentication data.

Figure 25. Web services clients accessing federated Web services providers
Figure 25. Web services clients accessing federated Web services providers

To change the sample Web services client binding to use an external STS to issue SAML tokens, specify the STS endpoint URL, and the policy set and bindings to interact with the STS. An example of the binding configuration panel is shown in Figure 26.

Figure 26. Configuring a Web services client to use external STS for issuing SAML tokens
Figure 26. Configuring a Web services client to use external STS for issuing SAML tokens

Summary

You can use an SSO solution to assert SAML tokens across security domains using the SAML feature in IBM WebSphere Application Server V7.0 Fix Pack 7 and later releases. The combination of SAML assertions and the trusted authentication realm feature enables claim-based resource access control using user identity and group membership SAML assertions. The trust model and the three trust relationship verification points ensure the security and integrity of the system. A sample EJB 3.0 JAX-WS application was provided to demonstrate cross-security domain SAML assertions and claim-based access control. You can also apply the technology to federate Web services resources across enterprise security domains. The SSO solutions described in this article provide SSO convenience to Web application and Web services users with minimal identity management overhead to IT administrators.


Acknowledgements

The authors thank Huiran Wang for developing the EJB 3 JAX-WS sample application and Greg Truty, Hyen (Henry) Chung, Keys Botzum, and Martin Lansche for their many constructive comments.


Download

DescriptionNameSize
Code sampleSMLfederation_sample.zip52 KB

Resources

Learn

Get products and technologies

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into WebSphere on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=470591
ArticleTitle=SAML assertions across WebSphere Application Server security domains
publish-date=04142010