Connecting the ComponentSpace SAML 2.0 stack to ForgeRock AM
I’ve been having a look at ForgeRock AM (v6.5)for a customer and decided to integrate it with the ComponentSpace (CS) SAML 2.0 stack as an exercise.
When I googled this, I couldn’t find a single entry although there were a number of posts asking for help so yet another reason to write this post.
For those who don’t know, the product started as OpenSSO, an access management system created by Sun Microsystems and now owned by Oracle Corporation. OpenAM is a fork which was initiated following Oracle’s purchase of Sun. ForgeRock (FR) was built out of OpenAM.
It’s primarily an on-premises product, although work is being done on ForgeRock Cloud.
In the Gartner AM quadrant, it sits in the bottom right section along with Idaptive, OneLogin and Auth0. The leaders in the top right section are Okta and Azure AD.
The first thing that is different is that you need to define a circle of trust (CoT). This “is an AM concept that groups at least one identity provider and at least one service provider who agree to share authentication information.” So to allow FR (the IDP) and CS (the SP) to engage in SSO flows, they must be placed within the same CoT.
You need to do this inside a FR realm. “AM supports its multiple clients through its use of realms. You configure realms within AM to handle different sets of users to whom you can set up different configuration options, storage requirements, delegated administrators, and customization options per realm.”
You need to log into FR as an Admin. user.
Then in the realm, navigate to “Applications → Federation”.
Then click “Add CoT”.
Type in the name of the CoT and click “Create” and “Save Changes”.
Now for the IDP.
Navigate to the dashboard for the realm.
“ Realm Overview → Common Tasks” then “Configure SAMLv2 Provider” then “Create Hosted Identity Provider”
Then enter the parameters as above. Note: there seems to be a bug here so you need to click the “No” button for metadata to make sure. Then select your realm.
Then “Configure” — the button near the top-right corner of the page. A success page is displayed then “Finish” to go back to the dashboard.
Now for the SP which is the CS stack. The example I’m using is the MvcExampleServiceProvider.
First we need the FR SAML 2 metadata found at:
It looks something like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<EntityDescriptor entityID="http://localhost:8080/am" xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:query="urn:oasis:names:tc:SAML:metadata:ext:query" xmlns:mdattr="urn:oasis:names:tc:SAML:metadata:attribute" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:x509qry="urn:oasis:names:tc:SAML:metadata:X509:query" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<IDPSSODescriptor WantAuthnRequestsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<KeyDescriptor use="signing">
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>
MIIDYT...Lr3cM= </ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</KeyDescriptor>
<ArtifactResolutionService index="0" isDefault="true" Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://localhost:8080/am/ArtifactResolver/metaAlias/YourRealm/idp"/>
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://localhost:8080/am/IDPSloRedirect/metaAlias/YourRealm/idp" ResponseLocation="http://localhost:8080/am/IDPSloRedirect/metaAlias/YourRealm/idp"/>
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:8080/am/IDPSloPOST/metaAlias/YourRealm/idp" ResponseLocation="http://localhost:8080/am/IDPSloPOST/metaAlias/YourRealm/idp"/>
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://localhost:8080/am/IDPSloSoap/metaAlias/YourRealm/idp"/>
<ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://localhost:8080/am/IDPMniRedirect/metaAlias/YourRealm/idp" ResponseLocation="http://localhost:8080/am/IDPMniRedirect/metaAlias/YourRealm/idp"/>
<ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:8080/am/IDPMniPOST/metaAlias/YourRealm/idp" ResponseLocation="http://localhost:8080/am/IDPMniPOST/metaAlias/YourRealm/idp"/>
<ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://localhost:8080/am/IDPMniSoap/metaAlias/YourRealm/idp"/>
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</NameIDFormat>
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</NameIDFormat>
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName</NameIDFormat>
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos</NameIDFormat>
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName</NameIDFormat>
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://localhost:8080/am/SSORedirect/metaAlias/YourRealm/idp"/>
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:8080/am/SSOPOST/metaAlias/YourRealm/idp"/>
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://localhost:8080/am/SSOSoap/metaAlias/YourRealm/idp"/>
<NameIDMappingService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://localhost:8080/am/NIMSoap/metaAlias/YourRealm/idp"/>
<AssertionIDRequestService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://localhost:8080/am/AIDReqSoap/IDPRole/metaAlias/YourRealm/idp"/>
<AssertionIDRequestService Binding="urn:oasis:names:tc:SAML:2.0:bindings:URI" Location="http://localhost:8080/am/AIDReqUri/IDPRole/metaAlias/YourRealm/idp"/>
</IDPSSODescriptor>
</EntityDescriptor>
Note: There is a bug where sometimes the certificate is not added to the metadata. If that happens, go back to the IDP screen, remove the “test” signing key, add it back and save. That should fix the problem.
We need:
entityID="http://localhost:8080/am"ACS=<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://localhost:8080/am/SSORedirect/metaAlias/YourRealm/idp"/>Cert=<ds:X509Certificate>
MIIDYT...Lr3cM= </ds:X509Certificate>
The certificate is much longer but shortened for convenience. Take the actual certificate and save it as a fr.cer file. It you click on it, it should show the Windows certificate wizard. Save the fr.cer file in the “Certificates” folder of the project.
In the web.config:
<add key="PartnerIdP" value="http://localhost:8080/am"/>
In the SAML.config, add:
<!-- ForgeRock -->
<PartnerIdentityProvider Name="http://localhost:8080/am"
Description="ForgeRock"
SignAuthnRequest="false"
SingleSignOnServiceUrl="http://localhost:8080/am/SSORedirect/metaAlias/YourRealm/idp"
PartnerCertificateFile="Certificates\fr.cer"/>
and that part is done.
FR doesn’t seem to have a place where you can manually configure SAML so we need some SP metadata.
In the CS package under the “Metadata” folder, there is an “ExportMetadata” utility.
Run as below:
C:\>cd C:\...\SAMLSuite\SAML v2.0 for .NET\Examples\Metadata\ExportMetadata\bin\DebugC:\...\SAMLSuite\SAML v2.0 for .NET\Examples\Metadata\ExportMetadata\bin\Debug>ExportMetadata.exe
SAML configuration file to export [saml.config]: C:\...SAMLSuite\SAML v2.0 for .NET\Examples\SSO\HighLevelAPI\MVC\MvcExampleServiceProvider\saml.config
X.509 signature certificate file [None]: C:\...\SAMLSuite\SAML v2.0 for .NET\Examples\SSO\HighLevelAPI\MVC\MvcExampleServiceProvider\Certificates\fr.cer
X.509 encryption certificate file [None]:
Assertion Consumer Service URL [None]: https://localhost/MvcExampleServiceProvider/SAML/AssertionConsumerService
Single Logout Service URL [None]:
Partner Identity Provider Name [None]: http://localhost:8080/am
SAML metadata file [metadata.xml]:
Now we need to use the metadata.xml to configure FR.
Navigate to “Realm → YourRealm → Applications → Federation → Entity Providers”
Then click the “Import Entity” button.
Import the metadata file. Ignore the “fakepath” entry.
Then “OK”.
The new SP entity will be created and visible in the “Entity Providers” list.
Now we need to add the CS SP to our CoT.
In the CoT list, click the “YourRealmCoT” link. At the bottom of the page, two lists of “Available” and “Selected” entity providers are shown. Highlight the “Available” entry (containing “MvcExampleProvider”) then click “Add”.
The screenshot shows the result after the “Add”.
Click “Save” to finish updating the CoT.
Now you should see both entries as above.
Note that the “Entity Provider” term in an AM SAML context is a generic term referring to a SP or IDP.
Now let’s run the CS sample.
So click the link:
This takes us to the FR login screen.
Authenticate and:
Success!
All good!