Skip to main content

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

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

All information submitted is secure.

  • Close [x]

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.

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

All information submitted is secure.

  • Close [x]

developerWorks Community:

  • Close [x]

Use SAML assertions from an application server acting as an identity provider

Single sign-on to Salesforce.com using SAML 2

Arnab Ray (arnab.ray@in.ibm.com), Application Architect, IBM
Arnab Ray is an architect for a security project that includes SAML, 1- and 2-way SSL, and Kerberos authentication.

Summary:  With the advent of cloud computing, many companies rely on third-party service providers that reside outside their network. However, a company might want to integrate its existing single sign-on (SSO) feature with these service providers but perform authentication with their own identity provider. Security Assertion Markup Language (SAML) is the industry standard for identity propagation of an authenticated subject between a company's identity provider and a third-party service. In this article, learn how to enable SSO so an employee can log in to a third-party service provider using company credentials.

Date:  08 Jan 2013
Level:  Intermediate PDF:  A4 and Letter (1894 KB | 29 pages)Get Adobe® Reader®

Activity:  4228 views
Comments:  

Introduction

In this article, learn how to configure a company identity provider (IdP) to communicate with a third-party service provider, called Salesforce, to simplify single sign-on (SSO) for a company employee. The employee signs in once to the company IdP and can then seamlessly navigate to a Salesforce account home page without having to log in again.


SAML2 concepts and components

This section provides a brief description of the key SAML concepts and the components defined in the standard.

Frequently used abbreviations

  • ACS: Assertion Consumer Service
  • IdP: Identity Provider
  • SAML: Security Assertion Markup Language
  • SP: Service Provider
  • SSO: Single Sign-on

SAML exchanges take place between system entities called a SAML asserting party and a SAML relying party. SAML defines the roles of IdP for the party that authenticates the user and service provider (SP) for the party that relies on the IdP to get a user authenticated. The main aspect of most SAML assertions is a subject about which something is being asserted.

Figure 1 shows the basic SAML components that form the building blocks of SAML messages and configuration.


Figure 1. SAML components
4 boxes showing assertions, protocols, bindings, and profiles
Assertions
SAML allows one party to assert security information statements about a subject. An assertion contains basic required and optional information that applies to all assertions. It usually contains a subject of the assertion, conditions used to validate the assertion, and assertion statements. SAML defines three kinds of statements that can be carried within an assertion.
Protocols
SAML defines several generalized request/response protocols. For Salesforce integration, this article uses the Artifact Resolution Protocol.
Bindings
SAML bindings detail exactly how the various SAML protocol messages can be carried over underlying transport protocols. For Salesforce integration, this article uses the HTTP POST bindings.
Profiles
Profiles typically define constraints on the contents of SAML assertions, protocols, and bindings to solve the business use case in an interoperable fashion. For Salesforce integration, this article uses the Web Browser SSO Profile.
Metadata
Metadata defines a way to express and share configuration information between SAML parties. Configurations of either party can be exported to XML formats and used to register the relying party on the IdP's side, and the asserting party on the SP's side, by importing the XML information. For Salesforce integration, this article uses the metadata of Salesforce SAML2 configuration to set up an SP partner in the IdP.
Authentication context
Is used in, or referred to from, an assertion's authentication statement to carry detailed information about the type and strength of authentication a user employed when they were authenticated at an IdP. The access control on the SP's side could be influenced by this. Authentication context is not used in the Salesforce integration in this article.

Single sign-on to Salesforce

This section discusses, at a high level, the business case for Salesforce integration with a company IdP.

Assume that an employee has company-specific credentials to log in to the company's applications. The authentication process is governed in an IdP application, which provides an SSO feature so the employee can access all applications without having to log in every time. Integrating the SSO feature with Salesforce lets the employee access a Salesforce account without having to log in again to Salesforce. Effectively, the employee uses company credentials to log in to a third-party service (Salesforce).

IdP-initiated web browser SSO: POST bindings

Figure 2 shows the interactions among the end user (employee), the web browser, the IdP, and the SP.


Figure 2. IdP initiated SSO
Flowchart showing the interactions between the IdP, SP, and browser numbered 1-8 from right to left

