Use Authentication Trees To Create A Great SAML Login Experience

If you are shopping for a C/IAM platform these days, chances are the vendor pitch you are going to hear is all about OAuth and OIDC and JWT tokens and other shiny things for application integration, authentication, authorization, and single sign-on. And rightly so, as these standards truly offer great new capabilities or provide a modern implementation of old friends. But once the honeymoon is over and reality sets in, you are probably going to find yourself facing a majority of SAML applications and services that need integration and only a very small minority of modern applications supporting those shiny new standards.

The ForgeRock Identity Platform is an authentication broker and orchestration hub. How you come in and where you take your session is merely a matter of configuration. With the great new capabilities introduced with Authentication Trees, one might wonder how these new capabilities jive with old-timers like SAML. And wow do they jive!

With SAML there are two main scenarios per integration: Being the service provider (SP) or being the identity provider (IDP). The service provider consumes an attested identity and has limited control over how that identity was authenticated. The identity provider on the other hand dictates how identities authenticate.

Application users can start the process on the IDP side (IDP-initiated) or on the application side (SP-initiated). IDP-initiated login comes typically in the form of a portal listing all the applications the user has access to. Selecting any of these applications launches the login flow. SP-initiated flows start on the application side. Often users have bookmarked a page in the application, which requires authentication, causing the application to initiate the login flow for unauthenticated users.

This guide focuses on the SP-initiated flow and how you can use the ForgeRock Identity Platform to create the exact login experience you seek. The use case is:

“Controlling which authentication tree to launch in SP-initiated flows”.

The configuration option is a bit non-obvious and I have been asked a few times if the only way was to use the realm default authentication setting or whether there were alternatives. This is a great way to create an individual login journey for SAML users, distinct from the others.

To configure your environment, follow these steps:

  1. Follow the steps to configure SAML federation between the ForgeRock Identity Platform and your application. For this guide I configured my private Google Apps account as an SP.
  2. Test the SP-initiated flow. It should use your realm default for authentication (realm > authentication > settings > core).
  3. Now create the trees you want SAML users to use in the realm you are federating into. In this example, a tree called “saml” is the base tree that should be launched to authenticate SAML users.

    where the “Continue?” node just displays a message notifying users that they are logging in via SAML SP-initiated login. The “Login” node is an inner tree evaluator launching the “simple” tree, which lets them authenticate using username and password:

    The “2nd Factor” node is another inner tree evaluator branching out into tree, which allows the user to select a 2nd factor they want to use:

    This guide will use the “push” tree for push authentication:
  4. Now navigate to the “Authentication Context” section in your “Hosted IDP” configuration in the AM Admin UI (Applications > Federation > Entity Providers > [your hosted entity provider] > Authentication Context):

    This is where the magic happens. Select “Service” from the “Key” drop-down list on all the supported authentication contexts (note, you could launch different trees based on what the SP proposes for authentication, Google seems to only support “PasswordProtectedTransport” by default) and enter the name of the base tree you want to execute in the “Value” column, “saml” in this configuration example.

Test your configuration:

  1. Launch your SP-initiated login flow. For Google GSuite you do that by pointing your browser to https://gsuite.google.com and select “Sign-In”, then type in your GSuite domain name, select the application you want to land in after authentication and select “GO”.
  2. Google redirects to ForgeRock Access Management. The “saml” tree displays the configured message, giving users the options to “Continue” or “Abort”. Select “Continue”:
  3. The “simple” tree executes, prompting for username and password:
  4. Now the flow comes back into the “simple” tree and branches out into the 2nd Factor selector tree “select”:
  5. Select “Push” and respond to the push notification on your phone while the web user interface gracefully waits for your response:
  6. And finally, a redirect back to Google Apps with a valid SAML assertion in tow completes the SP-initiated login flow:

OpenAM SP SAML Attribute Mapper extension for updating profile attributes

OpenAM can act as both SP and IdP for SAML webSSO flows. OpenAM also provides ability to dynamically create user profiles.

When OpenAM is acting as SAML SP and Dynamic user profile is enabled, if user profile doesn’t exist on OpenAM then OpenAM dynamically creates this profile from attributes in SAML assertion.
The problem comes if user profile is updated at IdP side, all subsequent SAML webSSO flows doesn’t update these changes at OpenAM SP side. More details here: OPENAM-8340

Solution

Versions used for this implementation: OpenAM 13.5, OpenDJ 3.5

One of the solution can include extending OpenAM SP Attribute Mapper. This extension may include just checking if user profile exists in OpenAM SP and updating any modified or new attributes in OpenAM datastore. Some tips for this implementation:

  1. Extend DefaultSPAttributeMapper and override getAttributes()
  2. Get datastore provider from SAML2Utils.getDataStoreProvider()
  3. Check if user exists: dataStoreProvider.isUserExists(userID)
  4. Get existing user attributes: dataStoreProvider.getAttributes()
  5. Compare attributes in SAML assertion with existing user attributes.
  6. Finally persist any new and updated attributes: dataStoreProvider.setAttributes()

