Tag Archives | federation

ADFS 2.0 in Forest Trust Environment

I’ve been meaning to get this out there for a while now.  I’m not going to go into great detail on ADFS but you can get more background on ADFS and federation in these posts:

Salesforce SSO with ADFS 2.0 – Everything You Need to Know

ADFS 2.0 Choose Your Attributes Wisely

SAML WebSSO Federation Made Easy

 

My scenario is as follows:

  • 2 domains in 2 forests with a one way trust between them.
    (For this post I’ll refer to these domains PERIMETER and INTERNAL)
  • PERIMETER trusts INTERNAL but INTERNAL doesn’t trust PERIMETER
  • Both PERIMETER and INTERNAL contain user accounts that need to be authenticated and federated via ADFS
  • The ADFS server is joined to the PERIMETER domain
  • ADFS and its related IIS services need to run under a service account from the INTERNAL domain

Here are the high level hoops I had to jump through to get this working:

  1. On a clean Windows 2008 R2 server, obtain and run the ADFS 2.0 setup file AdfsSetup.exe. Select “Federation Server”,  This will install everything you need to make ADFS 2.0 work (including pre-requisites).  Don’t run through the config wizard – We will do the config from command line later.
  2. Create a new service account. e.g. INTERNAL\Svc.ADFS.  Create a new DNS ‘A’ record and point it to the ADFS server. E.g. federate.internal.com. Set a Kerberos SPN for the DNS record against the service account:
     setspn -a HOST/federate.internal.com stjohn\Svc.ADFS
  3. Load the certificates MMC for local computer account and install a certificate which can be used for the ADFS web site. In the IIS manager configure a new binding on the default website for SSL with the appropriate FQDN and select the cert you just installed.
  4. Make sure the ADFS server has access to all LDAP servers for all domains. Something to consider if you’ve got a few firewalls here and there.
  5. Add your service account to the local admins group on the ADFS server and to domain admins group for the domain that the service account belongs to. Don’t panic this will only be temporary! This just allows the service account to create the necessary config for ADFS in the Program Data\ADFS OU. Once created it will have the correct permissions for the service account. I had to do this to get it work, not sure why it’s any different to a normal single forest install.
  6. Log on to the ADFS server with the service account. Skip this step at your peril!
  7. Run cmd prompt as admin. cd to:
    C:\Program Files\Active Directory Federation Services 2.0\
  8. Run the following command to configure and new ADFS 2.0 farm

    FSConfig.exe CreateFarm /ServiceAccount "INTERNAL\Svc.ADFS" /ServiceAccountPassword "somebiglongpassword" /AutoCertRolloverEnabled /FederationServiceName "federate.internal.com


  9. Remove the service account from local admins and domain admins now.
  10. That’s it. Load the ADFS console and configure ADFS as you would in any other scenario

Notes

  • During the install you might get a yellow warning about not being able to set the SPN. That’s cool we already did it above.
  • Make sure you can view the federation data for your new server e.g.
    https://federate.internal.com/FederationMetadata/2007-06/FederationMetadata.xml
  • If you get a certificate error from your service provider. E.g. This typical error from SalesForce:Signature or certificate problems
    Is the response signed? False
    The signature in the assertion is not valid
    Is the correct certificate supplied in the keyinfo? False
    No valid certificate specified in this response.

    T
    ry re-generating your token signing certificate using the following PowerShell commands. Note:This will break any existing trust relationships you have with any service providers. You will have to export the new cert and update your service providers with it.
Add-PSSnapin Microsoft.Adfs.Powershell
Set-ADFSProperties -AutoCertificateRollover $true
Update-AdfsCertificate -Urgent

 

This might not be the only way to get this working and I haven’t tested it thoroughly – your mileage may vary! But as always I’m keen to hear how you get on and happy to field questions.

 

10

ADFS 2.0 – Choose Your Attributes Wisely

If you’ve read my last few posts you’ll be aware that I’m in the middle of implementing ADFS 2.0 for Web SSO. SalesForce for starters, with more to follow.  I’m yet to put it into production but I was thinking today and just having a bit of a sanity check and something occurred to me.  We send LDAP attributes as claims, the attributes are accepted by our service provider as law. They trust our federation service – that’s what federation is all about. Trust.  There are number of mechanisms that make it very difficult for someone to spoof an assertion. On the whole, the SAML protocol can be considered very secure.  What it can’t do is guarantee the validity of the source LDAP attribute.

 

Consider the scenario above.  We’re going to send the User’s telephone number as a claim.  Maybe unlikely but it could happen, maybe you’ve got a SaS provider and you’ve already got 500 users in the system and telephone number is the only field you know is accurate between you and them. Unlikely? I know.   But that’s not the point.

The issue is this – in Active Directory the attribute telephoneNumber, along with a few other attributes is by default, self writeable.

Once Dave figure’s out that the telephone number is significant he’ll update his phone number in AD to Bob’s phone number, launch the SaS app and will be logged in as Bob.

 

While there are only a few self writeable attributes in AD and they’re not ones you’d likely use for federation, it’s important to keep the whole picture in mind and the problem could go beyond self writeable attributes.  A couple of other situations I can think of off the top of my head:

  • Active directory self service applications which allows users to update attributes which aren’t normally self writeable
  • Identity management systems which synchronise other systems to Active Directory.  Not a problem in itself but you might be moving the point authorization for a specific application without realising it.

So choose your attributes wisely and make sure you know how, why, when and by whom or what they are written to before you decide to send them as federation claims.

4

SalesForce SSO with ADFS 2.0 – Everything you need to Know