The numbers in Figure 2 indicate:

  1. User attempts to log in to the company IdP and is challenged for credentials.
  2. User logs in with valid credentials. At this stage, the authentication context of the user is set.
  3. User accesses a web page of the IdP showing links of remote protected resources, one of which is Salesforce.
  4. The request is intercepted by the IdP's SSO service, which first sends a signed SAML2 assertion back to the browser.
  5. The IdP application has a simple JavaScript component that enables posting this assertion to the Assertion Consumer Service (ACS) on Salesforce's side.
  6. If the Salesforce ACS is satisfied with the assertion (which depends on how the SAML2 configuration on either side has been set up), it returns to the browser with a redirect to the protected resource.
  7. The browser then requests that resource.
  8. The resource is made available to the browser. Thus, the user is able to navigate to a Salesforce protected page without having to log in again with a Salesforce-specific username and password.

Setting up the environment

To prepare to configure a SAML2 IdP hosted on Weblogic 10.3.0 and a third-party SP (Salesforce), use the following steps.

Set up the IdP on the application server

To set up the IdP on Weblogic 10.3.0:

  1. In the configured security realm, create a new Credential Mapping entry under Providers, as in Figure 3, using saml2CMP as the Credential Mapping name.

    Figure 3. Create credential mapper
    Screen showing numerous tabs with Providers and Credential Mapping greyed out. The new entry is SAML2CMP.

  2. Ensure the details of the Credential Mapping entry are as shown in Figure 4.
    • The name of the Credential Mapping entry (saml2CMP) should be used for the Issuer URI as well. (This may not be a mandate, but let's experiment with it.)
    • The Key in this example is that of the DemoIdentity key in the DemoIdentity keystore shipped with this particular application server.


    Figure 4. Configure credential mapper
    Configure credential mapper fields completed

  3. Restart the server.
  4. Navigate to the server's Federation Services > Saml 2.0 Identity Provider, as in Figure 5.

    Figure 5. Navigate to SAML2 IdP
    Screen showing Configuration, Federated services, and SAML2.0 Identity provider greyed out.

  5. Enter details as shown in Figure 6.
    • Check the boxes for the Enabled, Only Accept Signed Authentication Requests, POST Binding Enabled, Redirect Binding Enabled, and Artifact Binding Enabled fields.
    • Choose POST as the Preferred Binding.
    • Use /saml2/idp/login as the Login URL.


    Figure 6. Configure SAML2 IdP
    Configure SAML2 IdP

  6. Navigate to the server's Federation Services > Saml 2.0 General and enter details, as shown in Figure 7.
    • The Entity ID should be the same as Issuer URI, in this case, saml2CMP.
    • The Published Site URL typically should be http://host:port/saml2, where host is the hostname by which the IdP site would be visible to all intended SPs. Keeping this as localhost keeps it from being visible to external SPs, such as Salesforce, and will impede in SP-initiated SSO. IdP initiated flows will work.


    Figure 7. Configure SAML2 General
    Configure SAML2 General Configure SAML2 General

  7. Click Publish Meta Data to save an XML containing the details of this IdP.

Configure Salesforce to validate SAML assertions

To configure the Salesforce SSO feature to validate SAML assertions:

  1. Create a Salesforce trial account and login ID. Navigate to Setup, as in Figure 8.

    Figure 8. Navigate to Salesforce account setup
    Screen showing an Arnab Ray drop-down and Setup selected from that.

  2. Select Security Controls > Single Sign-On Settings, as in Figure 9.

    Figure 9. Navigate to SSO settings
    Single sign-on selected under the Security Controls drop-down.

  3. Edit SAML2 data as follows.
    • Keytool export command on alias DemoIdentity results in a .crt certificate. Import this to the IE certificate store and then export as DER (.cer) certificate. This will be required in the Identity Provider Certificate field.
    • Issuer should match the Entity ID (mentioned while setting up IdP), in this case, saml2CMP.
    Figure 10 shows an example.

    Figure 10. Edit SAML2 settings
    Edit SAML2 Settings

  4. Select Save and Download Metadata, as in Figure 11.

    Figure 11. Salesforce metadata
    Salesforce metadata button selected in the screen shot.

Define Salesforce as SP partner to the IdP

To define Salesforce as an SP to the Weblogic IdP:

  1. In the IdP, navigate to the configured credential mapper's Management tab and create a New Web SSO service provider partner, as in Figure 12.

    Figure 12. Create SP partner
    New Web SSO service provider partner selected under the New drop-down list.

  2. Edit the details, using the metadata file downloaded from Salesforce, as in Figure 13.

    Figure 13. Edit SP partner
    Edit SP Partner

  3. From the Management tab again, click the newly created SP partner and enter the Salesforce-specific SP partner details, as in Figure 14.

Define users and groups at the IdP

In this section, you define users and groups in the IdP that will define the valid set of users who will be authenticated. In the example, the DefaultAuthenticator of Weblogic will do the authentication. In a real-world scenario, the set of users could be maintained in an Active Directory (and you would need to configure an LDAPAuthenticator to authenticate a user).

  1. Navigate to Security realms > myrealm > Users and Groups and click the Groups tab. Create a new group called users, as in Figure 16.

    Figure 16. Create group
    Create group

  2. Click the Users tab and create a user by your Salesforce username, as in Figure 17.

    Figure 17. Create user
    Create User

  3. Edit the details of the user, as follows.
    • In the General tab: Give a description of this user (optional).
    • In the Passwords tab: Set a password (the password does not need to be the same as the Salesforce password).
    • In the Groups tab: Add the users group to this user.
    Figure 18 shows an example.

    Figure 18. Subscribe user to group
    Subscribe User To Group


The Identity Provider application

This section explores a simple web application that authenticates a user and initiates SSO to Salesforce. The contents include:

  • index.jsp, which is an unprotected page.
  • services.jsp, which contains the links to different remote resources of various SPs, including Salesforce. Listing 1 shows an example.
    • http://<Idp host>:<Idp port>/saml2/idp/sso/initiator is the SSO service on IdP's side. Each click action should post to this URL.
    • The service recognizes two parameters:
      • SPName, which should match the SP partner name configured in IdP.
      • RequestURL, which should contain the protected resource of the SP that is being requested.


    Listing 1. services.jsp
    			
    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    	           pageEncoding="ISO-8859-1"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    			"http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Insert title here</title>
    </head>
    <body>
    
    <form method="post" action="http://localhost:8001/saml2/idp/sso/initiator">
    <br>Service - 1 (at localhost:9001/appB)<br>
    <input type="hidden" name="SPName" value="sp1"/>
    <input type="hidden" name="RequestURL" 
    	value="http://localhost:9001/appB/protected/restricted.jsp"/>
    <input type="submit" value="submit"/>
    </form>
    
    <form method="post" action="http://localhost:8001/saml2/idp/sso/initiator">
    <br>Service - 2 (at Salesforce)<br>
    <input type="hidden" name="SPName" value="sp2"/>
    <input type="hidden" name="RequestURL" value="https://login.salesforce.com"/>
    <input type="submit" value="submit"/>
    </form>
    
    </body>
    </html>
    			

  • post_sp2.jsp, as shown in Listing 2.

    The name of the JSP matches the POST binding post form mentioned for the given SP partner (see the SP partner in IdP in Figure 14). The SSO service, after generating the SAML2 response, sets the same to the SAMLResponse hidden field. The original protected resource that was requested is set in the RelayState field.

    The JSP submits on load to post these details to the ACS endpoint of the concerned SP partner.



    Listing 2. post_sp2.jsp
    			
    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
        pageEncoding="ISO-8859-1"%>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
    	"http://www.w3.org/TR/html4/loose.dtd">
    
    <html>
    <head></head>
    
    <%
    String samlResponse = (String) request.getAttribute
       ("com.bea.security.saml2.samlContent");
    String relayState = (String) request.getAttribute
       ("com.bea.security.saml2.relayState");
    System.out.println(samlResponse);
    System.out.println(relayState);
    %>
    
    <body onLoad="document.forms[0].submit();">
    <FORM METHOD="POST" ACTION="https://login.salesforce.com">
    <INPUT TYPE="HIDDEN" NAME="RelayState" VALUE="<%=relayState%>"/>
    <INPUT TYPE="HIDDEN" NAME="SAMLResponse" VALUE="<%=samlResponse%>">
    </FORM>
    </body>
    </html>
    	

  • web.xml, as shown in Listing 3.

    Except for index.jsp, all other JSPs are protected. It's good for an authentication context to be set by the time the user reaches services.jsp so it can be used by the SSO service of the IdP.

    The roles and security constraints are in tandem with the users and groups that were set up in the IdP.



    Listing 3. web.xml
    			
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    		http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
    id="WebApp_ID" version="2.5">
    
    	<display-name>appA</display-name>
    	<welcome-file-list>
    		<welcome-file>index.jsp</welcome-file>
    	</welcome-file-list>
    
    	<security-constraint>
    		<web-resource-collection>
    			<web-resource-name>protected</web-resource-name>
    			<url-pattern>services.jsp</url-pattern>
    			<url-pattern>post_sp2.jsp</url-pattern>
    		</web-resource-collection>
    	 <auth-constraint>
    		<role-name>valid-users</role-name>
    	 </auth-constraint>
    	</security-constraint>
    	<login-config>
    		<auth-method>BASIC</auth-method>
    		<realm-name>myrealm</realm-name>
    	</login-config>
    	<security-role>
    		<role-name>valid-users</role-name>
    	</security-role>
    </web-app>
    			

  • Application server-specific deployment xml (weblogic.xml)

    As shown in Listing 4, in the security realm you need a group called users. Users subscribed to that group are able to access the protected pages of the IdP application. This was already accounted for in previous steps.



    Listing 4. weblogic.xml
    			
    <?xml version="1.0" encoding="UTF-8"?><wls:weblogic-web-app
    xmlns:wls="http://www.bea.com/ns/weblogic/weblogic-web-app"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.bea.com/ns/weblogic/weblogic-web-app
    http://www.bea.com/ns/weblogic/weblogic-web-app/1.0/weblogic-web-app.xsd
    http://java.sun.com/xml/ns/javaee
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
        <wls:weblogic-version>10.3</wls:weblogic-version>
        <wls:context-root>appA</wls:context-root>
        <wls:security-role-assignment>
                  <wls:role-name>valid-users</wls:role-name>
                  <wls:principal-name>users</wls:principal-name>
           </wls:security-role-assignment>
    </wls:weblogic-web-app>			
    			
    			


Demonstration

This section shows the entire process: An employee signs in to the company IdP using a company-specific credential and navigates to an account in a third-party SP without having to log in again. You'll see the eight-step scenario described in Figure 2, which shows the interactions among the end user, the web browser, the IdP, and the SP.

Sign in to IdP

First, the employee signs in to the company's IdP.

  1. AppA is the Identity Provider application deployed in localhost:8001, as shown in Figure 19.

    Figure 19. Request index.jsp
    Request Index.jsp

  2. AppA's services.jsp is a protected page. Attempting to access this page results in the application challenging for user credentials, as in Figure 20.

    Figure 20. Request services.jsp
    Request Services.jsp

    This relates to Step 1, Challenge for credential, in Figure 2.

  3. Successful authentication sets the authentication context in the IdP, as in Figure 21. AppA's services.jsp has links (buttons) to navigate to different SPs registered with this IdP. The SPs could be within network or external (like Salesforce).

    Figure 21. Response after IdP authentication
    Response after IdP authentication

    This relates to Step 2, User login, in Figure 2.

SSO to service provider

The employee can now navigate to his SP account home page without having to log in again.

Clicking on the Salesforce-specific submit button results in SSO to Salesforce, as in Figure 22.


Figure 22. SSO to Salesforce
SSO to Salesforce

The SSO relates to multiple steps from Figure 2, as follows.

Step 3: Select remote resource (by clicking on Salesforce-specific button).

Step 4: Signed SAML2 response. The SSO service, sso/initiator, sends the SAML2 assertion to the browser with a redirect code and URL. The assertion resides in the HTML body and is discussed in the next section.

Step 5: Post signed response. The browser redirects to the URL, which is that of the SP's ACS. The ACS is able to parse and validate the SAML2 assertion.

Step 6: Redirect to resource. After successful validation, ACS sends the redirect code and the URL to a browser. The URL is the original remote resource—the Salesforce account home page—to which the user wanted to navigate. It was passed from the SSO service to the ACS in a field called RelayState in the same HTML body that carried the SAML2 assertion.

Steps 7 and 8: The browser requests this resource and renders it.

SAML2 communication from IdP to SP

Now, a bit more about the assertion (SAMLResponse) and the original remote resource (RelayState) values sent by the IdP to the SP.

  1. Use the Firebug Firefox add-on (or equivalent) to capture the Base 64-encoded SAML2 response. The relaystate value is in plain text in Figure 23. It carries the URL corresponding to the Salesforce account home page.

    Figure 23. SAML2 encoded response
    SAML2 Encoded Response

  2. Perform a Base 64 decoding of the SAML2 response, as in Listing 5. You can download a sample Java™ program to do this.

Listing 5. SAML2 response from the IdP
			
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
Destination="https://login.salesforce.com" ID="_0xf08a42e0ff2fd317bd0d571396867446"
IssueInstant="2012-10-15T10:36:36.437Z" Version="2.0">
  <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">saml2CMP</saml:Issuer>
  <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:SignedInfo>
      <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
      <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
      <ds:Reference URI="#_0xf08a42e0ff2fd317bd0d571396867446">
        <ds:Transforms>
          <ds:Transform
            Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
            <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#WithComments">
            <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"
	      PrefixList="ds saml samlp xs xsi" />
          </ds:Transform>
        </ds:Transforms>
        <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
          <ds:DigestValue>Nl2w+aNCkEB5/ic4xT/bfX3FibZZcph6SUFRKpM/USQ=
          </ds:DigestValue>
       </ds:Reference>
    </ds:SignedInfo>
    <ds:SignatureValue>
	tsPmzJTolL4EGXZ7JJ3mFYWm1NRDQ6JbYda4QmUepwf1symh+onyJLUfypZuGiqoA2nhrW0Ucqj4
	M2wLsvKTkQ==
    </ds:SignatureValue>
  </ds:Signature>
  <samlp:Status>
    <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
  </samlp:Status>
  <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
    ID="_0xe9a8fb1b3602cb25c8f9e40b86459999" 
    IssueInstant="2012-10-15T10:36:35.187Z"
    Version="2.0">
    <saml:Issuer>saml2CMP</saml:Issuer>
    <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <ds:SignedInfo>
        <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
        <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
        <ds:Reference URI="#_0xe9a8fb1b3602cb25c8f9e40b86459999">
          <ds:Transforms>
            <ds:Transform
	      Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
            <ds:Transform
	      Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#WithComments">
	      <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"
                PrefixList="ds saml xs" />
            </ds:Transform>
          </ds:Transforms>
          <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
          <ds:DigestValue>WR9aoKICupHcjhKvTOTqJU8VjVXyPt4xAvLJM3gP7+Q=
          </ds:DigestValue>
        </ds:Reference>
      </ds:SignedInfo>
      <ds:SignatureValue>
	gr6yNHREAbeXlhUedvKBlDN1l2tAeytnKAcd+1m4dPAR2ilpP1bZ41UsSKjePMJgEdnMYPhi7UGu
	Y0GgT2/uPg==
      </ds:SignatureValue>
      <ds:KeyInfo>
        <ds:X509Data>
          <ds:X509Certificate>
	MIIB6TCCAZMCEBu0kyfhfu/FtvtEXsOdFjcwDQYJKoZIhvcNAQEEBQAweTELMAkGA1UEBhMCVVMx
	EDAOBgNVBAgTB015U3RhdGUxDzANBgNVBAcTBk15VG93bjEXMBUGA1UEChMOTXlPcmdhbml6YXRp
	b24xGTAXBgNVBAsTEEZPUiBURVNUSU5HIE9OTFkxEzARBgNVBAMTCkNlcnRHZW5DQUIwHhcNMTIw
	ODE0MDcxMzIyWhcNMjcwODE1MDcxMzIyWjB3MQswCQYDVQQGEwJVUzEQMA4GA1UECBYHTXlTdGF0
	ZTEPMA0GA1UEBxYGTXlUb3duMRcwFQYDVQQKFg5NeU9yZ2FuaXphdGlvbjEZMBcGA1UECxYQRk9S
	IFRFU1RJTkcgT05MWTERMA8GA1UEAxYIYXJuYXJheTUwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA
	yrXrz9ms71c9XhB8WVL8HnsNdtOuhdAJSyI3bxwsUrOzkH7+92Hif76e8A/dCBABAM8oW9+G5rqj
	1tBYJl+0FwIDAQABMA0GCSqGSIb3DQEBBAUAA0EAbQm+0iTRK98rHqLtSyfm/Jf63t0wBGu3lhfU
	P9Z84H70EPpFg0Ks/tgn9f66yo3vV8Tk4K1pSACjiZ4U+IAR6w==
           </ds:X509Certificate>
         </ds:X509Data>
       </ds:KeyInfo>
     </ds:Signature>
     <saml:Subject>
       <saml:NameID Format="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
         NameQualifier="www.whitehorses.nl">[My Salesforce username]</saml:NameID>
       <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
         <saml:SubjectConfirmationData
           NotOnOrAfter="2012-10-15T10:38:30.187Z"
		   Recipient="https://login.salesforce.com" />
       </saml:SubjectConfirmation>
     </saml:Subject>
     <saml:Conditions NotBefore="2012-10-15T10:36:30.187Z"
       NotOnOrAfter="2012-10-15T10:38:30.187Z">
       <saml:AudienceRestriction>
         <saml:Audience>https://saml.salesforce.com</saml:Audience>
       </saml:AudienceRestriction>
     </saml:Conditions>
     <saml:AuthnStatement AuthnInstant="2012-10-15T10:36:35.187Z">
       <saml:AuthnContext>
         <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified
         </saml:AuthnContextClassRef>
       </saml:AuthnContext>
     </saml:AuthnStatement>
     <saml:AttributeStatement>
       <saml:Attribute Name="Groups"
         NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
         <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		   xsi:type="xs:string">users
         </saml:AttributeValue>
       </saml:Attribute>
     </saml:AttributeStatement>
  </saml:Assertion>
</samlp:Response>	
			

The SAML2 constructs are detailed in Table 1.


Table 1. SAML2 constructs
ConstructValueAttributesRequiredRemarks
ResponseDestination="https://login.salesforce.com"
IssueInstant="YYYY-MM-DDTHH24:MI:SS.SSSZ"
Version="2.0"
Y
Issuersaml2CMPY
Signature[Abstracted, depends on the certificate used. Some of these have encrypted values.][Abstracted, depends on the certificate used. Some of these have encrypted attribute values.]N
SignedInfo
CanonicalizationMethod
SignatureMethod
Reference
Transforms
Transform
DigestMethod
DigestValue
SignatureValue
StatusY
StatusCodeValue="urn:oasis:names:tc:SAML:2.0:status:Success"Y
AssertionID=[generated ID]
IssueInstant="YYYY-MM-DDTHH24:MI:SS.SSSZ"
Version="2.0"
Y
Issuersaml2CMPY
Signature[Abstracted, depends on the certificate used. Some of these have encrypted values.][Abstracted, depends on the certificate used. Some of these have encrypted attribute values.]YA valid signature must be included in the assertion. It must be created using the private key associated with the certificate that was provided in the SAML2 configuration in Salesforce.
SignedInfo
CanonicalizationMethod
SignatureMethod
Reference
Transforms
Transform
DigestMethod
DigestValue
SignatureValue
KeyInfo
X509Data
X509Certificate
SubjectY
NameID[Salesforce username of Logged on Principal]Format="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
NameQualifier="www.whitehorses.nl"
Y
SubjectConfirmationMethod="urn:oasis:names:tc:SAML:2.0:cm:bearer"Y
SubjectConfirmationDataNotOnOrAfter="YYYY-MM-DDTHH24:MI:SS.SSSZ"
Recipient="https://login.salesforce.com"
YThe recipient specified in an assertion must match either the Salesforce login URL specified in the Salesforce configuration or the OAuth 2.0 token endpoint.
ConditionsNotBefore="YYYY-MM-DDTHH24:MI:SS.SSSZ"
NotOnOrAfter="YYYY-MM-DDTHH24:MI:SS.SSSZ"
YThe NotBefore and NotOnOrAfter constraints must also be defined and valid
AudienceRestrictionY
Audiencehttps://saml.salesforce.comY
AuthnStatementAuthnInstant="YYYY-MM-DDTHH24:MI:SS.SSSZ"Y
AuthnContextY
AuthnContextClassRefurn:oasis:names:tc:SAML:2.0:ac:classes:unspecifiedY

Custom implementations

In most real-world scenarios, the end user's username inside the company will be different from that in Salesforce. This section shows a simple example that maps and sets the Salesforce-specific username in the NameID field in the assertion. To enable such advanced mapping, you need to use a custom class in the Name Mapper Class Name field (which is currently blank, as shown in Figure 4).

  1. Write a custom class. Listing 6 shows an example.

    Listing 6. MyNameMapper.java
    					
    package sample.providers.saml;
    
    import java.util.HashSet;
    import java.util.Set;
    import javax.security.auth.Subject;
    import com.bea.security.saml2.providers.SAML2CredentialNameMapper;
    import com.bea.security.saml2.providers.SAML2NameMapperInfo;
    import weblogic.security.SubjectUtils;
    import weblogic.security.service.ContextHandler;
    import weblogic.security.spi.WLSGroup;
    
    public class MyNameMapper implements SAML2CredentialNameMapper {
    
           private static final long serialVersionUID = 1L;
           private String nameQualifier = null;
    
           private String getSalesForceName(String arg0) {
                  // this should ideally bring the Salesforce specific
                  // username from a back-end service
                  return "<My Salesforce username>";
           }
    
           @Override
           public SAML2NameMapperInfo mapName(String arg0, ContextHandler arg1) {
                  return new SAML2NameMapperInfo(nameQualifier, arg0, null);
           }
    
           @Override
           public SAML2NameMapperInfo mapSubject(Subject arg0, ContextHandler arg1) {
                  Set<WLSGroup> groups = arg0.getPrincipals(WLSGroup.class);
                  Set<String> groupNames = new HashSet<String>();
                  for (WLSGroup group : groups) {
                         groupNames.add(group.getName());
                  }
    
    			  String userName = SubjectUtils.getUsername(arg0);
    
                  if (userName == null || userName.equals("")) {
                         System.out.println("Username string is null " +
                                      "or empty, returning null");
                         return null;
                  }
    			  return new SAML2NameMapperInfo(nameQualifier,
    					getSalesForceName(userName), groupNames);
           }
    
           @Override
           public void setNameQualifier(String arg0) {
                  this.nameQualifier = arg0;
           }
    }
    			

    The getSalesForceName method is introduced to fetch the Salesforce username based on the company username. In a real scenario, the underlying user data store is expected to contain an attribute for Salesforce username for every user. For simplicity in this example, a hardcoded Salesforce username is returned without accessing any datastore.

    The mapSubject method has been overridden to enable the mapping of a different NameID. It is called by the SAML2CredentialMapper. The company username is obtained from the Subject that had been populated upon successful authentication into the IdP. The method then calls getSalesForceName to get the appropriate Salesforce username for this company user.

  2. Export the custom implementation as a JAR file and place it in the application server classpath.
    • Keeping this JAR file in >%DOMAIN%/lib will not work. It needs to be in the server's classpath.
    • Keep the JAR file in any appropriate location and edit %WL_HOME%/common/bin/commEnv.cmd (or commEnv.sh). Append the location of the JAR file as follows:

      set WEBLOGIC_CLASSPATH=........;[absolute path to the jar]

    • Restart the server.
  3. Open the IdP admin console and navigate to myRealm > Providers > Credential Mapper > samlCMP. Edit the Name Mapper Class Name attribute in the IdP settings with sample.providers.saml.MyNameMapper, as in Figure 24.

    Figure 24. Custom Name Mapper
    Custom Name Mapper

  4. If not already created, create a new user called valid-users in the IdP subscribing to group users.
  5. Repeat the demonstration steps, but this time log in to the IdP using the new user valid-users.
  6. Clicking the Salesforce specific button creates a SAML2 assertion, with [my salesforce username] in NameId instead of valid-users, eventually resulting in a successful single sign on.

Conclusion

In the article, you learned to create the minimum necessary configuration to enable a weblogic server-based IdP to enable SSO so an employee can log in to Salesforce using company credentials. SAML was used to enable this SSO feature.


Resources

Learn

Get products and technologies

  • Evaluation software: Download a trial version, work with a product in an online, sandbox environment, or access it in the cloud.

Discuss

  • developerWorks community: Connect with other developerWorks users while exploring the developer-driven blogs, forums, groups, and wikis.

About the author

Arnab Ray is an architect for a security project that includes SAML, 1- and 2-way SSL, and Kerberos authentication.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


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. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

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.

(Must be between 3 – 31 characters.)

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

 


Rate this article

Comments

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Security
ArticleID=854079
ArticleTitle=Use SAML assertions from an application server acting as an identity provider
publish-date=01082013