Deploy

  • Compile and deploy this extension in OpenAM under  (OpenAM-Tomcat)/webapps/openam/WEB-INF/lib
  • Change SAML attribute setting in OpenAM. Navigate to Federation > Entity Providers > (SP Hosted Entity) > Assertion Processing. Specify ‘org.forgerock.openam.saml2.plugins.examples.UpdateDynamicUserSPAttMapper’ under Attribute Mapper.
  • Restart OpenAM
  • And we are good to go! Any changes in user profile attributes in SAML assertion will now be persisted in OpenAM datastore.

Note that ideally attributes between different sources should be synced by using some tool like OpenIDM 

See Also

Get code: https://github.com/CharanMann/OpenAM-SAMLSP-updateDynamicUser
OpenAM User Profile settings: https://backstage.forgerock.com/docs/openam/13.5/admin-guide#auth-core-realm-attributes
OpenAM SAML configuration: https://backstage.forgerock.com/docs/openam/13.5/admin-guide#chap-federation

This blog post was first published @ theinfinitelooper.blogspot.com, included here with permission.

Enabling Assertion Encryption to OpenIG SAML

OpenIG SAML code is based upon the OpenAM Fedlet code which means much of the documentation and examples found around Fedlet will work for OpenIG as a Service Provider (SP) as well.  Including this very important option of encrypting assertions in the message.

A popular use-case for OpenIG is to acquire credentials from OpenAM in order to provide them to a down-stream application as a HTTP form-post.  This configuration provides a mechanism to have encrypted assertions for OpenIG without the dependencies of a policy agent or OpenAM post authentication plug-in.

Start with basic SAML configuration with OpenAM and OpenIG, detailed here:
https://backstage.forgerock.com/docs/openig/4/gateway-guide#chap-federation

Once the standard configuration is in place and tested, one can now begin the following steps in order to update the base setup to one that supports bi-directional signing and encryption.

  1. Copy key stores and file encryption to OpenIG SAML file-structure.  For production, deployment specific certifications would be deployed.  For this example, however the copy from the IDP will work.
  2. Update SAML meta-data files on location in the OpenIG SAML file-struction.
  3. Reimport the changes into OpenAM

Go to the OpenIG SAML configuration folder:  By default located here: ~/.openig/config/SAML

Add the following under the tag of <IDPSSODescriptor> for the idp.xml

        <KeyDescriptor use="signing">
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                <ds:X509Data>
                    <ds:X509Certificate>
MIIDaDCCAlCgAwIBAgIDcB/YMA0GCSqGSIb3DQEBCwUAMGUxCzAJBgNVBAYTAlVLMRAwDgYDVQQI
EwdCcmlzdG9sMRAwDgYDVQQHEwdCcmlzdG9sMRIwEAYDVQQKEwlGb3JnZVJvY2sxDzANBgNVBAsT
Bk9wZW5BTTENMAsGA1UEAxMEdGVzdDAeFw0xNjAzMTgxMTU2MjhaFw0yNjAzMTYxMTU2MjhaMGUx
CzAJBgNVBAYTAlVLMRAwDgYDVQQIEwdCcmlzdG9sMRAwDgYDVQQHEwdCcmlzdG9sMRIwEAYDVQQK
EwlGb3JnZVJvY2sxDzANBgNVBAsTBk9wZW5BTTENMAsGA1UEAxMEdGVzdDCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAKNbl89eP6B8kZATNSPe3+OZ3esLx31hjX+dakHtPwXCAaCKqJFw
jwKdxyRuPdsVG+8Dbk3PGhk26aJrSE93EpxeqmQqxNPMeD+N0/8pjkuVYWwPIQ/ts2iTiWOVn7wz
lE4ASfvupqOR5pjuYMWNo/pd4L7QNjUCKoAt9H11HMyiP+6roo/EYgX4AH7OAhfUMncYsopWhkW/
ze9z8wTXc8BAEgDmt8zFCez1CtqJB/MlSBUGDgk8oHYDsHKmx05baBaOBQ8LRGP5SULSbRtu34eL
FootBIn0FvUZSnwTiSpbaHHRgWrMOVm07oSLWBuO3h/bj38zBuuqqVsAK8YuyoECAwEAAaMhMB8w
HQYDVR0OBBYEFHxfAbr6PQ5Xgc+jVx+AGTPnnpWZMA0GCSqGSIb3DQEBCwUAA4IBAQAZBMJ29/2i
dv1ztC6ArHtB4kw/nHHwthXFwtWAN7sRPB8tLW7fD8aJ43RQr5107Bg1Lgkmt+FZxpafqUC/mukj
IzGzbW0COMSOTcWUGss+HxK6M6Fl9aOzKJMct1uOSpPFgjItcGqydGZXR2FH93vXWoAotUwtZ119
IixIdxpOJwYJg0HFn+GEfpU1PmiLfq2/uwqJ0hGCNfNcm9puagzhQrcDFOnolxjnYPSfSkU5wxlG
o99yE5eJwoHXXU7csaZVttmx7sPj1lUENogXUM6JMqzSyEIm1XCOCL8rZJkZ781W5CwZhuJTNzV3
1sBREs8FaaCeksu7Y48BmkUqw6E9
                    </ds:X509Certificate>
                </ds:X509Data>
            </ds:KeyInfo>
        </KeyDescriptor>
        <KeyDescriptor use="encryption">
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                <ds:X509Data>
                    <ds:X509Certificate>
