IdP adapter
Use the IdP adapter to alter the processing of the authentication request at a particular point in the SAML journey, such as to redirect the user before SSO takes place, or before a failure response is sent.
This task assumes your environment is already correctly configured for SSO using SAML 2.0, where AM is the hosted IdP.
The IdP adapter provides hooks at the following points in assertion processing:
| Extension point | Description |
|---|---|
preSingleSignOn |
Invoked when the authentication request is first received. Only applicable to SP-initiated flows. |
preAuthentication |
Invoked before the request is redirected for authentication. Only applicable to SP-initiated flows. |
preSendResponse |
Invoked after the user has successfully authenticated or for an existing valid session, before the response is sent. |
preSignResponse |
Invoked after the response has been constructed, but before the response is signed, to let you customize the content of the SAML response. |
preSendFailureResponse |
Invoked before a SAML error response is returned. Only applicable to SP-initiated flows. |
Java example
To create a custom IdP adapter in Java, follow these high-level steps:
-
Include the
openam-federation-libraryas a dependency in your Maven project. -
Write a Java class that implements the org.forgerock.openam.saml2.plugins.IDPAdapter interface, or extends the
com.sun.identity.saml2.plugins.DefaultIDPAdapterclass. -
Override one of the methods described in the extension points table to customize the authentication journey.
-
Package your custom class in a JAR file and copy to the
/WEB-INF/libfolder where you deployed AM. -
Configure AM to use the new Java plugin.
-
In the AM admin UI, go to Realms > realm name > Applications > Federation > Entity Providers > hosted IdP > Advanced.
-
In the IDP Adapter Class field, type the fully qualified name of your custom class.
-
Save your changes.
-
-
Restart AM or the container in which it runs.
-
Test your changes using an appropriate mode of single-sign on.
For example, note that some extension points are only invoked during SP-initiated flows.
Scripted examples
Learn about IdP adapter scripts from the following resources:
- Legacy example script
- Next-generation example script
- Scripting API
Redirect a journey using a legacy script
Complete the following steps to implement an example IdP adapter script that determines whether the authentication journey should be redirected based on the evaluation of a policy.
-
For this example, configure a policy that belongs to a policy set named
saml:-
In the AM admin UI, go to Realms > realm name > Authorization > Resource Types to create a new resource type with the following values:
-
Name:
SAML SP Access -
Pattern:
* -
Action: Assert (Default State: Deny)
-
-
Go to Policy Sets to create a new policy set:
-
Id:
saml -
Name:
saml -
Resource Types:
SAML SP Access
-
-
Add a new policy:
-
Name:
SAML Access Policy -
Resource Types:
SAML SP Access -
Resources:
* -
Actions:
ASSERT:Denied -
Response Attributes:
redirect_uri: https://example.com -
Subjects:
"type": "AuthenticatedUsers"
-
-
-
To modify the default script, go to Scripts, and click SAML2 IDP Adapter Script.
Alternatively, create a new legacy script of type
Saml2 IDP Adapter.-
In the Script field, add code to the
preSendResponsefunction to redirect or send an error response if the policy for the SP evaluates to false. For example:function preSendResponse () { var frJava = JavaImporter( com.sun.identity.saml2.common.SAML2Exception); try { // set realm DN if you want to use an LDAP filter condition in the SAML access policy var env = new java.util.HashMap(); var realmDn = new java.util.HashSet(); realmDn.add("dc=am,dc=example,dc=com"); env.put("am.policy.realmDN", realmDn); var subject = idpAdapterScriptHelper.getSubjectForToken(session); var resources = idpAdapterScriptHelper.getResourcesForToken(authnRequest); var ents = idpAdapterScriptHelper.getEntitlements( "saml", realm, subject, resources, env).iterator(); while(ents.hasNext()){ var entitlement = ents.next(); var isAllowed = entitlement.getActionValue("Assert"); if(isAllowed != null && isAllowed == true){ return false; } else{ var redirectUris = entitlement.getAttributes().get("redirect_uri"); if (redirectUris == null || redirectUris.isEmpty()){ logger.error("No redirect_uri"); response.sendError(403); } else{ var redirectUri = redirectUris.iterator().next(); response.sendRedirect(redirectUri); } return true; } } } catch(error) { logger.error("Error in preSend reponse. " + error); throw new frJava.SAML2Exception(error); } } -
Validate and save your changes.
-
-
Configure AM to use the updated IdP adapter script.
-
Still in the AM admin UI, go to Applications > Federation > Entity Providers > hosted IdP > Advanced.
-
Under IDP Adapter, select your customized script from the IDP Adapter Script list.
-
Save your changes.
-
-
Test your changes using an SP-initiated flow and verify that the user is redirected to the
redirect_uri(in this example,https://example.com).
Set a custom header using a next-generation script
-
In the AM admin UI, create a new script with the following values:
- Name
-
Example Next-Generation IdP Adapter - Script Type
-
Saml2 IDP Adapter - Evaluator Version
-
Next Generation
-
In the Script field, replace the
preSendFailureResponsefunction with the following script:function preSendFailureResponse() { // set custom header in event of failure try { if (responseHelper) { responseHelper.setHeader("CUSTOM-SAML-FAILURE", "true"); } } catch (e) { logger.error("Error in preSendFailureResponse: " + e.message); } logger.error("CUSTOM-SAML-FAILURE response header set"); } -
Validate and save your changes.
-
Configure AM to use the updated IdP adapter script:
-
Go to Applications > Federation > Entity Providers > hosted IdP > Advanced.
-
Select your custom script,
Example Next-Generation IdP Adapter, from the IDP Adapter Script list. -
Save your changes.
-
-
Test your changes using an SP-initiated flow that ends in failure. Verify that the response contains the custom header, for example:
HTTP/1.1 500 X-Frame-Options: SAMEORIGIN ... CUSTOM-SAML-FAILURE: true ...