Main

SalesForce SSO with ADFS 2.0 – Everything you need to Know

-14/01/2013 – Workaround for iPads and SSO!
Rohan writes to tell us that:

“If you activate Touch in your Org and set touch to be used for Browser access then an iPad will via Safari use the mobile touch interface. You’ll need to have http redirect set, and (As below) you are limited to the touch “app” so no chatter app or dashboards app.
That said, dashboards are meant to be coming to touch shortly so perhaps touch via the browser is enough.”

Cheers Rohan!

– 15/10/2012 – ADFS 2.0 / SalesForce + iPad/Safari Working!SalesForce have added a new option to change the SAML binding method from HTTP POST to HTTP REDIRECT. Using HTTP REDIRECT seems to fix the issue with ipad/Safari and ADFS 2.0. You can find this in the SSO settings.

Intro

In my last post I went over the basic concept of federation using SAML 2.0, today I’ll show you how to configure single sign-on for SalesForce using ADFS 2.0. This is a really nice solution because it’s easy to set up and doesn’t cost you anything except the Windows 2008 OS licence.

ADFS 2.0 is Microsoft’s answer to federation – it includes their own implementation of SAML 2.0. It runs on Windows Server 2008 [R2] and is installed from a separate downloadable package. It is not the ADFS ‘role’ which can be enabled in Windows Server 2008 R2, that’s ADFS 1.0 (not cool).

If you don’t feel you have a good grasp of SAML 2.0 I suggest that you set up ADFS 2.0 (as IdP) and Shibboleth (as SP) in a lab environment. There’s no better way to learn about a particular technology than to interface Microsoft’s implementation with its open source counterpart! There’s a great MSDN blog post that walks you through the set up. I really learnt a lot by doing this.

Overview

Let’s first take a look at an overview of the process then we’ll dive into the configuration. The diagram below shows the process for an IdP-initiated login into SalesForce – later we’ll look at SP-initiated login.

The user authenticates to the ADFS server using Kerberos and requests login to SalesForce

ADFS returns a SAML assertion to the user’s browser

The browser automatically submits the assertion to SalesForce who logs the user in

Install

Start with Windows Server 2008 [R2] – Domain Joined

Create a friendly DNS name for ADFS and point it to your adfs server. e.g adfs.testzone.local

Download and install ADFS 2.0. Federation Server role. This will install all pre-requisites

In the IIS manager create an SSL certificate for your friendly DNS name or use SelfSSL from the IIS 6.0 resource kit to create a self-signed certificate

Run through the ADFS Server configuration wizard

Create a new federation Service

Stand-alone server

Select the certificate that you created for your friendly DNS name

Create an SPN for the DNS name so that Kerberos authentication between the browser and the ADFS IIS instance works correctly

Configuration

To build a federation between two parties we need to establish a trust by exchanging some metadata. The metadata for our ADFS 2.0 instance is entered manually into the SalesForce configuration. SalesForce metadata is downloaded as an XML file which ADFS 2.0 can consume.

SalesForce Configuration

In the ADFS 2.0 MMC snap-in select the certificates node and double click the token-signing certificate to view it.

Go to details and “Copy to File”. Save the certificate in DER format.

On the ADFS server browse to your federation metadata URL which can be found in the ADFS MMC\Endpoints|Metadata|Type:Federation Metadata. In my case: https://adfs.testzone.local/FederationMetadata/2007-06/FederationMetadata.xml