MIIDaDCCAlCgAwIBAgIDcB/YMA0GCSqGSIb3DQEBCwUAMGUxCzAJBgNVBAYTAlVLMRAwDgYDVQQI
EwdCcmlzdG9sMRAwDgYDVQQHEwdCcmlzdG9sMRIwEAYDVQQKEwlGb3JnZVJvY2sxDzANBgNVBAsT
Bk9wZW5BTTENMAsGA1UEAxMEdGVzdDAeFw0xNjAzMTgxMTU2MjhaFw0yNjAzMTYxMTU2MjhaMGUx
CzAJBgNVBAYTAlVLMRAwDgYDVQQIEwdCcmlzdG9sMRAwDgYDVQQHEwdCcmlzdG9sMRIwEAYDVQQK
EwlGb3JnZVJvY2sxDzANBgNVBAsTBk9wZW5BTTENMAsGA1UEAxMEdGVzdDCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAKNbl89eP6B8kZATNSPe3+OZ3esLx31hjX+dakHtPwXCAaCKqJFw
jwKdxyRuPdsVG+8Dbk3PGhk26aJrSE93EpxeqmQqxNPMeD+N0/8pjkuVYWwPIQ/ts2iTiWOVn7wz
lE4ASfvupqOR5pjuYMWNo/pd4L7QNjUCKoAt9H11HMyiP+6roo/EYgX4AH7OAhfUMncYsopWhkW/
ze9z8wTXc8BAEgDmt8zFCez1CtqJB/MlSBUGDgk8oHYDsHKmx05baBaOBQ8LRGP5SULSbRtu34eL
FootBIn0FvUZSnwTiSpbaHHRgWrMOVm07oSLWBuO3h/bj38zBuuqqVsAK8YuyoECAwEAAaMhMB8w
HQYDVR0OBBYEFHxfAbr6PQ5Xgc+jVx+AGTPnnpWZMA0GCSqGSIb3DQEBCwUAA4IBAQAZBMJ29/2i
dv1ztC6ArHtB4kw/nHHwthXFwtWAN7sRPB8tLW7fD8aJ43RQr5107Bg1Lgkmt+FZxpafqUC/mukj
IzGzbW0COMSOTcWUGss+HxK6M6Fl9aOzKJMct1uOSpPFgjItcGqydGZXR2FH93vXWoAotUwtZ119
IixIdxpOJwYJg0HFn+GEfpU1PmiLfq2/uwqJ0hGCNfNcm9puagzhQrcDFOnolxjnYPSfSkU5wxlG
o99yE5eJwoHXXU7csaZVttmx7sPj1lUENogXUM6JMqzSyEIm1XCOCL8rZJkZ781W5CwZhuJTNzV3
1sBREs8FaaCeksu7Y48BmkUqw6E9
                    </ds:X509Certificate>
                </ds:X509Data>
            </ds:KeyInfo>
      <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc">
    <xenc:KeySize xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">128</xenc:KeySize>
</EncryptionMethod>
        </KeyDescriptor>

Add the following under the tag of <IDPSSOConfig> for idp-extended.xml

        <Attribute name="signingCertAlias">
            <Value>test</Value>
        </Attribute>
        <Attribute name="encryptionCertAlias">
            <Value>test</Value>
        </Attribute>

Add the following under the tag of <SPSSODescriptor> for the sp.xml

        <KeyDescriptor use="signing">
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                <ds:X509Data>
                    <ds:X509Certificate>
