This project is read-only.
Project Description
.Net 3.51 and 4.0 Projects that implement SSO for SalesForce in a .Net 3.51 IIS6/7 and .Net4.0 - IIS7 environments for Web and Outlook SSO Login. Utilizes WCF for communication and authentication. Also includes SSO for SpringCM


Single Sign-on (SSO) with Sales Force and .Net 3.51/4.0 WCF
The following project is a working production code using Microsoft’s Windows Communication Foundation (WCF) to implement delegated SSO SalesForce.Com. This includes both the internal web SSO server and the authentication server.

If you are here you probably have attempted to use the example posted by SF here http://wiki.apexdevnet.com/index.php/How_to_Implement_Single_Sign-On_with_Salesforce.com and its repeated version in a PDF on their sites, you quickly realize the example its framework 1.1. Even if you have a copy of VS 2003 or upgrade it to VS 2005/2008, it still does not work.

Why? That’s because it is wrong..... (go figure)

Anyway, after much debugging of their site login page, (view source) I have the corrected code here as well as an implementation using WCF. Note that this is as of June 2009, If SF changes their implementation then this too could break.

If you are well on your way rewriting the 1.1 code before you got here and stuck, just look at the SSO_Login.aspx and you will see the corrected form post.

There are three projects
  1. SSO Login :Your Corporate Internal web site that calls SF which in turn calls SSOWebService. Users and Outlook call this IIS app
  2. SSO_WebService :Web Service on your external front end server(s) (FEs) used to receive the authenication call from SalesForce
  3. OutlookAddin used enable SSO from within outlook. (optional)

Note that the web services are hosted in IIS and are not WCF activation services.

Here is the flow:
  1. SSO_Login
    1. Is hosted internally on IIS6 / IIS 7 site in AD/NTLM network
    2. User links to http:/Webserver/SSOLogin/SFWebLogin.aspx_ with windows authenication
    3. SSO_Login determines user windows login and reformats or looks up user’s SalesForce user name.
      1. We used the same name in both systems so the example flips znetsys\Brucevb to the salesforce user account BruceVB@zNetSys.com
      2. You may require AD or SQL lookup to accomplish this or other means to perform the mapping.
      3. The web page also supports using a url parameter ?SFUser=JoesSFAccount if you want to go that way.
    4. A GUID is generated and used as the password or security token.
    5. The GUID is unique for this one login attempt
    6. User and password are set in the HTML form
    7. The username, GUID, password and timestamp are forwarded WCF style to SSO__WcfService.svc running on your FEs where it is added to a internal collection waiting for SF to call. Note that the SSO__WebService should be in the DMZ and not part of the NTLM/AD network. This call is therefore HTTP anonymous but secured by WCF.
    8. Form is then submitted posted to https://login.SalesForce.com (SF docs have the wrong login page)
    9. Session ends
  2. SalesForce receives the post from (8) above and calls your web service if
    1. You have delegated SSO Enabled in SF
    2. You have configured a SSO profile in SF for user in above
    3. That profile is assigned to the user logging in.
    4. You have configured the SSO link in SF Http://xyzCorp/SF_WebService.svc
      1. Https://naxxx.salesforce.com/_ui/system/security/SingleSignOnSettingsUi/d
  3. SSO_WebService
    1. SF Calls Authenticate on SF_WebService.svc
    2. User, Password (Guid) , IPAddress is passed to web method from SF.
      1. The calling host domain is verified as salesforce.com (actually it is proxy.sf.salesforce.com)
      2. IPAddress is verified to be in valid range.
      3. The password (GUID) and Guid are verified using the information passed to the service from the SSOLogin.aspx page
    3. Service returns true or false.


  1. The Outlookaddin tags on to this infrastructure by calling the SSOLogin application VIA netTcpBinding which performs the same process as above and returns the Guid to outlook as the password to be used by the Salesforce Outlook Connector. SF Outlook then logs in SSO Style. The addin works both in Outlook 2003 and Outlook 2007

Warning: The hardest part here is configuring the Web/App Config files and setting up IIs6 / IIS7. I had some issues that I could not resolve IIS6, WCF with {SSO_Login}. I have run the {SSO_WebService} in both IIS6 and IIS7 internally and in the DMZ. This code runs in our production environment and I have setup tracing manually and with Web Events and switches in the config files to help with debugging. However there is little room for error when it comes to configuration. I wrote the code and I can still get lost in the config files so map out those ports and IP addresses earily. Get it working in test before you try to go out to the DMZ