Identity Provider Login URL:This is the URL of your ADFS SAML endpoint where SalesForce will send SAML requests for SP-initiated login. This can be found inADFS MMC\Endpoints|Token Issuance|Type:SAML 2.0/WS-Federation(In my case: https://adfs.testzone.local/adfs/ls/)

SAML User ID Type:To log a user on we can either match against their SalesForce username or we can match against their federation ID which would need to be populated in the profile of every user. For testing select federation ID. If your users currently use their email address as their SalesForce username then when you come to roll out SSO into production you can switch to sending the username.

SAML User ID Location:To log the user on we can either use the NameID in the SAML assertion or we can use some other attribute. NameID should suffice.

Entity ID: This is how our ADFS IdP will identify the SalesForce SP. I just left it as https://saml.salesforce.com. If you were supporting multiple SalesForce instances from the same ADFS instance then you’d want to use the more unique name. This is also the identifier we use when we do a IdP-initiated login with ADFS

Save the settings and download the Metadata xml file.

ADFS 2.0 Configuration

Now that we have the metadata for SalesForce we can create the trust on the ADFS side.

Open the ADFS 2.0 MMC snapin and add a new “Relying Party Trust”:

Select Data Source: Import data about a relying party from a file. Browse to the XML you downloaded from SalesForce

Display Name:Give the trust a display name e.g. ‘SalesForce Sandbox’

Choose Issuance Authorization Rules: Permit all users to access this relying party

Open Edit Claim Rues Dialog:Ticked

In the claim rules editor select the “Issuance Transform Rules” tab

Add a new rule:

Claim Rule Template: Send LDAP Attributes as Claims

Claim Rule Name: For testing we’ll send the UPN as NameID so call the rule: “Send UPN as NameID” In production you might send the user’s email address or employee ID *

With IdP-initiated login you would typically set up a link on the company intranet that users would click to get access to SalesForce. SP-initiated login happens when a user clicks a direct link to SalesForce. For this to work we need to set the secure hash algorithm to SHA1 instead of the default SHA-256. This is set in SalesForce relying party trust properties under advanced.

If you don’t set this you’ll get the following message in to the ADFS event log:

Event ID: 378

SAML request is not signed with expected signature algorithm. SAML request is signed with signature algorithm http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 . Expected signature algorithm is http://www.w3.org/2000/09/xmldsig#rsa-sha1

With My Domain

It’s best practice to implement the “My Domain” feature at the same time as implementing SSO if you haven’t already done so. “My Domain” gives you your own subdomain on SalesForce. e.g. MyCompany.my.salesforce.com. When you click a “My Domain” link SalesForce will know to redirect you to your Idp (ADFS) to be authenticated.

Without My Domain

As long as the user has performed at least one IdP-initated login from a given browser SalesForce will have set a cookie so in future it knows to redirect the browser to the IdP with a SAML request. The IdP will in turn issue a SAML response for the browser to pass back to SalesForce.

You might find some SalesForce documentation that mentions the ssoStartPage attribute which can be set in the SAML assertion. I found that this wasn’t necessary, and if you look at the cookie you get after an IdP-initiated login you’ll see that ssoStartPage is set to the IdP login URL you specified in the SalesForce SSO configuration.

LogoutURL

You can specify a URL to redirect to when the user logs out by creating a custom claim rule which sends an additional logoutURL attribute.

This should redirect you and sign you into SalesForce. If you get a SalesForce login error use the SAML assertion validator tool on the SalesForce single sign-on configuration page. It will display the results of the last failed SAML login.

If you get an error from ADFS then check the ADFS logs in Server Manager\Diagnostics\Applications and Services Logs\ADFS 2.0\Admin. There is also a very good MSDN blog post on ADFS 2.0 diagnostics.

Once you have IdP-initiated login working try SP-initiated. Copy a link from deep inside SalesForce then log out. Reload your browser and paste the in the URL. You should be seamlessly redirected to your IdP, authenticated and then redirected back to the link you requested.

Portal SSO and JIT Provisioning

There’s plenty of good info in the Force.com literature for portal SSO and just-in-time provisioning but here’s some ADFS 2.0 specific stuff. I’ve only been playing with this for a couple of weeks but I’ve had requests for the info so here’s what I’ve got so far. Let me know if I’ve missed something or I’ve got something wrong.

Portal SSO

To do a Portal SSO login you need to send the portal ID and the Org ID as claims using custom claims rules. There is significant caveat though, if you’re using ADFS to do SSO for both full-License and portal users. If you send the Portal ID and the Org ID for a full-license user SalesForce will assume you are trying to log into a portal. This will result in a SAML error because a full-license user can’t also be a portal user. To overcome this you can use a condition in the custom rule so the portal ID and Org ID are only sent if the user is a member of a given Active Directory group. The rules below use the AD group SID which you can find using pstool psgetsid.exe. The advantage of using an SID is that if the group is renamed the SID stays the same.

I haven’t found a way to send send a claim only if a user is not a member of a group, and the ADFS 2.0 claims rules language reference is non-existent! If someone works this out please let me know.

JIT Provisioning

Just-in-time provisioning allows you to create users on the fly with a SAML assertion as they attempt to login. All you need to do is enable JIT in your SSO settings and then send the required attributes. JIT custom claims rules are just like the portal ones above. The SalesForce Single Sign-On Implementation Guide has all the details on what attrbiutes to need to be sent. Here’s a few things to keep in mind:

You can provision and update users into specific profiles or rolls based on Active Directory groups just like with the portal logins above, but you’ll need to manage the AD groups carefully – you couldn’t have a user in multiple groups which represent different SalesForce profiles or rolls

You can provision and update users but you can’t un-provision them. Again you’ll need to use Active directory security groups to determine who can be JIT provisioned and you’ll have to manage your licensees and account De-activations outside JIT

I found that I couldn’t JIT provision users if chatter wasn’t enabled – still waiting for the word on this from SalesForce

Further Analysis

In case you’re wondering how the browser collects and passes these SAML requests and responses around, we’ll take a closer look at the entire process.

We’ll go over the SP-Initiated login because it has the most steps and really demonstrates SAML and federation at its best. I’ll use screen shots of Fiddler2 to show you exactly what’s happening at each step.

Note* Fiddler messes with Windows integrated authentication to IIS so you’ll need to turn off extended protection on the /adfs/ls/ virtual directory if you want to try this. Otherwise your browser won’t authenticate with ADFS and you’ll see event 4625 with error 0xc000035b in the Windows security log on the ADFS server.

Step 1

The user clicks a direct link to a SalesForce page. The browser connects and SalesForce reads the ssoStartPage attribute from the user’s cookie. SalesForce uses JavaScript to redirect the browser to the SalesForce SAML request generator. The SAML request generator creates a SAML request for the IdP by sending an invisible HTML form with hidden fields back to the browser. It then uses JavaScript to automatically submit the form to the IdP SAML endpoint.

Step 2

The browser submits the HTML form which contains the SAML request to the ADFS SAML endpoint. Since we are using Windows integrated authentication, ADFS redirects the browser to the /auth/ingetrated/ directory at which point a 401 (User must authenticate) is sent. Finally, the user is authenticated using Kerberos and ADFS serves up a SAML response. Again, the SAML message is returned to the browser in an HTML form which is then submitted to the SalesForce SAML endpoint using JavaScript.

Step 3

The browser submits the HTML form which contains the SAML response to the SalesForce SAML endpoint which verifies the SAML assertion, logs the user in and redirects the browser to the original requested URL.

Common Issues & Troubleshooting

Here are some of the issues you might com across. Thanks to everyone who has commented and shared their experience – I’ll keep updating this section.

Federation ID is case sensitive
One thing to watch out for is the Federation ID is case-sensitive. So if this is your organizational email, be sure to enter it exactly as AD FS sends it, or Salesforce won’t be able to find the matching user.

I’ve looked into writing a custom claim rule to normalize the case the lase of the LDAP attribute before sending it but it looks like it’s not possible the claims language doesn’t seem to have any string manipulation except a basic regex replace.

Assertion Expired
An assertion’s timestamp is more than five minutes old.
Note: Salesforce does make an allowance of three minutes for clock skew. This means, in practice, that an
assertion can be as much as eight minutes passed the timestamp time, or three minutes before it. This amount
of time may be less if the assertion’s validity period is less than five minutes.

So make sure your clock as sync’d to a good internet time source.

Preventing Users Using Their old Username/Password

It doesn’t seem to be possible to prevent users from logging in using the standard method which is a bit of a pain. There is an idea you can promote here to get this feature implemented:

Conclusion

Well that’s it! Everything you need to know about SalesForce WebSSO with ADFS 2.0.

Federation is really cool, so make sure you encourage its use in your organisation instead of older methods involving clunky tightly coupled links and horrible things like allowing your cloud vendor to do LDAP authentication against your domain controllers over VPNs etc!

Thanks for reading and please ask questions, make comments and corrections. I’ll continue to update this post as we go.

Updates

2011/07/30

Added JIT and Portal SSO info

Updated SP-initiated login with “My Domain” info – Thanks to Pat over at SalesForce for helping out this this

Wonderful items from you, man. I have bee aware your stuff previous to and you’re just
too great. I actually like what you’ve obtained
right here, certainly like what you are stating and thee best way by which you assert it.
You make it entertaining and you still take care of to keep it smart.
I can’t wait to learn much more from you. That is really a great
web site.

Ԍreat goods from you, man. I have underѕtand your stuff prevgious to and you’re just too magnificent.
I reslly like ѡhat you’ve ɑcquіred here, certainly like what you are saying and the way in which you say it.
You makoe it enjoyable and yoou still care for to keep it sensible.

I cant wait to гeɑd much more from you. Tһis iis actually a wonderful web site.

I have been exploring for a little bit for any high-quality articles or weblog posts
on this kind of area . Exploring in Yahoo I eventually
stumbled upon this site. Reading this information So i’m
glad to express that I have an incredibly excellent uncanny feeling I came upon just what
I needed. I such a lot no doubt will make sure to do
not put out of your mind this site and provides it a look regularly.

Having read this I believed it was extremely enlightening.
I appreciate you finding the time and effort to put this information together.
I once again find myself spending a lot of time both reading and commenting.
But so what, it was still worthwhile!

RhysGoodwin – Thanks for the post! We are implementing SSO through OKTA. At this point we have a pretty good understanding of the technology side – we’re now trying to think through the provisioning side from a logistics standpoint.

I think ideally we would like to have AD groups identified that would correspond to Salesforce Roles and Profiles. The challenge I see with this is that when you have 50-100 Roles (which have advantages for reporting in Salesforce), that seems like it could get out of hand from an AD group perspective (a group being a unique combination of Role and Profile, right?). Also, if a Salesforce Role were to change (or if we add or remove a Role), what is the process for this? Is it manual intervention on both sides?

A few options I’m thinking:

1. Leave Complex Role structure in Salesforce, fully map OKTA provisioning to these combinations
Pros: Fully automated user provisioning, no additional role/profile intervention needed by users
Cons: Maintenance burden to create all these groups and keep them in sync. Choosing the AD groups might be confusing as there will be a ton

2. Leave Complex Role structure in Salesforce, partially map OKTA provisioning to generic combinations
Pros: Semi-automated provisioning. Users can “get to work” right away with the right security permissions through semi-generic profiles and roles.
Cons: Requires manual intervention by users in Salesforce

3. Simplify the Roles in Salesforce, fully map OKTA provisioning to these combinations
Pros: Fully automated user provisioning, no additional role/profile intervention needed by users
Cons: Loss of some reporting capabilities using the “My Teams” options. Thinking that we would try to leverage the “Manager” field for more complexity, but it’s not ideal and we lose the full “My Teams” function

4. Leave Complex Role structure in Salesforce, do not map OKTA provisioning to any combination (or maybe just Profile and not Roles)
Pros: No maintenance needed for AD groups
Cons: Users will essentially be non-functional in Salesforce until their Role and Profile is defined in Salesforce manually (puts a delay in usable access). Requires manual intervention by users in Salesforce

Would love to hear your thoughts on this from a best practice perspective. And if I’m missing a silver bullet or another option, please let me know. Apologies if you covered in the comments above – I did a find on “Role” and didn’t see anything applicable to this.

Hi Dave,
A few thoughts:
You can never have too many AD groups. As long they are well organised, have good naming conventions, descriptions etc.

I don’t think there is a right or wrong way to do this, or at least there are multiple right ways of doing things. It really comes down to where you want your enforcement points to be and that comes down to a number of factors including company policy, administrative processes, segregation of duties, audit-ability etc. Also depends how often you are making changes on the SalesForce side. In any case I would look to implement some kind of automated synchronization. I haven’t really looked into anything salesforce related for a while as I’m not really working with it at the moment. Perhaps they have some tools or APIs that would be appropriate.

I think you’ll find that the most common scenario is to use AD for initial authentication/authorization but then have all the fine-grained authorization managed within SalesForce. And I think that’s typical with many enterprise apps. Of course in this case you can’t audit access in a single place. Nor can you administer user access in a single place.

With regards to “manual intervention on both sides”. Yes unless you do some kind of synchronization.

Yes, it’s good to have confirmation that there isn’t a silver bullet I’m not thinking about and that it’s common to use essentially option 2 unless there are special circumstances (e.g. company policy, etc.) that would change this.

A standard feature of ADFS is to auto-generate a new certificate before the old one expires. Salesforce does not appear to have functionality to detect this and download the new certificate automatically. Another part of the problem was that we knew the certificate expired August 11th, but not that ADFS would generate a new certificate automatically and start using that 20 days in advance.

This SSO issue will be occurred next year when the current certificate expires.
My question is why SF not detected/downloaded the new certificate automatically.
If any option/workaround is available in SFDC, please provide me the your suggestions.

When the electricity is passed a friction is created and thereby heat.
In the cross over or perhaps soften step, the main width within the attach
heightens even though the peak on the flight journey will reduce.
If you are seeking for the best ways to find biodegradable plastic extruders to get custom products for
your company, contact Hall manufacturing.

Have you come across a situation where ADFS has primary and secondary certificates. Would salesforce be able to be configured to authenticate against the secondary cert while the primary is still active i.e. has not yet expired?

I would imagine this is a standard practice to manage primary and secondary certs onADFS to manage migration / grace failover, but not sure if Salesforce can authenticate against the secondary cert while the primary is still active (from testing perspective at least)?

Hi Sushil,
As far as I know this isn’t possible but it’s been a while since I’ve looked at the features on the SFDC side. The way this stuff is supposed to work is that both parties can always access each others metadata so can always retrieve the latest certificate etc. but I’ve never seen that is practice. Cheers, Rhys

if any user try to login to Salesforce through SSO ,He/She successfully login as “Standard User” as i mention in UserProfileId Rule .But when we change user profile from “Standard User” to some else like “Marketing Manager” ; from Salesforce Admin console ,When the same user login to his Salesforce account ,it again reverted to “Standard User”.

We are having an issue with our Federation ID and AD returns both cases randomly. One week it will be in all Caps then the next week it will be in Mix Case. We can not find a reason why we would be getting different case at different times. We have to change the users to match for it to work. What we do not understand is why it would ever change.

That’s very odd. I’d suggest querying the UPN on different domain controllers to see if they return different cases. I don’t believe it’s possible to normalize the case with a claims rule. You could re-write the attribute on every user object to lower case but if you do I’d suggest changing the value in the process. I.e –

Obviously ripping through your entire directory with a script is not to be taken lightly. Use at your own risk!
I’d be keen to hear how you get on if you find out anything else. I’m not sure why SFDC need to do a case match .

My company is using ADFS to log in into Salesforce and it’s working fine in Android phones and Windows machines. but I don’t know why , when we try to log in using Safari or Salesforce1 app from iOS devices, we’re getting ” An error occurred. Contact your administrator for more information” error message.

The most weird thing about this is that if we press the “back” button on Safari, it redirects to Salesforce, even after we receive this error. The main issue here is that Salesforce1 app for iOS doesn’t have this “back” button to “force” the logon, lol.

Could you tell me what we’re doing wrong? I google it a lot but i still haven’t luck until now.

Pls tell me how to create subject “Name ID” element for ADFS SAML. we always got all the claim values as
“AttributeStatement” . Do you know how to set in ADFS SAML subject element set the particular field ?

We are looking into having multiple IDPs in one ORG, so actually multiple companies in one ORG.
How can we make sure an admin of company A doesn’t gues a username or e-mailaddress for SAML assertion of company B and is with this method able to login to access data of the other company.
Can we bind users to an IDP or add an extra claim which checks on shared secret? So we can be sure a hacking admin can’t access data of another company?

Hello Rhys Goodwin’s…..Thanks for this helpful post….. i have successfully implemented this Salesforce SSO with ADFS, but i am not able to do JIT provisioning. So can you please email me ADFS steps to configure this??

The login via NTLM is seamless for the Internet Browsers (from the Internal network) from the domain joined computers.
Using Internet Browser (from the Internal network) on Android phone I get basic authentication prompt and after entering user name and password I get access to Salesforce. So, that works fine as per design.

The only issue I have is when I attempt to login to Salesforce with SalesForce1 App on Android (from the Internal Network) then I get “401 – Unauthorized: Access is denied”.

I will put wireshark on the server and take a look at the traffic as you suggested.

Hi Rhys,
First I would like to thank your for these instructions. It helped me very much when setting up our ADFS and Salesforce SSO.
We have one ADFS server on the Internal Network and one ADFS Proxy Server in DMZ.
ADFS server (Anonymous and Windows Authentication enabled (NTLM Provider Only))
ADFS proxy server (Anonymous and Forms Authentication enabled)

SSO works fine using the Internet Browsers ( IE, Chrome and FireFox) from the Internal Network and from the Internet. But, I have one issue with Salesforce1 mobile app that I am unable to resolve.

When the SalesForce1 App connects from the Internal Wireless Network to the ADFS server then user gets an error “401 – Unauthorized: Access is denied”.
SSO works fine when the SalesForce1 App connects from the Internet to the ADFS Proxy server.
Any idea?
Regards,
Zoran

Hi Zoran, I don’t have any experience with the SalesForce1 app. For internal browsers is the login via NTLM seamless? I.e no login form or popup? That is. Windows passes the token of the currently logged in user? If that’s the case then I wouldn’t expect the mobile app to be able to do that because the mobile device is not domain joined. (Assuming Android or ios). So how does the app request the credentials from the user and how does it pass them to the adfs server? I would try to enable basic authentication as well as Windows authentication. Failing that I’d put wireshark on the server and take a look at the traffic on the wire. Let me know if you want a hand.

Hi Zoran,
Did you find any resolution for
I am also looking for any workaround/resolution for “401 – Unauthorized: Access is denied” Please let me know if there is any way to use ADFS with salesforce 1 app.
FYI->when i contacted salesforce support they told me that pop up login screen(ADFS) for Single Sign on is not going to be supported by the Salesforce1 App. You are going to have to have a forms based login page as your landing page for Single Sign on.
The following is a document around our Single Sign on best practices:

With AD FS in Windows Server 2012 R2, you can specify on the internal network which browser clients are allowed to use Integrated Windows Authentication (IWA) for transparent logon. This is done by modifying the supported user agents via the following cmdlet.
Set-ADFSProperties –WIASupportedUserAgents

Where “Mozilla/5.0 (Windows” will let Chrome and Firefox use WIA on any Windows PC and Windows Mobile Device. If you use Chrome, Firefox or Saleforce1 on non-windows device then the forms authentication is always used .

Please check this post if you are don’t have ADFS on Windows Server 2012 R2:

I’m no longer positive the place you’re getting your info, but great
topic. I needs to spend a while studying more or understanding more.
Thank you for excellent information I used to
be searching for this info for my mission.

Put items up for auction within the late afternoon EST when individuals are getting home
inside US but still up in Europe. Looking in the replay of these
US goal, it really looks worse and worse. And as there are our food – we may nurture it,
lead it to grow better us, allow it to be more easily obtainable to us, even bio-engineer it, but it is the sun’s energy that actually makes it grow.

Hello! This is my first comment here so I just wanted to give
a quick shout out and say I genuinely enjoy reading through your posts.
Can you recommend any other blogs/websites/forums that deal with the same topics?
Thanks!

Very nice post. I just stumbled upon your weblog and
wanted to say that I’ve really enjoyed surfing around your blog posts.
In any case I will be subscribing to your rss feed and I hope you write again soon!

First of all, thank you for sharing first-hand experience. This article nicely explains SSO with ADFS 2.0 scenario, specially for the novice developers who are in the initial stages of implementation. We’re planning to implementing SSO with ADFS 2.0 in one of our products, we have few basic queries. It would be great if you could shed some light on the following:

1) Consider the scenario where user authenticates himself with ADFS once in the morning when he logons to his workstation.
For IdP-Initiated SSO, when user tries to access application URL (on first login attempt & also on subsequent login attempts) how does the IdP know which user it is supposed to authenticate? Is there any difference in the way this is handled during the first login attempt & on subsequent login attempts. Also, because in IdP-initiated authentication, we don’t pass any SAML Request hence there is no provision of passing user creds.

2) Further, after receiving SAML response assertions, on application side do we explcitly need to set any assertions in cookie so that on subsequent login attempts the application can explicitly pass this cookie info to IdP for the IdP to know whom to authenticat? Or is ADFS equipped enough to drop the authentication cookie (on first authentication attempt) & retrive it (on subsequent attempts) behind the scenes?