MIICQDCCAakCBEeNB0swDQYJKoZIhvcNAQEEBQAwZzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNh
bGlmb3JuaWExFDASBgNVBAcTC1NhbnRhIENsYXJhMQwwCgYDVQQKEwNTdW4xEDAOBgNVBAsTB09w
ZW5TU08xDTALBgNVBAMTBHRlc3QwHhcNMDgwMTE1MTkxOTM5WhcNMTgwMTEyMTkxOTM5WjBnMQsw
CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEUMBIGA1UEBxMLU2FudGEgQ2xhcmExDDAK
BgNVBAoTA1N1bjEQMA4GA1UECxMHT3BlblNTTzENMAsGA1UEAxMEdGVzdDCBnzANBgkqhkiG9w0B
AQEFAAOBjQAwgYkCgYEArSQc/U75GB2AtKhbGS5piiLkmJzqEsp64rDxbMJ+xDrye0EN/q1U5Of+
RkDsaN/igkAvV1cuXEgTL6RlafFPcUX7QxDhZBhsYF9pbwtMzi4A4su9hnxIhURebGEmxKW9qJNY
Js0Vo5+IgjxuEWnjnnVgHTs1+mq5QYTA7E6ZyL8CAwEAATANBgkqhkiG9w0BAQQFAAOBgQB3Pw/U
QzPKTPTYi9upbFXlrAKMwtFf2OW4yvGWWvlcwcNSZJmTJ8ARvVYOMEVNbsT4OFcfu2/PeYoAdiDA
cGy/F2Zuj8XJJpuQRSE6PtQqBuDEHjjmOQJ0rV/r8mO1ZCtHRhpZ5zYRjhRC9eCbjx9VrFax0JDC
/FfwWigmrW0Y0Q==
                    </ds:X509Certificate>
                </ds:X509Data>
   </ds:KeyInfo>
        </KeyDescriptor>
        <KeyDescriptor use="encryption">
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                <ds:X509Data>
                    <ds:X509Certificate>
MIICQDCCAakCBEeNB0swDQYJKoZIhvcNAQEEBQAwZzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNh
bGlmb3JuaWExFDASBgNVBAcTC1NhbnRhIENsYXJhMQwwCgYDVQQKEwNTdW4xEDAOBgNVBAsTB09w
ZW5TU08xDTALBgNVBAMTBHRlc3QwHhcNMDgwMTE1MTkxOTM5WhcNMTgwMTEyMTkxOTM5WjBnMQsw
CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEUMBIGA1UEBxMLU2FudGEgQ2xhcmExDDAK
BgNVBAoTA1N1bjEQMA4GA1UECxMHT3BlblNTTzENMAsGA1UEAxMEdGVzdDCBnzANBgkqhkiG9w0B
AQEFAAOBjQAwgYkCgYEArSQc/U75GB2AtKhbGS5piiLkmJzqEsp64rDxbMJ+xDrye0EN/q1U5Of+
RkDsaN/igkAvV1cuXEgTL6RlafFPcUX7QxDhZBhsYF9pbwtMzi4A4su9hnxIhURebGEmxKW9qJNY
Js0Vo5+IgjxuEWnjnnVgHTs1+mq5QYTA7E6ZyL8CAwEAATANBgkqhkiG9w0BAQQFAAOBgQB3Pw/U
QzPKTPTYi9upbFXlrAKMwtFf2OW4yvGWWvlcwcNSZJmTJ8ARvVYOMEVNbsT4OFcfu2/PeYoAdiDA
cGy/F2Zuj8XJJpuQRSE6PtQqBuDEHjjmOQJ0rV/r8mO1ZCtHRhpZ5zYRjhRC9eCbjx9VrFax0JDC
/FfwWigmrW0Y0Q==
                    </ds:X509Certificate>
                </ds:X509Data>
   </ds:KeyInfo>
        <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc">
   <xenc:KeySize xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">128</xenc:KeySize>
   </EncryptionMethod>
        </KeyDescriptor>

Add the following under the tag of <SPSSOConfig> for sp-extended.xml

        <Attribute name="wantAssertionEncrypted">
            <Value>true</Value>
        </Attribute>
        <Attribute name="encryptionCertAlias">
            <Value>test</Value>
        </Attribute>

WARNING: both IDP side and SP reference a certificate alias called test note that the certificates are different.   This is because default keystore for OpenAM 13.5 is the newer JCEKS while the certificate store for OpenIG is the older style JKS.  The stores contain different certificates which same alias name, do not get confused by the alias name.  For production neither of these certificates should be used.  Deployments should use own certificates. However, for testing purposes be aware of these multiple key stores.

Now in OpenAM, delete the IDP and SP entities from the console and import the changes to the SAML meta-data that was changed in place on the OpenIG side.

The only difference that needs to happen to the files prior to import. but changed back before use in OpenIG, is the hosted flag that is set in both the idp-extended.xml and sp-extended.xml

Basically the copy of the meta-data that needs to be imported back into OpenAM needs to have hosted=1 for the idp-extended.xml and hosted=0 in the sp-extended.xml metadata.  Which should be exact opposite from that of the Service Provider (OpenIG).

Restart each of the web-containers after import (OpenIG and OpenAM) and try.

Once working a SAML payload should now look like this:

<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="s2773fa280cdacc7e591189474f7c37a65c440f2ca" InResponseTo="s2be8aad955e0a068adb14260784005f5cb83f391a" Version="2.0" IssueInstant="2017-02-26T23:13:06Z" Destination="http://XXXXXXXXXX"><saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://XXXXXXXXXX</saml:Issuer><samlp:Status xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<samlp:StatusCode xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Value="urn:oasis:names:tc:SAML:2.0:status:Success">
</samlp:StatusCode>
</samlp:Status><saml:EncryptedAssertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"><xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Type="http://www.w3.org/2001/04/xmlenc#Element"><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><xenc:EncryptedKey><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/><xenc:CipherData><xenc:CipherValue>dnzVx9L58Kqe5vT6jX7OrIZUYgJH2L6vifmRKbZ+TBLsbFzz181yCAAyzQZu+tcLl2eqO+wzykOR
Py8AfwUx20L8KRfB4KgOb0yEq1y3Wpcyg/gIGd5GRjM0C17eNT61uOCpJ43qkTEtJanbhW7HEO7r
yml5bPZ74wYOBDK1NHY=</xenc:CipherValue></xenc:CipherData></xenc:EncryptedKey></ds:KeyInfo><xenc:CipherData><xenc:CipherValue>OwSwziVjZ7CntCK10iT8tFkrRoe5qy3QcEMnRhk7ipf1dgrGuQgThExmdtVohUyTdbegZs4bCCDt
6onU0ayihcDKpq3x7INOyeMh8RjYd9KTjEgh+9R+QqDisiOZMNiknxmfbV0CaDC7QaGhuqEW5zWK
jZaNMALTn42phtFhIR+Dr9yHRqjdpAeNi94EBEepypBbJhiX/5FVuwl+e6syQKSLBAoMG+jlRGKm
rQFZTcLE5+4kH5JlqTO4u/M8X56pJSOk2+O5cU1+KHYNkn4sA/1qpEP1QoL9YHvtsvtnSxSbkSbx
W2ZrzFoxKRqxVSQ0y7StX9bCRvcieUQB7kz3yVPatcTLvAZYDYBSO0aGY+Yg5kA8ishClAUxNpVx
m59NeXF3I+sZRrs2F6gpqIiQmJdsHX2VdyGNo6jSHYyBV+I+4ygfDvJQP5HkGszWkLpHX0sREaSY
xjLAENVyB6LpX/5ZfkUh6KasdjklASASDIJaljdsdnjasASDJjkdWqsRvvhwRRuo0hOs/M3mHENJ
Y3BaYZrrjaQU7u9he9cNT4q7opgSl9RZ4dEl60g6y4L/BHBxYIankw7I1v4sHCthTjaxCvUFrd4T
q6KOE2gOTvL18enrBGIxrWbm7pJWLnD3E/BsTuOPKkEOrD+WaLRPjJy8MA==</xenc:CipherValue></xenc:CipherData></xenc:EncryptedData></saml:EncryptedAssertion></samlp:Response>

References
https://backstage.forgerock.com/docs/openam/13.5/dev-guide/chap-fedlets#fedlet-signing-encryption
https://backstage.forgerock.com/docs/openig/4/gateway-guide#chap-federation

This blog post was first published @ http://nin9tyni9e.blogspot.no/, included here with permission from the author.

Using SAML Assertion Attributes in ForgeRock OpenAM – Concluding Episode: Using SAML Assertion Attributes

This blog post was first published @ www.fedji.com, included here with permission.

You’ve reached the concluding episode of a four part video made on using SAML v2 Assertion attributes in an application protected by ForgeRock OpenAM. I don’t need to mention that this being the last one in the lot, it may seem pointless to read/view this entry independently without going through the entries below, preferably in the exact same order as is listed:

1. Protecting a J2EE Application with ForgeRock OpenAM
2. Configuring Federation in ForgeRock OpenAM
3. Configuring Transient Federation in ForgeRock OpenAM
4. Using SAMLv2 Assertion Attributes

We can safely say that the diagram below is the end state of our demonstration:

image05

So what we’ve in there is a client attempting to access the protected J2EE Application, which is intercepted by the OpenAM Policy Agent, who in turn redirects the request to an IDP initiated SSO URL, resulting in a Login page to the end user from IDP. The IDP would then validate the credentials supplied by the end user, and if found authentic, sends an assertion to the SP with the user attributes (like mail, telephonenumber) specified in the Federation Configuration. Because it uses Transient Federation, the user will not have a profile in SP, still the attributes in the Assertion is available in the user’s session to be used by the Agent to pass on to the application. It may have sounded complicated, but I’m confident that the concluding episode of a rather lengthy screen-cast can help you figure it all.

I want to take a moment to Thank you! to have spent time reading/viewing my web logs on ‘Using SAML Assertion Attributes’ and sincerely hope it was useful.

Enjoy!

Using SAML Assertion Attributes in ForgeRock OpenAM – Episode 03/04 : Configuring Transient Federation in ForgeRock OpenAM

This blog post was first published @ www.fedji.com, included here with permission.

This is the third episode from a four part video made on using SAML v2 Assertion attributes in an application protected by ForgeRock OpenAM. In the interest of continuity and also to get the context accurately, it may make sense to read/view the blog posts in the following order:

1. Protecting a J2EE Application with ForgeRock OpenAM
2. Configuring Federation in ForgeRock OpenAM
3. Configuring Transient Federation in ForgeRock OpenAM
4. Using SAMLv2 Assertion Attributes

Let me throw a picture at you:

image04

The diagram is a slightly modified version of the one that you would have seen in my earlier blog entry. It has one additional user in the Identity Provider (which of course seems like a world famous detective and that’s no coincidence), but no corresponding entry in the Service Provider. In the Identity Federation Configuration earlier, we saw how a user with an id ‘demo’ in the Identity Provider linked her account with her id in the Service Provider. But there can be situations, when we may want to use Federation with identities only at the IDP, still gaining access to the applications protected by the SP. That’s where Transient Federation comes into play. It maps the identities from IDP to an anonymous user in the SP (many to one mapping).

Enjoy!

ForgeRock OpenIG as SAML 2.0 Service Provider

This blog post was first published @ www.fedji.com, included here with permission.

This post is based on the ForgeRock Documentation on configuring OpenIG as SAML 2.0 Service Provider. The video logs embedded just below this write up is a visual representation of what is already there in the document that I mentioned above. For a detailed study, please read through the documentation and then sit back, relax and watch the demonstration in the screen-cast below

SAML 2.0 as you probably know is a standard to exchange information between a SAML authority (a Identity Provider a.k.a IDP) and a SAML Consumer (a Service Provider a.k.a SP). In the demonstration that follows ForgeRock OpenAM acts as an Identity Provider and ForgeRock OpenIG acts as a Service Provider. So the authentication of a user is done by the IDP, who will then send a piece of information (Assertion) to the SP that could contain the attributes of user from the user’s profile in the IDP DataStore. SP will then use the information thus obtained (Assertion) to take further action (like giving access to the user etc.)

There are two ways of getting this done:
(i) SP initiated SSO
(ii) IDP initiated SSO

In simple words, in a SP initiated SSO, the user contacts the Service Provider, who in turns gets in touch with the Identity Provider, who would validate the user credentials and then exchange a piece of information (Assertion) that could contain the user attributes to the Service Provider. Whereas a IDP initiated SSO, the IDP will authenticate the user, and would then send an unsolicited message (Assertion) to the SP, who would then take further action (like giving access to the user etc.)

The following two illustrations might give a rough idea:

SAM2UsingOpenIG

In our story (above in the illustration and below in the video), a user authenticates against ForgeRock OpenAM (IDP), who will send then an assertion (containing user’s mail and employeenumber attribute) to ForgeRock OpenIG (Service Provider), who will apply filters (like extracting the attributes from assertion and posting it as username and password) to post the user’s credentials to a protected application (Minimal HTTP Server)

If you’ve got a vague picture on what’s discussed above, I’d believe it’ll be clearer after watching the video below:

Enjoy!

Introduction to OpenIG (Part 1: Use cases)

Welcome

You've probably landed here because you want to know something about OpenIG. This is the right place to be :)

This post is the first one of a serie of OpenIG-related articles that would gives you hand-on samples with explanations.

Identity Gateway

OpenIG stands for Open Identity Gateway, it is an identity/security specialized reverse proxy. That means that it control the access to a set of internal services.

By controling the access, I mean that it intercepts all the requests coming to the protected service (be it a RESTful API or a web application) and process them before (and after) forwarding them to the server.

Different kind of processing can be handled:

  • Request authorization
  • Capture and password replay
  • Message logging
  • Transformation

Commons use cases

Ok, that was a bit of a generalist description (transformation is intentionally vague :) ). Having some real-life use cases will help to have a better feeling/understanding of what OpenIG is capable of.

SAML Application Federation

In this use case, OpenIG acts as a SAML-enabled facade to a somehow legacy application that cannot be adapted to support SAML federation. The Identity Provider (could be OpenAM) will consider OpenIG as a standard SAML Service Provider.

SAML CoT with OpenIG used as a facade to a legacy application

Application Authentication

Here, OpenIG acts as an OpenID Connect Relying Party (OIDC terminology for client) and requires the user to authenticate to an OpenID Connect Provider (the identity provider) before giving him/her access to the protected application.

Authenticated user's profile information (such as name, email, address, picture, ...) are available to enrich the user experience, or make further verifications.

OpenID Connect - OpenIG Relying Party

RESTful Services Protection

This simple case shows OpenIG verifying request to a proxified RESTful API: each request must contains a valid OAuth 2.0 Bearer Token to be allowed to reach the service API. In this case, OpenIG acts as an OAuth 2.0 Resource Server.

Very useful if you have an old-fashioned REST API that you cannot easily update to deal with OAuth 2.0 tokens.

OAuth 2.0 - OpenIG ResourceServer

Not enough ?

Well, we're done with the 'marketing' stuff. In the next post, we will start to play with OpenIG.

See you soon!

Setting up Java Fedlet with Shibboleth IdP