Also you may have noticed that there are no certificates used. They are not needed but the network should still restrict VIA ports and IP addresses as a compensating security measure.


Install Summary

Unzip and compile the two projects. ( Try the outlookaddin after you get the rest going)
I have these set up as web projects. There are no dependencies between the projects. It was built using .net 3.5 SP1, although It may be able to compile under .net 3.0 and VS2005 as it may not utilize and 3.5, but you may need to revert the sites to VS2005.
Let’s test locally….
SSO_WebService
  1. Publish/Pre-compile the {SSO_WService} web service.
  2. In IIS create a web site the {SSO_WService} that points the compile code
  3. Set up two bindings replacing app-dev2 (my test server) with your dev box
    1. app-dev2 8080
    2. app-dev2 8181
  4. We are testing our External Front end servers so the authentication should be set to anonymous on, Windows auth off in IIS. In the {SSO__WService} project examine the appSettings Section. There are two keys
    <!-- Test Entries -->
    <!--Address SSO_SSOLogin.aspx call  -->
    <add key="SSO_WcfService1" value="http://App-Dev2:8181/SSO_WcfService.svc" />
    <!-- Address that Sales Force WS will Call -->
    <add key="SF_WebService1" value="http://App-Dev2:8080/SF_WebService.svc" />

The {SSO_WcfService} (remove the 1) is the channel that your login page will call to forward the GUID
The {SF_WebService} (remove the 1) entry corresponds to the channel that Salesforce will call for authentication . This is the entry that would appear in the single Sign-on page. https://salesforce.com/_ui/system/security/SingleSignOnSettingsUi/d in SalesForce
Note that because your dev box is behind the firewall (or should be!!) SF cannot call the service but we can unit test anyway.

Publish the {SSO_WService} project again
In IE Key this url http://App-Dev2:8080/SF_WebService.svc and you should get the standard
You have created a service. 
To test this service, you will need to create 
a client and use it to call the service. You can do this using the 
svcutil.exe tool from the command line with the following syntax:
If you do not get an error then the service is operational.

SSO_Login
Now. In the {SSO_Login} project examine the appSettings Section. It’s cool but we need to go elsewhere to the AppData/SSOWcfServiceSrvs.xml which has something like this.

<WebServers>
  <Server Active="true">http://175.30.232.105:8181/SSOSF/SSO_WcfService.svc</Server>
  <Server Active="true">http://175.30.232.106:8181/SSOSF/SSO_WcfService.svc</Server>
  <Server Active="false">http://App-Dev1:8181/SSO_WcfService.svc</Server>
</WebServers>


Because we may have multiple FE servers to talk to, a single entry in the appSettings will not do. Here we set to Active the servers we wish to call from the login page. In our case it would be the this entry
{code:xml}
<Server Active="false">http://App-Dev1:8181/SSO_WcfService.svc</Server>
{code:xml}

That being said, if you only have one FE (Which means you a Single Point of Failure Single Sign-On (SPFSSO) you could just update the Endpoint entry in the web.config and comment out the C# loop per standard WCF.

Now Back to the appSettings, there are a few entries that allow you to set tracing and override the user logging in etc... But of interest now is this
    <!-- Test the SF Call to the web service-->
    <add key="TestSFWebServiceCall" value="true" />
    <!-- Test Address that Sales Force WS will Call-->
    <add key="SF_WebService" value="http://172.30.232.105:8080/SF_WebService.svc" />
Set TestSFWebServiceCall=true to call the authenticate method as SalesForce would so you can test some of the logic locally before you deployed to your FEs.

With trace running you can get a pretty good picture of what is happening via the event logs.

And if you got the above done without pulling your hair out, you were already are bald

Final

Now that you have it running in test. Deploy the SSO_WService to the FE Servers.


OutLook
the Outlook Addin is best understood you going through the code but it basically feeds the SalesForce plugin what it wants so that SSO occurs. The SF Docs are wrong and they way it is documented does not work. It is more marketing than an actual solution.



Last edited Sep 17, 2010 at 5:26 PM by bvanburen, version 29