3) Do the above scenarios work in similar fashion for SP-Initiated authentication, because unlike IdP here we have the provision of passing SAMLRequest, hence we can choose the parameters that needs to be sent to IdP.

Hi, I’m trying to use the free developer edition (http://developer.force.com/) of and setup a demo SAML Idp for testing with my ADFS 2.0 + SP. So far I’ve managed to enabled SAML support, and created a connected app. Everything works relatively well right up to login. After login, I’m redirected back to my ADFS but I’m facing following error

Failed to process the Web request because the request is not valid. Cannot get protocol message from HTTP query. The following errors occurred when trying to parse incoming HTTP request:

Microsoft.IdentityServer.Protocols.Saml.HttpSamlMessageException: MSIS7015: This request does not contain the expected protocol message or incorrect protocol parameters were found according to the HTTP SAML protocol bindings.

Hi, Thanks for getting back to me, when you say SAML 1.1 instead of 2.0, which setting are you referring to? In the ADFS or salesforce? The only thing I’ve set relates to SAML 1.1 is the Name ID Format urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress in salesforce.

I’ve also tried both
urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
urn:oasis:names:tc:SAML:2.0:nameid-format:transient

Oh sorry I was confused. You’re wanting to set up SalesForce as the Idp. And ADFS 2.0 as the SP. Sorry I haven’t had any experience with this. This article is about setting up ADFS 2.0 as the Idp and with SalesForce as the SP. I.e. Allowing Active directory users to Single-Sign-On to SalesForce.

I am following your steps to the T, and yet cannot get the authentication working with adfs 2.0. Am sure I am making some very basic mistake. Everytime I try to login, I get error 273 as the event code.

I understand that JIT allow you to create an account/ID in your AD and then automatically create an account in Salesforce. Will it possible to reverse certain accounts that are not needed in Salesforce?

Also, do you have any guide on setting up JIT like how to configure the attribute? I am very new and I not sure how to proceed.

My primary concern with this is that if I log into salesforce using the ADFS direction, log out of salesforce, and then go to the ADFS site again it will log back in immediately without prompting for creds. Do you know if theres a way to disable that auto login?

Are you referring to the seamless login (WIA) which happens between internet explorer and the ADFS server for domain joined PCs?
One way to address this might be to enable FBA (Forms based Authentication) on ADFS this way users will be prompted for a username/password. You do of course loose the benefit of seamless login but you can’t have it both ways 🙂

I appreciate the fast response! From what I can tell, it looks like that would be a universal change on the ADFS server and cant be done per trust, right? I think that might bust up the O365 config that already exists on that server.
Ah well, it’s not a huge deal, I just wanted to address the apparent security concerns of someone being able to walk up to another person’s computer, click on their salesforce link, and then sign in as that person automatically. But personally I don’t think its a problem :).