The Java Fedlet is basically a lightweight SAML Service Provider (SP) implementation that can be used to add SAML support to existing Java EE applications. Today we are going to try to set up the fedlet sample application with a Shibboleth IdP (available at testshib.org).

Preparing the fedlet

There is two kind of Java fedlet in general: configured and unconfigured. The configured fedlet is what you can generate on the OpenAM admin console, and that will basically preconfigure the fedlet to use the hosted OpenAM IdP instance, and it will also set up the necessary SP settings. The unconfigured fedlet on the other hand is more like starting from scratch (as the name itself suggests :) ) and you have to perform all the configuration steps manually. To simplify things, today we are going to use the configured fedlet for our little demo.

To get a configured fedlet first you have to install OpenAM of course. Once you have an OpenAM set up, Create a new dummy Hosted IdP (to generate a fedlet it is currently required to also have a hosted IdP):

  • On the Common Tasks page click on Create Hosted Identity Provider.
  • Leave the entity ID as the default value.
  • For the name of the New Circle Of Trust enter cot.
  • Click on the Configure button.

Now to generate the configured fedlet let’s go back to the Common Tasks page and click on Create Fedlet option.

  • Here you can set the Name to any arbitrary string, this will be the fedlet’s entity ID. For the sake of simplicity let’s use the fedlet’s URL as entity ID, e.g., http://fedlet.example.com:18080/fedlet.
  • The Destination URL of the Service Provider which will include the Fedlet setting on the other hand needs to be the exact URL of the fedlet, so for me this is just a matter of copy paste: http://fedlet.example.com:18080/fedlet.
  • Click on the Create button.

This will generate a fedlet that should be available under the OpenAM configuration directory (in my case, it was under ~/openam/myfedlets/httpfedletexamplecom18080fedlet/Fedlet.zip), let’s grab this file and unzip it to a convenient location. Now we need to edit the contents of the fedlet.war itself and modify the contents of the files under the conf folder. As a first step open sp.xml and remove the RoleDescriptor and XACMLAuthzDecisionQueryDescriptor elements from the end of the XML.

At this point in time, we have everything we need for REGISTERing our fedlet on the testshib.org site, so let’s head there and upload our metadata (sp.xml), but in order to prevent clashes with other entity configurations, we should rename the sp.xml file to something more unique first, like fedlet.example.com.xml.

After successful registration the next step is to grab the testshib IdP metadata and add it to the fedlet as idp.xml, but there are some small changes we need to make on the metadata, to make it actually work with the fedlet:

  • Remove the EntitiesDescriptor wrapping element, but make sure you copy the xmlns* attributes to the EntityDescriptor element.
  • Since now the XML has two EntityDescriptor root elements, you should only keep the one made for the IdP (i.e. the one that has the “https://idp.testshib.org/idp/shibboleth” entityID), and remove the other.

The next step now is that we need to update the idp-extended.xml file by replacing the entityID attribute’s value in the EntityConfig element to the actual entity ID of the testshib instance, which should be https://idp.testshib.org/idp/shibboleth.

After all of this we should have all the standard and extended metadata files sorted, so the last thing to sort out is to set up the Circle Of Trust between the remote IdP and the fedlet. To do that we need to edit the fedlet.cot file and update the sun-fm-trusted-providers property to have the correct IdP entity ID:

cot-name=cot
sun-fm-cot-status=Active
sun-fm-trusted-providers=https://idp.testshib.org/idp/shibboleth,http://fedlet.example.com:18080/fedlet
sun-fm-saml2-readerservice-url=
sun-fm-saml2-writerservice-url=

It’s time to start the testing now, so let’s repackage the WAR (so it has all the updated configuration files) and deploy it to an actual web container. After deploying the WAR, let’s access it at http://fedlet.example.com:18080/fedlet. Since there is no fedlet home directory yet, the fedlet suggests to click on a link to create one based on the configuration in the WAR file, so let’s click on it and hope for the best. :)

Testing the fedlet

If we did everything correctly, we end up on a page finally where there are some details about the fedlet configuration, and there are also some links to initiate the authentication process. As a test let’s click on the Run Fedlet (SP) initiated Single Sign-On using HTTP POST binding one, and now we should be facing the testshib login page where you can provide one of the suggested credentials. After performing the login an error message is shown at the fedlet saying Invalid Status code in Response. After investigating a bit further, the debug logs tells us what’s going on under ~/fedlet/debug/libSAML2:

SPACSUtils.getResponse: got response=<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="_0b33f19185348a26fffe9c3a1aa6e652" InResponseTo="s2be040cf929456a64f444527dfc1d7413ce178531" Version="2.0" IssueInstant="2013-12-04T18:39:32Z" Destination="http://agent.sch.bme.hu:18080/fedlet/fedletapplication"><saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://idp.testshib.org/idp/shibboleth</saml:Issuer><samlp:Status xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<samlp:StatusCode xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
Value="urn:oasis:names:tc:SAML:2.0:status:Responder">
</samlp:StatusCode>
<samlp:StatusMessage xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
Unable to encrypt assertion
</samlp:StatusMessage>
</samlp:Status></samlp:Response>

Now we can also look into the testshib logs (see TEST tab), and that will tell us what was the real problem:

Could not resolve a key encryption credential for peer entity: http://fedlet.example.com:18080/fedlet

So this just tells us that the Shibboleth IdP tries to generate an encrypted assertion for our fedlet instance, however it fails to do so, because it is unable to determine the public certificate for the fedlet. This is happening because the basic fedlet metadata does not include a certificate by default, to remedy this let’s do the followings:

  • Acquire the PEM encoded certificate for the default OpenAM certificate:
    $ keytool -exportcert -keystore ~/openam/openam/keystore.jks -alias test -file openam.crt -rfc
  • Drop the BEGIN and the END CERTIFICATE lines from the cert, so you only have the PEM encoded data, and then you’ll need to add some extra XML around it to look something like this:
    <KeyDescriptor>
    <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:X509Data>
    <ds:X509Certificate>
    MIICQDCC...
    </ds:X509Certificate>
    </ds:X509Data>
    </ds:KeyInfo>
    </KeyDescriptor>
    
  • Add the KeyDescriptor under the SPSSODescriptor as a first element.
  • Upload the updated SP metadata with the same filename (fedlet.example.com.xml) again at the testshib site.

Since the decryption process requires the presence of the private key of the certificate, we need to ensure that the private key is available, so let’s do the followings:

  • Copy the ~/openam/openam/keystore.jks file to the fedlet home directory
  • Visit the http://fedlet.example.com:18080/fedlet/fedletEncode.jsp page and enter changeit (the password of the default keystore and private key as well).
  • Grab the encrypted value and create ~/fedlet/.storepass and ~/fedlet/.keypass files containing only the encrypted password.
  • Open up ~/fedlet/sp-extended.xml and ensure that the encryptionCertAlias setting has the value of test.
  • Restart the container, so the changes are picked up.

At this stage we should retry the login process again, and if nothing went wrong you can see all the nice details of the received SAML assertion from testshib.org! It Works! :)

