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.
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: - 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>
- 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.
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
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