Agree. It’s a feature not a bug! There is a simple solution – the user should lock their workstation when they walk away. I guess there may be a valid argument for a very sensitive applications but in most cases SFDC or o365 wouldn’t fall into that category IMO.

Since the start, it has seemed that Sony has always had the one up on Microsoft in terms
or console performance, architecture and pure grunt.
It’s important not to search for exactly the same title when researching completed prices, particularly if
the item has something like a model or serial number in the title,
just search for the most obvious search phrase. World of Warcraft: Created by Blizzard Entertainment, World of Warcraft is a real-time
multi-player game.

As such, the service provider acquires this information
in lease or some contract thus ensuring a profit.
Most organizations use the method of cell phone tracking by SMS to locate the whereabouts of their employees.
Despite the transparency of the world wide web, looking for these details does not undermine your
personal information.

Another potential method has been revealed in regards to fixing a save bug from the recently-released ‘Pokemon X’
and ‘Pokemon Y’ video games on the Nintendo 3DS.
As far back as 2008, Katherine was publicly discussing her battle
with quitting after attracting negative press when she was constantly.
Froakie’s evolution will be pure Water-type, and will
learn the move Bounce.

But we have multiple sandboxes in Salesforce and we append the sandbox name to the email address (as our user name) to log into the specific sandbox. So for a sandbox called “test”, we log in using our email address with “.test” appended to it. I’ve tried all day to get the “.test” appended to the email address, but can figure it out. I was hoping you’d know of a simple solution. Any help would be greatly appreciated!

My next problem is I have another external hosted application that my users would like to access from a link within SalesForce. The problem is when the users click the link within SalesForce to the other hosted external app, they have to log in again.

The other external hosted application has an SAML assertion consumer endpoint.

How should I get SalesForce, the other hosted app, and my ADFS server talking?

It should be just a matter of setting up a new relying party in ADFS 2.0 for the other application. That way when your users click the link they will be signed in via ADFS in just the same way they are for SalesForce.

I’ve been working in the configuration of a Single Sign-On between Salesforce and ADFs and I’ve found SO USEFUL your blog. Many more than the Salesforce’s documentacion! So first of all, thanks for your help with this topic 🙂

I am writing to you because I’ve found the same problem as Jeff (“Unable to parse the response: Expected element not found: Assertion”) and the Salesforce support team don’t give me any answer about my problem. Have you any idea of why I don’t get any proper SAML answer no mather what type of claim rule I define in the ADFS side?

Please, have you any suggestion about it? I am very stuck with this! Thank you so so much for your help!

Hello I am so glad I found your weblog, I really found you by error, while I was searching on Aol for something else, Nonetheless
I am here now and would just like to say thanks a lot for a tremendous post and a all round entertaining blog (I also love the
theme/design), I don’t have time to go through it all at the minute but
I have saved it and also added your RSS feeds, so when I have time I will be back to read
a great deal more, Please do keep up the great b.

I feel that is one of the such a lot vital information for me.
And i am satisfied reading your article. But want to remark on few
normal issues, The website taste is ideal, the articles is
in point of fact nice : D. Excellent activity, cheers

I’m hoping to start my own site soon but I’m a little lost on everything.
Would you recommend starting with a free platform like WordPress or
go for a paid option? There are so many options out
there that I’m totally overwhelmed .. Any tips? Many thanks!

I love your blog.. very nice colors & theme. Did you create this website yourself or did you hire someone to do
it for you? Plz respond as I’m looking to create my own blog and would like to know where u got this from. thanks

When I initially commented I appear to have clicked on the -Notify me when new
comments are added- checkbox and now each time a comment is added I get 4 emails with
the exact same comment. Perhaps there is an easy method you are able to remove me from
that service? Thanks!

When configuring ADFSv2 for use with Salesforce, it’s recommended that you select the new “HTTP Redirect” option available in the Salesforce Single Sign-On settings under “Service Provider Initiated Request Binding”. We introduced this in Winter 13 to improve interoperability with iOS based devices.

Hi Eric, when you’re prompted for credentials by Internet explorer and you enter the credentials and are successfully authenticated this normally indicates that authentication is configured correctly but Internet explorer is not seeing the site as being in the ‘Local Intranet’ zone so does not perform integrated login.

In your case you are prompted but not successfully authenticated after providing the credentials. This normally indicates that there is an authentication configuration issue. This is most likely a Kerberos configuration issue and most likely a case of missing, duplicate or incorrect SPN configured in AD. The web server and the browser agree to use Kerberos but because Kerberos is not configured correctly the authentication fails and just keeps prompting you to authenticate.

What setspn commands have you run against AD. What is the DNS name of your adfs instance and what is the name of the service account which adfs runs under? Feel free to provide fictitious names in your reply, as long as you illustrate the configuration.

One interesting thing that I suspect is a factor: After the redirect that results in the 403 – Forbidden error, the request was to http://adfs.companyname.local/adfs/ls/ (displayed in the address bar) and using IIS failed request trace I can see the request was made to the url above on port 80. I am guessing this ought to be an https request, but I am not sure what governs that request.