Updates

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

 

  1. The user authenticates to the ADFS server using Kerberos and requests login to SalesForce
  2. ADFS returns a SAML assertion to the user’s browser
  3. 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
setspn -a HOST/adfs.testzone.local testzone\ADFSSVR01
setspn -a HOST/adfs testzone\ADFSSVR01

For more info on Kerberos SPNs see my Active Directory and Kerberos SPNs Made Easy post

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

 

Copy the entityID.  In my case http://adfs.testzone.local/adfs/services/trust

Go to SalesForce Setup\Security Controls\Single Sign-On Settings\



  • SAML Enabled: Ticked
  • SAML Version: 2.0
  • Identity Provider Certificate: Browse and select the token-signing certificate you exported earlier
  • Issuer: Paste your entityID in here
  • 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 in ADFS 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 *
  • LDAP Attribute: User Principal Name
  • Outgoing Claim Type: Name ID

*Update:See my post on choosing you’re attributes wisely. There’s a potential security pitfall here.

 

SP-Initiated Login

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.

The custom rule is as follows:

=> issue(Type = "logoutURL", Value = "http://intranet.youcompany.com", Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/attributename"] = "urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified");

 

 

 

Testing

Alright, so that should be about it.  We can now go and set the Federation ID of a SalesForce user to the UPN our own AD user account and see if it all works.

Point your browser to your ADFS IdP-initiated login URL and specify the loginToRp parameter as the SalesForce SAML entity ID.
E.g. https://adfs.testzone.local/adfs/ls/idpinitiatedsignon.aspx?loginToRp=https://saml.salesforce.com

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.

Send Portal ID

c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid", Value =~ "^(?i)S-1-5-21-1458536374-0499464381-951853424-103426$"]
 => issue(Type = "portal_id", Value = "033G00000002a1P");

Send Org ID

c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid", Value =~ "^(?i)S-1-5-21-1458536374-0499464381-951853424-103426$"]
 => issue(Type = "organization_id", Value = "01GK00000004ra2");

 

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
  • JIT can’t be used to provision Portal accounts!
    *Update* It looks like this has changed and it is now supported. Thanks Tim for pointing this out!
    https://login.salesforce.com/help/doc/en/sso_jit_portal_requirements.htm
  • 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:

http://success.salesforce.com/ideaView?id=08730000000ZtgiAAC


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

 

235

SAML WebSSO & Federation Made Easy

 

This week I found myself on a SalesForce/SAML/Federation journey which turned out to be very enlightening. Until a few days ago I really had no idea how SAML or Federation worked and it took me a few hours to get my head around it, so I’m going to try explain SAML in a way that’s easy to understand.

SAML 2.0 (Security Assertion Markup Language).

2 Companies:
Company A (Service Provider – SP) has a web application
Company B (Identity Provider –  IdP) has a database of people who need to access Company A’s application

We have a few options here:

  1. Company A could create a new database of people with usernames and passwords within the web application
  2. We could synchronise the database of people including their usernames and passwords from Company B to Company A
  3. We could make a link from the web application to Company B’s database of people and do lookups in real-time
  4. We could tell the web application at Company A to trust users who come from Company B

Options 1 through 3 are pretty crappy.  Option 4 is called federation and it’s cool.

Here’s what happens (part analogy, part reality):

Both companies have a pair of keys. A public key and a private key.  Once something is locked with the private key only the corresponding public key can open it.  Company A has a copy of Company B’s public key and vice versa.

A user in Company B tries to access the web application at Company A.  The web application looks for a cookie in the user’s browser to see if he is already authenticated, he is not so the web application (SP) redirects the browser to Company B’s IdP, telling him – “Go and get a ticket!”

The browser goes to Company B’s IdP who authenticates the user against Company B’s database of users. The IdP at Company B locks the user’s employee ID with his private key, gives it to the browser and tells him – “Here’s your ticket now go back to the SP you came from!”

The browser goes back to the web application (SP) at Company A and presents his ticket.  The SP uses Company B’s public key to unlock the ticket.  The web application says to himself –  “It works! This user MUST have come from Company B because otherwise this public key could NOT have unlocked this ticket. And look, the ticket contains an employee ID and I have a rule that says that this employee ID is allowed access!” And so the web application gives the browser a cookie which allows him access.

 

In SAML the ticket is called an Assertion.  In this case we sent the Employee ID but any other user-unique attribute could be used, it just needs to be agreed between the 2 parties.

In reality the web application might not support SAML directly but instead maybe protected by a federation product which takes care of the SAML SP stuff.  The IdP stuff will also likely be handled by a federation product which is backed by some kind of LDAP directory or maybe SQL.  The browser cookie stuff mentioned above is outside the scope of SAML but I included it for completeness – It’s typical of how these things work.

 

The neat thing about federation is that you don’t need any links between Company A and Company B. Once the trust is established everything else takes place “browser to SP” and “browser to IdP” through a series or re-directs and http POSTs.

 

Ok so that’s SAML.  Actually there are a lot more parts to it than that but that’s the way it’s most commonly used today i.e. for WebSSO.  Now that you have the concept, you can dig into the technical details.

I found Google’s explanation useful:
http://code.google.com/googleapps/domain/sso/saml_reference_implementation.html

and Wikipedia :

http://en.wikipedia.org/wiki/SAML_2.0

 

The best way to learn this stuff is to give it a go.  Check out Shibboleth which is an open source SAML SP and IdP implementation.  I’ve got the Shibboleth SP side talking to ADFS 2.0  as the IdP but I haven’t played with the Shibboleth IdP yet.

 

Next time I’ll show you how to put SAML to use with Active Directory Federation Services 2.0 and cloud provider SalesForce.  In the mean time feel free to ask questions or make corrections.

10