Introduction Single Sign-On is a process that allows network users to access all authorized network resources without having to separately log in to each resource. Single Sign-On also gives your organization the ability to integrate with an external identity management system or perform web based single sign on to Force.com.
How Single Sign-On Works The high-level process for authenticating users via Single Sign-On is as follows: 1. When a user tries to log in—either online or using the API—Salesforce validates the username and checks the user’s profile settings. 2. If the user’s profile has the "Uses Single Sign-on" user permission, then Salesforce does not authenticate the username with the password. Instead, a Web Services call is made to the user’s single sign-on service, asking it to validate the username and password. 3. The Web Services call passes the username, password, and sourceIp to a Web Service defined for your organization. (sourceIp is the IP address that originated the login request). You must create and deploy an implementation of the Web Service that can be accessed by Salesforce.com servers. 4. Your implementation of the Web Service validates the passed information and returns either "true" or "false." 5. If the response is "true," then the login process continues, a new session is generated, and the user proceeds to the application. If "false" is returned, then the user is informed that his or her username and password combination was invalid.
Enabling Single Sign-On
1. Contact Salesforce.com to turn on Single Sign-On for your organization. 2. Build your SSO Web Service: Download the Web Services Description Language (WSDL) file, AuthenticationService.wsdl, that describes the Single Sign-On service. It can be used to automatically generate a server-side stub to which you can add your specific implementation. You can download the file from Setup | Develop | API | Download Delegated Authentication WSDL. The file should be saved in web directory of symfony project.
3. In Salesforce, specify your organization’s Single Sign-On Gateway URL by clicking Setup | Security Controls | Single Sign On Settings.
4. Modify your user profiles to contain the "Uses Single Sign-On" user permission. In Salesforce, click Setup | Manage Users | Profiles to add or edit profiles. It is recommended you create a new user with a new profile to test single sign on. Do not test with the administrator account.
Token Generation You can use any string as a token. But to make it secure you have to follow some encryption and decryption mechanisms. Symfony uses a plugin dwCrypt which will provide encryption and decrption functions. For the plugin to work, Mcrypt package need to be installed which in turn requires libmcrypt2.5.8 and mhash0.9.9 packages. The installation procedure is given below: 1. Download and install libmcrypt2.5.8 Libmcrypt 2. Download and install mhash0.9.9 MHash 3. Download and install mcrypt2.6.7 MCrypt 4. Enable mcrypt package for php. 5. Install dwCrypt plugin for symfony symfony plugin-install http://plugins.symfony-project.org/dwCryptPlugin Implementation
I.Specify a link in your intranet page which map to an action which submits SSO request to salesforce.
SalesForce II.Submit SSO Request The above url route to this action. 1.Create a function in action class to send the SSO request to salesforce. The function should contain the following codes
$this->username = sales_force_username; $this->token = $this->generateToken($this->username); $this->logoutURL = the_url_that_should_appear_after_logging_out_from_salesforce $this->startURL = sales_force_home_url_after_logging_in; $this->ssoStartPage = "http://my_intranet.com/logintosalesforce"; 2.Generate token
public function generateToken($username) { $cryptService = new sfCrypt(); $token = $cryptService->encrypt($username); return $token; } 3.Submit Form The form should submit username and token to salesforce. The following code describes the template
{$result} {literal} {/literal} II. Get the soap request from salesforce. Salesforce will contact the web service in the gateway URL with a SOAP request when the form is submitted.Suppose the gateway url is 'http://my_intranet.com/WebService.php. The code for WebService.php is given below,
define('SF_ROOT_DIR', realpath(dirname(__FILE__).'/..')); define('SF_APP', 'symfony_application_name'); define('SF_ENVIRONMENT', 'soap'); define('SF_DEBUG', true); require_once(SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.SF_APP.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php'); ini_set("soap.wsdl_cache_enabled", "0"); $server = new SoapServer(sfConfig::get('AuthenticationService.wsdl')); $server->setClass("myWebServiceController"); $server->handle(); ?> Notice that the file should reside in web directory myWebServiceController.class.php should be written in symfony_project/apps/symfony_app_name/lib directory.
class myWebServiceController extends sfController { public $request; /** * Function to initialize SOAP request * * @return void */ public function __construct() { $this->context = sfContext::getInstance(); $this->request = $this->context->getRequest(); } /** * The function handles soap request. It first parses the request. * The user will be logged in if the * response is true and will not be logged in if an exception is caught. * * @param Object $soapRequest - The soap request object * * @return array */ function Authenticate($soapRequest) { /** This loop parses the incoming request and stores the username and token in an array*/ foreach ($soapRequest as $key=>$value) { $loginInfo[$key] = $value; } try { /** You can add validation for the incoming token here. The variable $loginInfo['password'] will give the token in the request. To authenticate the user you have to set the Authenticated parameter to true */ return array("Authenticated"=>'true'); } catch (Exception $e) { throw new SoapFault("1", $e->getMessage()); } } } If Authenticate is set to true, user become authenticated and can see the home page for logged-in users of salesforce.com for more details please visit the article by my friend Rajeev: http://raajeevam.blogspot.com/
How Single Sign-On Works The high-level process for authenticating users via Single Sign-On is as follows: 1. When a user tries to log in—either online or using the API—Salesforce validates the username and checks the user’s profile settings. 2. If the user’s profile has the "Uses Single Sign-on" user permission, then Salesforce does not authenticate the username with the password. Instead, a Web Services call is made to the user’s single sign-on service, asking it to validate the username and password. 3. The Web Services call passes the username, password, and sourceIp to a Web Service defined for your organization. (sourceIp is the IP address that originated the login request). You must create and deploy an implementation of the Web Service that can be accessed by Salesforce.com servers. 4. Your implementation of the Web Service validates the passed information and returns either "true" or "false." 5. If the response is "true," then the login process continues, a new session is generated, and the user proceeds to the application. If "false" is returned, then the user is informed that his or her username and password combination was invalid.
Enabling Single Sign-On
1. Contact Salesforce.com to turn on Single Sign-On for your organization. 2. Build your SSO Web Service: Download the Web Services Description Language (WSDL) file, AuthenticationService.wsdl, that describes the Single Sign-On service. It can be used to automatically generate a server-side stub to which you can add your specific implementation. You can download the file from Setup | Develop | API | Download Delegated Authentication WSDL. The file should be saved in web directory of symfony project.
3. In Salesforce, specify your organization’s Single Sign-On Gateway URL by clicking Setup | Security Controls | Single Sign On Settings.
4. Modify your user profiles to contain the "Uses Single Sign-On" user permission. In Salesforce, click Setup | Manage Users | Profiles to add or edit profiles. It is recommended you create a new user with a new profile to test single sign on. Do not test with the administrator account.
Token Generation You can use any string as a token. But to make it secure you have to follow some encryption and decryption mechanisms. Symfony uses a plugin dwCrypt which will provide encryption and decrption functions. For the plugin to work, Mcrypt package need to be installed which in turn requires libmcrypt2.5.8 and mhash0.9.9 packages. The installation procedure is given below: 1. Download and install libmcrypt2.5.8 Libmcrypt 2. Download and install mhash0.9.9 MHash 3. Download and install mcrypt2.6.7 MCrypt 4. Enable mcrypt package for php. 5. Install dwCrypt plugin for symfony symfony plugin-install http://plugins.symfony-project.org/dwCryptPlugin Implementation
I.Specify a link in your intranet page which map to an action which submits SSO request to salesforce.
SalesForce II.Submit SSO Request The above url route to this action. 1.Create a function in action class to send the SSO request to salesforce. The function should contain the following codes
$this->username = sales_force_username; $this->token = $this->generateToken($this->username); $this->logoutURL = the_url_that_should_appear_after_logging_out_from_salesforce $this->startURL = sales_force_home_url_after_logging_in; $this->ssoStartPage = "http://my_intranet.com/logintosalesforce"; 2.Generate token
public function generateToken($username) { $cryptService = new sfCrypt(); $token = $cryptService->encrypt($username); return $token; } 3.Submit Form The form should submit username and token to salesforce. The following code describes the template
{$result} {literal} {/literal} II. Get the soap request from salesforce. Salesforce will contact the web service in the gateway URL with a SOAP request when the form is submitted.Suppose the gateway url is 'http://my_intranet.com/WebService.php. The code for WebService.php is given below,
define('SF_ROOT_DIR', realpath(dirname(__FILE__).'/..')); define('SF_APP', 'symfony_application_name'); define('SF_ENVIRONMENT', 'soap'); define('SF_DEBUG', true); require_once(SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.SF_APP.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php'); ini_set("soap.wsdl_cache_enabled", "0"); $server = new SoapServer(sfConfig::get('AuthenticationService.wsdl')); $server->setClass("myWebServiceController"); $server->handle(); ?> Notice that the file should reside in web directory myWebServiceController.class.php should be written in symfony_project/apps/symfony_app_name/lib directory.
class myWebServiceController extends sfController { public $request; /** * Function to initialize SOAP request * * @return void */ public function __construct() { $this->context = sfContext::getInstance(); $this->request = $this->context->getRequest(); } /** * The function handles soap request. It first parses the request. * The user will be logged in if the * response is true and will not be logged in if an exception is caught. * * @param Object $soapRequest - The soap request object * * @return array */ function Authenticate($soapRequest) { /** This loop parses the incoming request and stores the username and token in an array*/ foreach ($soapRequest as $key=>$value) { $loginInfo[$key] = $value; } try { /** You can add validation for the incoming token here. The variable $loginInfo['password'] will give the token in the request. To authenticate the user you have to set the Authenticated parameter to true */ return array("Authenticated"=>'true'); } catch (Exception $e) { throw new SoapFault("1", $e->getMessage()); } } } If Authenticate is set to true, user become authenticated and can see the home page for logged-in users of salesforce.com for more details please visit the article by my friend Rajeev: http://raajeevam.blogspot.com/