Identity & Access Management: Give Me a REST

Give me a REST (or two weeks stay in a villa in Portugal if you're asking...).  RESTful architectures have been the general buzz of websites for the last few years.  The simplicity, scalability and statelessness of this approach to client-server communications has been adopted by many of the top social sites such as Twitter and Facebook.  Why?  Well, in their specific cases, developer adoption is a huge priority.  Getting as many Twitter clients or Facebook apps released, increases the overall attractiveness of those services and in a world where website and service competition is as high as ever, that is a key position to sustain.


Why REST?

Cute picture of RESTing lion [1]
The evolution and move to REST is quite a clear one from a benefits and adoption perspective.  REST re-uses many of the standard HTTP protocol verbs such as GET, POST and DELETE,  when constructing URL's.  These verbs are well understood and well used, so there's no new syntactic sugar to swallow.  Each component of the service owners database is abstracted into neatly described resources that can be accessed using the appropriate URI.  Requests can then be made to return, say, a JSON or XML representation of the underlying database object.



The client, permission granted, can then in turn update or create a new object in the same way, by sending a new JSON object via a PUT or POST request.

What's This Got To Do With IAM?

Identity management has often been thought of as an enterprise or organizational problem, focussing on the the creation and management of company email, mainframe and ERP system accounts.  This process then brought all the complexity of business workflow definition, compliance, audit, system integration and so on.  Access management on the other hand, has often been focused on single-sign-on, basic authorization and web protection.  IAM today is a much more complex and far reaching beast.  

Organizations are reaching out into the cloud for services, API's and applications.  Service providers and applications are becoming identity providers in their own right, reaching back out to consumers and businesses alike.  For once, identity management is on the tip of the tongue of the most tech-avoiding consumers, concerned with privacy, their online-identities and how they can be managed and consumed.

A RESTful Future

These new approaches to identity and access management require rapid integration, developer adoption and engine-like API's that can perform in an agile, scalable and secure fashion.  Identity and access management services for consumers, such as being able to login with their Facebook or Twitter account using OAuth or OAuth2 without having to create and manage multiple passwords for the other sites they interact with, not only increases user convenience.  It also puts pressure on business security strategies as they can struggle to cope with the ability for employees to bring-their-own-identity to many of the now popular business services such as Webex, Dropbox, Salesforce and the like.

As identity management is no longer solely concerned with siloed, business unit or organisational boundaries and looking more to being fully connected, integrated and focused on consumerization, developer adoption has never been more important.  Security in general, has never been a high priority for application builders, who are more centred on features and end usability.

Identity and access management is making a big change to that area with many access management systems being easy to externalize from application logic using RESTful integration.


By Simon Moffatt

[1] - Image attribute Stock.Xchng http://www.sxc.hu/profile.big_foot