Yeah that certainly doesn’t sound right. Everything should be https. Also you mentioned 2 DNS names have you registered both of them as SPNS against the service account which in this case is the network server (computer account). You might have to fire up wireshark on the workstation and take a look at the Kerberos traffic. Use kerbtray inbetween tests to clear all tickets.

Thanks for the pointers, I decided to start from scratch and follow your directions to a tee and got idP-initiated working (after correcting a case-sensitive issue with my User principal name). Turned out my DNS and certificates were not configured correctly. I should have SP-initiated functioning soon!~

Please let me know if you’re interested in a author for your weblog. You have some really great articles and I believe I would be a good fit. If you ever want to take get some new material, I’d absolutely love to write
some content for your blog in exchange for a link back to mine.

First, I appreciate these instructions. This helped me very much when setting up our ADFS to Salesforce Federation. I was wondering if you worked with the ADFS v2.0 Rollup 2 (RelayState) and Salesforce Desktop Chatter. I know Microsoft added support for RelayState and Salesforce uses this in the Desktop Chatter product.

Hey Chris, sorry for the late reply. I can’t be of much help I’m afraid, we don’t use the desktop client and I have yet played with rollup 2 but thanks for pointing it out I’ll throw it on our test server when I get a chance.

Rhys,
I’m not sure if you’ve encountered this but seeing as that you’re the Salesforce SSO expert (Salesforce even refernces this post) I figured I’d ask you.
Have you had any issues with SSO and chatter customer users? The problem I’m having is that when I finally deployed SSO (with adfs and my domain) my chatter customer users, whom don’t have SSO creds, started receiving chatter emails that force them to an adfs auth login. I contacted Salesforce and they seem to think this is a product conflict but have no desire to fix it. Do you know of a fix or work around I can implement for this?

We don’t have Chatter customer users so I don’t have any experience. Can you Explain a little more? Is this your situation:
Internal employees have full SalesForce licenses and can use either SP or IDP initiated login via ADFS without issue. External customers have Chatter customer licenses and access your ‘MyDomain’ url from the internet but when they do they are re-directed to your ADFS instance which won’t work for them. Is this correct?

Thanks, for the quick reply!
That’s correct, I can’t seem to find a way to stop external customers from being re-directed to my ADFS instance.
Once ‘MyDomain’ is deployed salesforce generated chatter emails (i.e. Daily Digest and post notification) have their links changed to the mydomain url. And anything using the ‘MyDomain’ url forces an ADFS initiated login.
Too bad there’s no way to have a failed ADFS initiated login failover to the Salesforce native service.

I’m having the same issues with Chatter Customer Group members getting the MyDomain URL in their digest emails and not being able to login to view the post. This thread started out great (with the same situation I’m experiecing) but then went another direction. Did either of you figure out a work-around method?

A late reply sorry Ryan. We’re not using chatter yet so don’t have a solution. One avenue you could look down is to enable delegated SSO (as well as SAML) I think that gives some aditional controls as to which users are configured for sso etc. Probably a long shot. Actually seems like a pretty obvious bug which SalesForce should fix.

Hi Tim, from memory I tested this and had it confirmed by SalesForce at the time. so I think this must be a new development. Thanks for pointing it out. I’ve updated the post.

We actually ended up implementing our own JIT provisioning solution. Users first hit an in-house app that checks if they already have an account and if they don’t it will create one for them using the SFDC API. The reason we did this is because we needed to take the user through a few steps to make sure that the details we had for them were correct before we created an account for them. Also email is an mandatory field for creating accounts but we don’t have email addresses for all our users in AD so this method allows us to gather that information from the user.

Hi,
I am having a issue regarding login on salesforce authenicated sites.
My scenario is :
I have two org1 and org2 org.We need test1 standard user of org1 can login on org2’s authenicated sites. Test1 user have the same username in org2 as it in org1.
Is it possible with adfs 2.0. ?

I used your blog to do.but when i am login on authenicated sites using idp .I am getting error.
Error : There was a problem accessing the site. Try to browse to the site again.
If the problem persists, contact the administrator of this site and provide the reference number to identify the problem.

Thanks you Rhys for quick replay.Yes I am Using adfs 2.0 as Idp.
Now I am able to Login On sites .But now the problem is that My org1 have a link with Url of Idp like https://adfs.testzone.local/adfs/ls/idpinitiatedsignon.aspx?loginToRp=https://saml.salesforce.com .By Clicking on that Link it is redirect me on the org2 sites . But first it ask me to login on adfs idp server with username and password.
Is it possible that we can pass the username and password of active directory user in URL ? Or can we change some code in idpinitiatedsignon.aspx cs file.
So that it never ask me to login on adfs idp.
Please help me

when Adfs Idp redirect browser to sites it add /secur/frontdoor.jsp in frony of sites url which is not needed. I don’t want it should add .Please suggest me the solution .
Thanks in Advance
Pradeep Kumar

Hi Pradeep, are you using ADFS 2.0 for the SSO on to org1? I have a feeling that you’re not going to be able to do what you need using ADFS 2.0.

If you are using internet explorer you shouldn’t be prompted ADFS for a username/password. There are a number of things that could cause this. Have you done kerberos configuration?

Also the ADFS server needs to be classified in the local intranet zone to send your credentials. All of this about sending your domain credentials using Kerberos NOT send a username and password which was entered at a salesforce login page. I might be able to give you more advice but you’d need to give me more of an overview of your environment.

Hi Rhys,
Thanks for the reply.
My actual requirement Org1 should have a link .By click on that link Org2’s sites should open a new window and the Org1’s standard user should logged in on org2’s sites.Because Org1’s user have the same username as it in Org2’s user object field like identifier.
I have used your blog to do ADFS server to Org2’s Sites.
But ADFS Server and Org2’s sites takes authentication when we click on link in Org1. I used domain name of Org2 as a link in Org1. ADFS server ask for the Username and password first time only.
I want ADFS server and Sites should not ask for the Login as Org1’s Username same with Org2’s User Identifier Field.
Can I use ADFS Server proxy for Forms Authentication on ADFS Server ?
I used Org2 is metadata File in Relying party trust.
What types of settings i should done?
I did not do anything kerberos configuration.
Please suggest me the best way to do this.
Thanks in advance
Pradeep kumar

Hi Pradeep,
Having the same username and password between orgs won’t help.

You have ADFS 2.0 / SSO working for org1 and now you want it to work for org2 as well. Correct?

You’ve got several different issues here and some more which you’ll discover once you solve these ones I’m sorry to say.

One major problem is that ADFS 2.0 won’t let you have more than one relying party with the same signing certificate which means you won’t be able to have org1 and org2 set up separately with 2 separate idpinitiated urls. Only way around this that I know of is to have a separate ADFS 2.0 servers.

Hi Rhys,
Thanks for writing an excellent post. I have incorporated ADFS 2.0 in web app? I was wondering if ADFS supports form post to another secure site? I have a scenario where site 1 post post form to site 2 but since site 2 is re-authenticated, the form post gets lost. Thanks.

I’m don’t fully understand your question but I think what you’re saying is: if you post data to a site that the user hasn’t yet authenticated to using ADFS, what will happen to the data? I would say that this would have to be handled by the application itself. One option is to stuff the data into cookies so that when the user comes back after authentication the data can be retrieved. The problem is that some browsers (safari) have very small cookie data limits. Another option is to store the data server side. But you’d have to think twice about this solution in a load balancing situation where the user might not always hit the same server. Of course all this assumes that the app you’re dealing with is your own and you can modify it.

Hi Rhys,
Great article. We have an SSO project starting up. Traditionally we were writing code for authenticate and create saml tokens. Now with ADFS2.0 I am very much inclined to use this since it’s a no code solution. I want to know thought if it’s a viable solution.

My use cases –
1. User goes using browser to https://company.my.salesforce.com.
2. User can use Salesforce Chatter app , Mobile devices, and browsers ( IE, FF, Safari, Chrome )
3. User should be able to redirect to the login URL and perform SSO.
4. Our ADFS end point will be external ( internet facing ).
5. User can be within company network or outside company network. If latter then needs to be challenged for credentials before SSO can happen.

Will all of the above requrements get met ( chatter, multiple browsers , mobile devices etc ) using ADFS2.0 as the solution ? I know with FF and Safari users might get challenged but want to know if multiple browsers are OK as it’s a must for us.

