This post will describe how OpenAM can be configured as a hosted SAML Identity Provider Proxy with Salesforce acting as Service Provider, and Active Directory Federation Services 2.0 as the Identity Provider. Note that this use case uses Salesforce as the Service Provider. Note that to a Service Provider, an IdP Proxy looks like an ordinary IdP. Likewise, to an Identity Provider, an IdP Proxy looks like an SP. Thus an IdP Proxy has the combined capability of being both an IdP and SP.
The following table is lifted from Spaces. Like a Web (HTTP) Proxy, an IdP Proxy delivers increased efficiency, security, and flexibility.
||..cache web pages
||..controlled access to web pages
||..controlled access to federation IdPs
||..HTTP request/response filtering
||..SAML request/response filtering
Presented here is the IdP Proxy flow:
- A browser client requests a web resource protected by a SAML SP (Salesforce). If a security context for the principal already exists at Salesforce, skip to step 14.
- The client is redirected to the IdP component of the IdP Proxy (OpenAM-IdP0), which is protected by the SP component of the IdP Proxy (OpenAM-SP1).
- The client makes a SAML AuthnRequest to the SSO service at OpenAM-IdP0. If a security context for the principal already exists at OpenAM-IdP0, skip to step 10.
- The AuthnRequest is cached and the client is redirected to the terminal IdP (ADFS). ADFS presents a BA prompt for authentication by default.
- The client makes a SAML AuthnRequest to the SSO service at ADFS. If a security context for the principal does not exist, ADFS identifies the principal.
- ADFS updates its security context for this principal, issues one or more assertions, and returns a response to the client.
- The client submits the response to the assertion consumer service at OpenAM-SP1. The assertion consumer service validates the assertions in the response.
- OpenAM-SP1 updates its security context for this principal and redirects the client to OpenAM-IdP0.
- The client makes a SAML AuthnRequest to OpenAM-IdP0, the same AuthnRequest made at step 3.
- OpenAM-IdP0 updates its security context for this principal, issues a single assertion, and returns a response to the client. The response may also contain the assertions issued by ADFS at step 6.
- The client submits the response to the assertion consumer service at Salesforce. The assertion consumer service validates the assertions in the response.
- Salesforce updates its security context for this principal and redirects the client to the resource.
- The client requests the resource, the same request issued at step 1.
- The resource makes an access control decision based on the security context for this principal and returns the Salesforce landing page to the client.
For starters, please refer to Victor’s excellent post about preparing the metadata files for a similar scenario at SAMLv2 IDP Proxy Part 1.
Follow steps 1-4 in that post to prepare your metadata.
Federation Entities in OpenAM
In this section we will survey the entities you have imported in OpenAM so far:
Circle of Trust
Remote Service Provider: Salesforce
Your settings should be very similar to those presented here:
Signing and encryption can be turned off, if not needed.
This screen shows a critical settings related to the IDP Proxy. Ensure your ADFS 2.0 Entity ID is correctly defined in the list.
Remote Identity Provider: ADFS 2.0
Hosted IDP Proxy
Set “test” as the signer certificate in the IDP section of the Hosted IDP/SP proxy entity.
IDP Section continued..
The first page..
Assertion processing screen..
The mapping shown below is critical. Here we map the ADFS credential to an internal (anonymous) user, in our case it is “demo”. It could be “anonymous” if such a user is present in your user repository.
Since ADFS does not support Scoping elements, also necessary to achieve this integration is a custom Service Provider adapter that removes the Scoping element from SAML AuthRequest sent to ADFS.
SP Section Continued..
Add the Entity ID for Salesforce here:
Preliminary Steps: Configure OpenAM
1. Import certificates into OpenAM keystore and Java keystore:
/usr/java/jdk1.7.0_45/bin/keytool -importcert -alias sfdc -file SelfSignedCert_09Mar2014_053347.crt -keystore keystore.jks
/usr/java/jdk1.7.0_45/bin/keytool -importcert -alias adfs -file adfscert.cer -keystore keystore.jks
/usr/java/jdk1.7.0_45/bin/keytool -exportcert -alias adfs -file adfscert.crt -keystore keystore.jks
/usr/java/jdk1.7.0_45/bin/keytool -exportcert -alias sfdc -file sfdc.crt -keystore keystore.jks
/usr/java/jdk1.7.0_45/bin/keytool -importcert -alias adfs -file ccgadfs.crt -trustcacerts -keystore /usr/java/jdk1.7.0_45/jre/lib/security/cacerts
/usr/java/jdk1.7.0_45/bin/keytool -importcert -alias sfdc -file sfdc.crt -trustcacerts -keystore /usr/java/jdk1.7.0_45/jre/lib/security/cacerts
2. In OpenAM, after importing the metadata files, add the Federation Authentication Module under /local realm
Step 5: Creating the Single Sign On settings in Salesforce
In Salesforce, under Security Controls -> Single Sign On Settings, create a new “SAML Single Sign-On Setting”, and fill in the Identity Provider Login URL, and Logout URLs from the metadata file “machineb.idpproxy.com-idp-meta.xml” in Step 4.a.
Step 6: Importing the Service Provider descriptor from the IdP Proxy into ADFS 2.0
On the Windows server, start up AD FS 2.0 Management utility, and create a new relying part trust, by cliking on “Add Relying Party Trust”.
Select “Import data about the relying party from a file”, and use the “machineb.idpproxy.com-sp-meta.xml” you created in Step 4.c. Call it “Salesforce via OpenAM IDP Proxy” and finish.
Select the newly created relying party and ensure the settings match the screenshots presented here.
For example, change the default SAML ACE from Artifact to POST.
Also, change the secure hash algorithm to SHA-1 as shown here.
Click on “Edit Claim Rules” and follow instructions given in OpenAM and ADFS2 configuration to create the first rule.
Create a custom claim rule using the following script:
c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"] => issue(Type = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", Issuer = c.Issuer, OriginalIssuer = c.OriginalIssuer, Value = c.Value, ValueType = c.ValueType, Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/format"] = "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified", Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/namequalifier"] = "<entity-id of ADFS 2.0>", Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/spnamequalifier"] = "<entity-id of your IDP proxy>");
You should see two rules now:
Click ok to finish editing claim rules.
Optional ADFS 2.0 configuration
You can configure ADFS to not encrypt or sign SAML responses. Follow these steps if necessary:
- Use Windows Power Shell to check for installed ADFS snap-in: Get-PSSnapin -Registered
- You should be able to see: Microsoft.Adfs.PowerShell 1.0 “This powershell snap-in contains cmdlets used to manage Microsoft Identity Server resources”
- Now proceed to add it : Add-PSSnapin Microsoft.Adfs.Powershell
- Configure ADFS to not encrypt SAML response: Set -ADFSRelyingPartyTrust -TargetName “Salesforce via OpenAM IDP Proxy” -EncryptClaims $False
- **If you get an erroneous SAML StatusCode “Responder” error in OpenAM during testing, run these commands to turn off certificate revocation checks in ADFS:
- Set-ADFSRelyingPartyTrust -TargetName “Salesforce via OpenAM IDP Proxy” -EncryptionCertificateRevocationCheck ‘None’
- Set-ADFSRelyingPartyTrust -TargetName “Salesforce via OpenAM IDP Proxy” -SigningCertificateRevocationCheck ‘None’
Navigate to your Salesforce SSO URL, you will immediately be taken to the ADFS basic authentication prompt:
Enter your ADFS domain credentials here and hit Log In. If all is well, you should be taken to your Salesforce landing page.