Recipes by Category

App Distribution (2) Bundle logic, interface and services for distribution. App Logic (37) The Apex programming language, workflow and formulas for logic. Collaboration (6) The Salesforce Chatter collaboration platform. Database (29) Data persistence, reporting and analytics. Integration (33) Web Service APIs and toolkits for integration. Security (9) Platform, application and data security. Tools (4) Force.com tooling User Interface (36) Visualforce MVC and metadata-drive user interfaces. Web Sites (12) Public web sites and apps with optional user registration and login.
Beta Feedback
Cookbook Home » Enabling Single Sign-On with the Force.com Platform

Enabling Single Sign-On with the Force.com Platform

Post by Developer Force  (2010-07-16)

Status: Certified
Level: novice

Problem

You want to validate usernames and passwords for Salesforce.com against your corporate user database or another client application rather than having separate user passwords managed by Salesforce.com.

Solution

Salesforce.com offers two ways to use single sign-on:

Delegated Authentication

Use delegated authentication if you have mobile users in your organization, or if you want to enable single-sign on for partner portals or Customer Portals. You must request that this feature be enabled by salesforce.com. This recipe explains delegated authentication in more detail.

Federated Authentication using SAML

Federated authentication uses SAML, an industry standard for secure integrations. Investing in SAML with Salesforce.com can be leveraged with other products or services. If you use SAML, you don't have to expose an internal server to the Internet: the secure integration is done using the browser. In addition, Salesforce.com never handles any passwords used by your organization. For more information, see “Configuring SAML Settings for Single Sign-On” in the Salesforce.com online help.

When delegated authentication is enabled, salesforce.com does not validate a user's password. Instead, salesforce.com makes a Web services call to your organization to establish authentication credentials for the user.

When implementing delegated authentication, select one of the following security modes:

Simple passwords

Users directly provide passwords that the delegated authentication server evaluates. In this mode, users can also use the Salesforce.com login page and all of the Salesforce.com clients without modification or extra infrastructure.

Tokens