Hey Gandhi,
I’m interested to here about your SAML code. .NET? Are you only doing Idp-initiated logins or are you actually acting as a SAML 2.0 endpoint and handling SAMLRequests? Anyway on to your questions:

1.Yep this will do an SP initiated login – ‘redirect’ browser to ADFS so a SAML assertion can be generated. Deep links inside SFDC work too.

2. Chatter app? I’ve not tried this but I’ll put it on my list of things to test. Is this a desktop and a Mobile (Android/iPhone) app? Safari is not so good. Idp-initiated login works but a cookie size limit essentially makes it incompatible when doing SP-initiated login. See the discussion Dan and I have been having below. – No solution yet.

3. I don’t understand the question sorry.

4. I’m using MS ISA Server 2006 reverse proxy for this but it brings it’s own set of problems. I’m thinking of publishing an ADFS proxy to try it out.

5. What you’re asking for is forms based authentication from the internet and integrated (Kerberos) from inside the network. You should be able to do this. Again I use MS ISA 2006 for this but I’m guessing it would be possible with ADFS proxy.

I’ve run into another issue attempting to deploy ADFS 2.0 into production. I was hoping somebody may have some insight into the errors as I can’t seem to find much about them any where. Please note I had this working fine on a development server and development edition of SFDC.

I’ve done the exact same install as I did before in production however now I’m getting errors in the ADFS Event Viewer.

To throw the errors:

Navigate to: https://mycompany.my.salesforce.com/
This throws the vague ADFS error: ‘There was a problem accessing the site. Try to browse…….Reference number: 294fc148-c62c-4c79-87a8-5d62c7001bfa ‘
When I view the ADFS Event Log I can see four errors, they are all event ID: 364. The first says something like this: ‘Encountered error during federation passive request…….. at Microsoft.IdentityServer.Web.FederationPassiveAuthentication.GetPassiveEndpointAbsolutePath()’, the last says something like: ‘Encountered error during federation passive request……..at Microsoft.IdentityServer.Web.FederationPassiveAuthentication.GetIssuerFriendlyName()’

Also note I’ve turned on tracing but don’t see any errors come through when I attempt this. However when restarting the service I see one Event debuggin error which I’m not sure is relevent: ‘CreateFromCurrentConfiguration: Unable to read Winhttp configuration. Using direct connection’

Thanks for your help. I’ve got a feeling I’m missing something with the certificates. However they appear to mimic my dev settings. I also wonder if I’ve done something incorrectly with IIS, port 443 was already taken by another site so I moved the /adfs/ls dirs to the 443 site from the ‘default’ web site and recreated the applications. Once again I did this in dev with no problems. Another issue I’m thinking may be the fact that I’ve not deployed ‘my domain’ within SFDC. However once again I did not do this step in dev and it worked fine so I assumed I could do this later.

When I restart the ADFS service I get an Event ID error of 67 in ADFS tracing that states ‘CreateFromCurrentConfiguration: Unable to read Winhttp configuration’.

Hey Chris, yeah I’m not too sure what’s happening here. Are you able to do an Idp Initiated login? Also did you do your MyDomain config before or after you did your SAML config? Either way just try to turn off SSO in SFDC then turn it back on and re-download the metadata. Then delete and re-create the relying party again. Another thing to check with regards to dev/prod environments – are there different group policies applying to the prod server which didn’t apply to the dev server?

Rhys, sorry for the late reply, I’ve been in training the last couple of days (as well as today) and haven’t had a chance to test your suggestions. Sadly disabling/re-enabling SSO within SFDC did not help. I’m not aware of any group policy that is different within dev/prod.

I could not perform an Idp Initiated login. It throws the same 4 errors in the ADFS event log:

The only error I see in the ADFS debug trace is:
CreateFromCurrentConfiguration: Unable to read Winhttp configuration. Using direct connection. Exception: System.NullReferenceException: Object reference not set to an instance of an object.

Hi Chris, no hassle at all. Your SPNs aren’t correct but I’m not convinced that’s your issue. Your SPN -L output should look like this. (Assuming your running ADFS under NETWORK SERVICE not a domain service account – this is the default)

I’m running out of ideas. Your building this in a VM environment? Maybe time to stand up a new server along said this one and see if you get the same results, should only take an hour or so in a VM environment.

Rhys, I’ve asked our guys to spin up a machine for me (will test this when the request is completed). I’ve done some more reading on ADFS set up and I’m wondering if any of these certificate concerns make a difference. Would you be able to give me a yes or now? Take note I had this working in development under the same settings.

The certificate should be made out to the site name your accessing however that will only make the certificate a bit more valid, it’s still invalid from the point view of anyone who doesn’t trust the CA who signed the certificate and like you say it works in dev. In my dev I have a self signed cert and I just tell my test clients to trust it and it works fine. I don’t think it would matter to sales force it can’t access the ADFS server at all and it doesn’t need to, that’s the beauty of federation.

Rhys, from your suggestions I have easily implemented ADFS/SSO just fine on another server. I can only imagine there are some type of conflicts with our other server which is currently bogged down with apps.

Thanks for all your help, I would have been a bit lost without your suggestions. When I find time I’m going to check that the endpoints are listening as I think changing ADFS to a different port and moving it off of the Default website may be causing some of the issues.

If I can manage to find the solution I’ll be sure to post it here for others to find.

Hey, great to hear you got it sorted. Pretty strange problem and if you’re situation is anything like mine, since it’s working now you’ll probably will never get the time to dig back in and find the cause but it would good to hear back if you do.

I think I can help you out with the ADFS claims rules if a user is not in a group. I had set up JIT before I saw the update to your guide as well, and have to say your constructs are great. I am having an issue with Safari browsers now, for mobile and desktop, where the RelayState is not passed. If you have time maybe I can pass along what I know about the rule language and you may be able to shed light on the Safari issue? Either reply to me here or via t w i t ter @ i n i t 9 9
Cheers
Dan

I’m very keen to hear your thoughts on the claims rule language. It really annoys me that MS haven’t released a full language reference.

As for Safari – I’ve never used anything except IE with ADFS 2.0 but I just installed Safari on a Win XP test VM. As soon as I’m redirected to ADFS from SFDC I get a pretty generic ADFS error. I get the same message when trying an Idp-initated login. I’ll try to trace it when I get back to work on Monday. So is the RelayState in the AuthRequest but not in the AuthResponse? Or is it not even in the request? What operating systems are you running Safari on and how are your clients authenticating to ADFS?
Also what tools are you using to debug?

That’s very interesting that you are seeing the same results. I’ve only experienced this with Safari and my domains SP initiated sign on. I’ve tried this on iPhone/iPad/Win7 (apparently the SF Chatter client uses the i Webkit browser on the devices, so you get the same result). We authenticate to ADFS using forms only.
I do see relaystate passed to the browser, but then the saml response cookies sent back to adfs seem truncated by half or so (when compared with a response from IE or FF) I’ve been trying httpanalyzer as Fiddler doesn’t work well with Safari. Would you be willing to work with SF & MS with me on this?

As for the claims language, I didn’t think to put together something as elegant as your regex, but I did find this way. We are using ADLDS for the federation ID as we have a different unique ID stored there. Hope this is of some help to you and others. Seems to be working for us. The key to getting the wheels to turn here was the NOT EXISTS function.

Hey Dan, thanks a lot for the claims rule stuff, seems obvious now! I knew about ‘exists’ and had tried ! in front of it but not “not” -again no reference, grrrr!

btw I can’t take credit for the elegance of the regex it’s a copy/paste from a one of the built-in templates! How to learn the claims rule language: 1) look at code results from the templates. 2) Enter half correct syntax and let the validator tell you what it was expecting! Ok I’ll stop now.

Anyway as for Safari, I must have had my head in the clouds for too long. – This is going to be a major issue for me too (people like ipads).

Ok So lets first determine if we are getting the same issue. MyDomain SP initiated, redirect to ADFS then error. ADFS doesn’t redirect me back to SFDC. It sounds like you are getting redirected back to SFDC but then getting a SAML error or have I misunderstood you?

To send a SAML assertion to SFDC, ADFS replies to your browser with an HTML form with hidden fields containing the SAMLResponse and RelayState, a javascript then submits the form form you. Are you saying that when ADFS gives you that form, the fields are truncated?

I’m not using forms auth at all. Can you give me a few lines on this? Are you using ADFS proxy? Are you allowing access to ADFS from the internet or just internal. For forms auth and external access I’m using Microsoft ISA 2006, (a whole different can or worms). Anyway more than happy to help out where I can.

Hi Rhys,
Completely agree on the rules language. Took me forever to figure that one out. Such a mess of an implementation.

Anyway, I think I’m experiencing the same issue as you. MyDomain SP initiated, redirect to ADFS, enter credentials on the form, submit, ADFS error (MSIS7046: The SAML protocol parameter ‘RelayState’ was not found or not valid. …)

That CBA article seems to describe it. I get 4 (I think) MSISSamlRequest cookies in Firefox, but in Safari I get 2, and if I decode them, they’re incomplete. Since &RelayState is at the end, its missing.

For forms, I’ve disabled the other auth options because we wanted a consistent experience for login, regardless of IE or Safari or Chrome etc. With integrated turned on, in a browser not passing ntlm/kerberos, you get an ugly pop-up rather than getting sent to the form. I have some ideas how to fix that, but don’t have time, so we are just using forms. ADFS is internet exposed through a proxy on the border, and we’re just using forms, on a SQL server backed cluster of 2 ADFS servers. (Their JoinSqlFarm of the ADFS setup command line is also broken by the way, but that’s another story.)

Do you think its ADFS or Safari messing things up? I have been talking to Salesforce as well to request additional support.

Right well I’m finally on the same page as you. I’ve got my test environment fully set up:
– XP With safari and HTTPAnalyzer
– Ipad on it’s own wireless network and a mirror port and wireshark dumping the traffic of the wireless access point

I can re-produce the problem exactly. Let the sniffing begin. Now the only issue is time looks like I’ve got meeting most of the day.

1. Connect to SFDC, he gives us a SAMLRequest in the form of a HTML form. He also gives us the RelayState.

2. We post the data to ADFS (Un-authenticated, this is evident by the anonymous auth config of the /adfs/ls directory).

3. ADFS looks at all the data we posted (SAMLRequest,RelayState) decides what to do, what relying party to use etc. It stuffs all the data into 4 cookies and redirects the browser to the appropriate authenticated directory. e.g. /adfs/ls/auth/integrated/.

4. The browser GETs the redirected URL and presents the cookies that were set in the previous step. ADFS gets on the the SAML transaction.

With safari when we look at what cookies are presented back in step we only see 2 cookies not 4 so half the SAML info is missing.

So what happens to the missing cookies, they don’t get set properly? They get lost somewhere? Safari chooses not to present them, why?

Nice find! That’s what I’m seeing too. Let me look into this cookie max as well.
I may have a contact in Apple I’ll ring and see if they can help as well. Definitely seems to be a bug, though of course I will expect them to call it a feature.

Yeah I’m not sure it’s so much a bug as just a limitation in the browser. I mean there has to be some kind of limit and all the browsers do have a limit. It’s just strange that there’s such a big gap between Safari and all the browsers. In any case the “fix” really needs to come from the ADFS side even if we could increase the limit in Safari it’s not practical. Still good to raise it with Apple so they can increase the limit to something reasonable in the future. A change like that will take a long time to filter through the populous.

Have you got any MS support? I’m not really sure the best way to raise this with them. They could implement a patch but I don’t think it will be a trivial change.

Yeah I saw that article too but it really looks like it’s more on the development side, not sure how we can relate that to configuration in ADFS 2.0 – unless as there is an undocumented option for the web.config or something.

I’ve got a copy of the code which I think I can freely share. When I get some time and get it working I’ll look to package it in a way that makes it accessible to non-developers. (With the authors permission of course). Not sure when that will be though.

Hi, RhysGoodwin,
You have done best article!!! Thank a lot.
I have some question, I have done all steps but when I go to Salesforce with my domain, Windows ask me to re-login again on ADFS server!!! It shouldn’t be like that, how can I solve this? Thank you very much

Hi Lextech, the most common cause for this is Kerberos authentication failing. Can you answer the following:
What browser are you testing with?
Have you configured SPNs?
When you are prompted for login again is it successful when you enter your username/password?
Have you made any changes to IIS authentication settings on the ADFS server?

We already had an ADFS v2 QA setup and have a few production connections. I am trying to use ADFS and am leanting ADFS, SAML and some networking at the same time.

I have accomplished the SSO I wish but need to assure how it’s workingas well. My main doubts are in the client authentication to ADFS. When I looked at our QA system the IIS adfs/ls authentication had been configures with Extended=Off; Kernel Mode = Enabled; Providers = (1) Negotiate (2)NTLM. If I turn IE/WIA off I see an Authorization: NTLM cookie in a fiddler trace and with WIA enabled see Authorization: Negotiate cookie.

My goal is to have authenticated users hit ADFS and and authenticate via Kerberos and if not be prompted to authenticate. Would the Would the (1)Negotiate, (2) NTLM provider stack accomplish this? I see there is also a Negotiate:Kerberos provider. So in spite of my success with my SAML setup I am still in doubt that the desired setup is making it work. To add to my doubt I se Kerberos failures in the security event log after a succesfull login via ADFS.

Hey Doug, I’ll try to reply in full later but yes you’re on the right track, Kerberos is king. Best to use negotiate. In my case I’ve left extended protection on. I don’t know the ins and outs of it yet. For Kerberos to work you’ll need to understand SPNs and then set them up. Also use kerbtray.exe for troubleshooting. Check out this post and see if it helps let me know how you get on:https://blog.rhysgoodwin.com/windows-admin/active-directory-and-kerberos-spns-made-easy/

I suspect one of two issues. Firstly the ‘My Domain’ section is still saying ‘Your domain name registration is pending’, I’m not sure if this is the reason. Or secondly I’m just not sure I have IIS set up properly. I didn’t expect to see a 404 error. I did nothing to set up IIS and let ADFS do the work. I can see it created directories under the ‘Default Web Site’.

If you are being re-directed then I don’t think it’s an issue with SFDC. I notice above you mention http://MyFriendlyDomain/adfs/ls/ it should be https. (Not sure if that was just a typo in the example?). But double check that you have https in your “Identify Provider Login URL” at SFDC. No IIS config is needed. It’s all handled by ADFS 2.0. Let me know how you get on.

I’ve managed to get this working. I hadn’t noticed the website wasn’t running because instead of showing the little icon of ‘stopped’ it showed ‘multiple protocols’. I already had a site running on 443 so I moved adfs/ls to that site and now IIS is working properly.

Hi all,
If anybody is reading this blog and needs the answer as to how I resloved the Issuer Mismatched error. I had changed my issuer to https thinking it needed to be. However my assertion was sending http. Changing the Issuer to http resolved the issue.

I hope you have a moment. This is a great article by the way! Very easy to follow and setup.

The issue I’m seeing is when I initially hit the idp URL, I’m asked to authenticate to the domain even though I’m already logged into the domain! Once I provide my AD credentials I’m then sent onto Salesforce.

Which browser are you using? Since entering credentials when prompted does authenticate you correctly I suspect that issues is not to do with Kerberos/authentication configuration at the server. Internet explorer will only attempt to to send the user credentials automatically if the site is categorised in either the “Trusted Zone” or “Local Intranet Zone” so check which zone the ADFS server is detected in by looking at the IE status bar when you get prompted.

Good to hear you got it sorted. You wouldn’t believe it -right now as we speak I’m working on SSO for customer portal, also JIT provisioning. Having a few issues and I’ll be meeting with some SFDC people next week to discuss. I’ll keep you posted. Are you looking at this too?

Actually, yes I/we are! I’ve got several links that Salesforce provided in way of passing additional Portal ID and Org ID information. I’m pretty new to ADFS so we’re still trying to figure out how that would work since Customer Portal works off it’s own URL.

You need to create a custom claims rules to send the portal id and org id. My issue at the moment is that when you send portal id and org id it seems to stop normal sso from working. I’ll let you know how I get on and will eventually post the details here.

Thanks Rhys! We were finally able to get this all working. We had to also include the siteURL since our Portal is managed via Sites. We also had to tweak our starting home page so it goes directly to the home page vs. landing the user back at our custom login page.