Instead of passwords, security tokens are provided, and the delegated authentication server evaluates these. This mode hides all passwords from Salesforce.com. Instead of a user signing onto a Salesforce.com login page, the user signs onto a private login page on your company's web server that may be behind your corporate firewall. In this mode, the user is authenticated on that private login page. When the user has been successfully authenticated, the user is redirected to the Salesforce.com login page and logged in using a single-use token. In this mode, users can't login directly to the Salesforce.com login page (users can't generate tokens), and they can't directly login using a client or mobile app. This recipe uses this mode.

Mixed

Your organization creates a delegated authentication server that can evaluate either tokens or passwords. This enables organizations to mobile and client apps, while still providing their users with a private login page.
Contact salesforce.com to enable delegated authentication for your organization if it is not already enabled.

To enable delegated authentication for your organization, build your delegated authentication Web service, and then configure your Salesforce.com organization to enable the Web service.

First, build your delegated authentication Web service:
  1. In Salesforce.com, click Setup | Develop | API | Download Delegated Authentication WSDL to download the Web Services Description Language (WSDL) file, AuthenticationService.wsdl.

    The WSDL describes the delegated authentication service and can be used to automatically generate a server-side stub to which you can add your specific implementation. For example, in the WSDL2Java tool from Apache Axis, you can use the --server-side switch. In the wsdl.exe tool from .NET, you can use the /server switch.

    A simple C# implementation of delegated authentication is shown below. The sample uses Microsoft .NET v1.1 and works with IIS6 on a Windows 2003 server. See wiki.developerforce.com/index.php/How_to_Implement_Single_Sign-On_with_Force.com for a more complex sample that demonstrates a solution using an authentication token.
    using System;
    using System.DirectoryServices;
    
    namespace samples.sforce.com
    {
    	/// <summary>  
        
    	/// This is a very basic implemention of an  
        
    	/// authentication service for illustration purposes.  
        
    	/// This sample should only be used  
        
    	/// with a HTTPS Delegated Gateway URL.  
        
    	/// It simply connects to your Active Directory  
        
    	/// server using the credentials that are passed in.  
        
    	/// If there is a bad username/password combination,  
        
    	/// it throws an exception and returns false;  
        
    	/// otherwise the credentials are ok  
        
    	/// and it returns true.  
        
    	/// Note that DirectoryEntry might not connect to  
        
    	/// Active Directory until we do something  
        
    	/// that actually requires it.  
        
    	/// That's why we read a property from the  
        
    	/// created DirectoryEntry object.  
        
    	/// </summary>  
        
    	public class SimpleAdAuth : System.Web.Services.WebService
    	{
    		[System.Web.Services.WebMethodAttribute()]
    		[System.Web.Services.Protocols.SoapDocumentMethodAttribute(
    			"",
    			RequestNamespace = "urn:authentication.soap.sforce.com",
    			ResponseElementName = "AuthenticateResult",
    			ResponseNamespace = "urn:authentication.soap.sforce.com",
    			Use = System.Web.Services.Description.SoapBindingUse.Literal,
    			ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
    		[return: System.Xml.Serialization.XmlElementAttribute("Authenticated")]
    		public bool Authenticate (
    			string username, string password, string sourceIp,
    			[System.Xml.Serialization.XmlAnyElementAttribute()] 
    				System.Xml.XmlElement[] Any)
    		{
    			if(username.IndexOf("@")==-1)
    				return false;
    
    			// Attempt to bind to an Active Directory entry.  
        
    			// This will authenticate the username and password.  
        
    			// TODO: you'll need to change this to match  
        
    			// your Active Directory name  
        
    			const string root = "LDAP://DC=sample,DC=org";
    			try
    			{
    				DirectoryEntry de
    					 = new DirectoryEntry(root, username, password);
    				// retrieve a property  
        
    				string tempName = de.Name;
    				return true;
    			}
    			catch(Exception)
    			{
    				return false;
    			}
    		}
    	}
    }
    
    As part of the delegated authentication process, a salesforce.com server makes a SOAP 1.1 request to authenticate the user who is passing in the credentials. An example of this type of request is shown below.
    <?xml version="1.0" encoding="UTF-8" ?> 
    <soapenv:Envelope 
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
     <soapenv:Body> 
       <Authenticate xmlns="urn:authentication.soap.sforce.com"> 
         <username>sampleuser@sample.org</username>  
         <password>myPassword99</password>  
         <sourceIp>1.2.3.4</sourceIp>  
       </Authenticate> 
     </soapenv:Body> 
    </soapenv:Envelope>
    
    Your delegated authentication service needs to accept this request, process it, and return a true or false response. A sample response is shown below.
    <?xml version="1.0" encoding="UTF-8"?> 
    <soapenv:Envelope 
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soapenv:Body> 
     <AuthenticateResponse 
    xmlns="urn:authentication.soap.sforce.com"> 
      <Authenticated>true</Authenticated> 
     </AuthenticateResponse> 
    </soapenv:Body> 
    </soapenv:Envelope>
  2. Add a link to your corporate intranet or other internally-accessible site that takes the authenticated user’s credentials and passes them using an HTTPS POST to the Salesforce.com login page. For security reasons, you should make your service available by SSL only. This ensures that a password, if it is included, is not sent unencrypted. You must use an SSL certificate from a trusted provider, such as Verisign or Thawte.

    Because Salesforce.com does not use the password field other than to pass it back to you, you do not need to send a password in this field. Instead, you could pass another authentication token, such as a Kerberos Ticket, so that your actual corporate passwords are not passed to or from Salesforce.com.

    You can configure the Salesforce.com-delegated authentication authority to allow only tokens, or to accept either tokens or passwords. If the authority only accepts tokens, a Salesforce.com user cannot log in to Salesforce.com directly, because they cannot create a valid token; however, many companies choose to allow both tokens and passwords. In this environment, a user can still log in to Salesforce.com through the login page.

    When the salesforce.com server passes these credentials back to you in the Authenticate message, verify them, and the user will gain access to the application.

Next, in Salesforce.com, specify your organization’s delegated authentication gateway URL by clicking Setup | Security Controls | Single Sign-On Settings | Edit. Enter the URL in the Delegated Gateway URL text box. For security reasons, Salesforce.com restricts the outbound ports you may specify to one of the following:
  • 80: This port only accepts HTTP connections.
  • 443: This port only accepts HTTPS connections.
  • 7000-10000 (inclusive): These ports accept HTTP or HTTPS connections.
For security reasons, you should make your service available by SSL only.

Finally, modify your user profiles to enable the Is Single Sign-On Enabled user permission. In Salesforce.com, click Setup | Manage Users | Profiles to add or edit profiles.

Discussion

The actual implementation of delegated authentication is transparent to users, but involves a number of steps behind the scenes. When you configure Salesforce.com for delegated authentication, you are allowing a delegated authority to control authentication. When a user first logs onto their network environment, they are initially authenticated by this authority. When the user attempts to log on to subsequent protected applications, instead of passing a username and password to the application, the user requests a token from a token generator. (On Windows, this token request can use the NTLM protocol.) The received token is passed to the application, which verifies that the token properly identifies the user, and then allows the user access to the application.

Salesforce.com can use this method, since the password field is simply used to exchange information with the client, rather than specifying a particular data type. This flexibility means that Salesforce.com can accept a token, which is then used with the delegated authentication authority to verify the user. If the verification succeeds, the user is logged on to Salesforce.com. If the verification fails, the user receives an error. The process flow for Salesforce.com delegated authentication is shown in the figure below.

Delegated Authentication Process Flow

Share

Recipe Activity - Please Log in to write a comment

Document is self explanatory but leaving behind few questions, seeking response on them.

1) Do we always required a Valid Salesforce user account to do delegated Authentication with token?

2) If i pass my salesforce user id in token and i did not send username separatly, will Salesforce be able to fetch the username from token and hence provide me the access to my account ?

3) Can a my intranet domain user without having any salesforce userid can be authenticated via delagated ?

Thanks

by Anil Kumar Singh  (2011-01-11)

X

Vote to Verify a Recipe

Verifying a recipe is a way to give feedback to others and broaden your own understanding of the capabilities on Force.com. When you verify a recipe, please make sure the code runs, and the functionality solves the articulated problem as expected.

Please make sure:
  • All the necessary pieces are mentioned
  • You have tested the recipe in practice
  • Have sent any suggestions for improvements to the author

Please Log in to verify a recipe

You have voted to verify this recipe.