It’s really hard to say without more information but no I can’t think of something off the top of my head that would cause that. You’ll need to dig deeper into Windows/ADFS event logs on the ADFS server and if you don’t find anything there you might need to use an HTTP debugging tool. Does Idp initiated login work?

Hi James, have a look under the testing section above where I discuss Idp-initiated login. And for HTTP debugging you can use fiddler as above in the “Further Analysis” section. Fiddler has an option to enable debugging on SSL, basically just man-in-the-middle. Also under the testing section a link to ADFS diagnostics blog post. Were you able to find anything in any of the logs?

Having some issues, after a successful ADFS test to an SFDC environment.

Now I’ve got a production environment to get going, and can’t seem to get beyond the deadly 3 password prompts and a 401 error page.

I’ve made sure spn is set for HOST/sso.domain.com, AND HTTP/sso.domain.com. The Federation Service name is different from the host name. My domain issued ADFS cert uploaded to SFDC, and a Thawte SLL cert for sso.domain.com installed on sso.domain.com.

All my settings are identical from the old DEV SFDC test to my new Sandbox production test.

Hi John, double check that you don’t have duplicate SPNs, you can do that by searching the servicePrincipalName attribute in AD. If it prompts you but authenticates correctly when you type in your username/password then IE must not be sending the credientials. That is IE is not identifying your ADFS site as a local intranet site. If it prompts you but always fails then you have a kerberos error. Use kerbtray.exe and wireshark on the workstation to troubleshoot the error. let me know how you get on or if you’d like more detail. One other thing to test – try disabling extended protection on IIS ADFS site.

Hi Rhys,
Can you please help me understand how to test ADFS Security Testing? I have to prepare two slides to present client that we have ADFS Testing experience. What to test on ADFS Security and How to test them. Any model or frame work would be of extensive help.
Appreciate you help in this instance and thanks in advance

It would be much easier if you had them discover the Federation Service Name via Federation Service Properties rather than looking through metadata. I can see this being prone to confusion/mistakes. Otherwise, good stuff. I may ping you about getting this over to our TechNet Wiki for AD FS 2.0. Called AD FS 2.0 Content Map. BTW – I am a Microsoft Employee.

Hi Yogesh, I’ve not had any experience getting Firefox/Safari to do Kerberos against IIS but I’d recommend digging deeper to find out why you need to turn off extending protection to make it work. Check out my Kerberos entry here

Does the ADFS solution handle the Outlook/Notes plug-in, deep-linking, do anything with the delegated auth API’s or help with provisioning in any way? Is OAuth2.0 going to be part of ADFS anytime soon, I believe and Chuck M could probably confirm one way or another if Salesforce is moving to to OAuth for the mobile apps?

I’m not sure about Outlook/Notes plug-in but thanks for brining it up, I better check if our organisation uses it! If they do I’ll report back whether it works. I can’t see any reason why it couldn’t work, presumably it’s just a web client.

Deep linking – yes it works.

I haven’t had any experience with delegated auth at all so I’m not sure if the APIs have provisioning support. This probably a question for Chuck/Pat too. I don’t think provisioning via SAML is possible.

Thanks, I didn’t think so. Ping Identity I believe is one of the only companies that offers a complete solution. Providing only web sso does not give a user a true SSO experience. I think any SSO solution specific to Salesforce needs to be able to handle the browsers, mobile apps, and the Outlook/Notes plug-in, deep-linking. A true SSO solution should also be able to handle a variety of protocols, binding types, etc…. I am not convinced ADFS 1 or 2 is ever going to be anything more than a 1-off or bandaid SSO tool.

Well it’s not really about ADFS it’s about SAML Web SSO. SalesForce is a web based platform. It doesn’t matter whether the client is a browser, mobile app, outlook plugin or whatever. They all talk to SalesForce with the same protocol (HTTP). The key is that each client implementation must support the necessary functionality to be able to handle the SAML process. It looks like the Outlook plug-in will be updated to do this in the next release. SAML has a number of binding options including:
HTTP Redirect (GET) Binding
HTTP POST Binding
HTTP Artifact Binding

For SP-Initiated login customer can actually use our My Domain feature, which allows them to capture their own URL. Using this URL, we can automatically initiate a SAML Request to the customer’s IDP without having to go through IDP initiated SSO and getting a cookie set. Much better admin and end-user experience.

We actually have a much more elegant means of achieving SPInitiated SAML these days using a feature we call My domain. Using this customers can claim their own URL and we tie SAML configuration to that URL. I’ love to help you update this paper and will work with Pat on the developer force version

Yeah I’m more than happy for you to put this info up on the Wiki. I actually got my first taste of SAML understanding from the SalesForce SAML article you linked below. Let me know if you want the source images.

Works like a champ. Only had one minor issue: our test server had a time skew that was THREE MINUTES FASTER than the client used for the authentication, and I kept getting a “Assertion Expired” error in the user login logs.

Evidently SFDC doesn’t like time skews much:
Assertion Expired
An assertion’s timestamp is more than five minutes old.
Note: Salesforce does make an allowance of three minutes for clock skew. This means, in practice, that an
assertion can be as much as eight minutes passed the timestamp time, or three minutes before it. This amount
of time may be less if the assertion’s validity period is less than five minutes.

Another point i have, how big is your company? do you have “external” clients? have you ever thought about this ADFS Proxy Scenario? I have not read any documentation until know but i think this could be awesome for my company in order to provide sso for not connected users…

Hi Ben, thanks for your feedback. With regards to the 401, looking at the link you provided it sounds like you might haved configured IIS to force NTLM. This really should be avoided. You really want to be using negotiate (which implies Kerberos). Are you using the server name or a different DNS name to access ADFS? If you’re using a DNS name you need to register it as an SPN as mentioned above. Also note the link to my post on Kerberos and SPNs. What can happen is that IIS and internet explorer negotiate and agree to use Kerberos which fails so you get a 401. It took me a while to get my head around Kerberos but it’s really important to fully understand it if you’re doing a lot of work with IIS in an intranet context.

We have about 200 SFDC users and growing, out of 1000+ internal domain users. To be honest I haven’t looked at the ADFS proxy at all. When you say external or ‘not connected’ do you me users who might be working from home? For this scenario we use Microsoft ISA server to authenticate the user. I might do a post on ADFS / ISA soon. Let me know if you try out the proxy and what you discover.

about that 401 issue, your right. I’ve forced NTLM which is “not correct”. But when i’m using negotiate it’s not working, i still get this f.. 401 error.
I’m not using a ‘new’ DNS name to access the webpage.
I set the SPNs:

Your SPNs are wrong. AD FS 2.0 uses HOST, not HTTP. And the service name needs to be your federation service name (seen in the Federation Service Properties). If the AD FS server’s host name is fs1.contoso.com and your federation service name is sso.contoso.com, the SPN you need is: HOST/sso.contoso.com.

Also try turning off Extended Protection for Authentication on /adfs/ls/ for Windows authentication (advanced settings). I write about all of this stuff on the TechNet Wiki, which should be your source for AD FS know-how. Search for AD FS 2.0 Content Map and you’ll hit our collection.

One thing to watch out for is the Federation ID is case-sensitive. So if this is your organizational email, be sure to enter it exactly as AD FS sends it, or Salesforce won’t be able to find the matching user.

This is a bug on SF. You should file with them. Attribute values normally should not be case sensitive. A claim rule on AD FS could do ToUpper or ToLower, but that’s not the correct solution. If I have 50,000 employees, I don’t want to have to worry about the case of their UPN individually.

I also made the assumption that I could use ToUpper() etc but it seems the claim language is very simple and doesn’t support “complex” string manipulation.

In general I found the claim rule language documentation to be fairly lacking – I wasn’t able to find a full language reference at all.

My initial thought was that the same as your’s. “If I have 50k employees…” But in reality I don’t think it will be too much of an issue. If you’re dealing with such large numbers of users then your account provisioning would need to be automated via the SFDC API anyway so the field would be copied like-for-like.

Hi Timothy, is the issue that chrome always prompts for username/password? If so, dose it work when you enter your username/password? If so you need to look into WIA for chrome it’s not enabled by default. You should be able to configure chrome with group policy to enable WIA across the environment.