IG 2023.2

SAML

SAML 2.0 single sign-on and federation

The IG federation component implements SAML 2.0, to validate users and log them in to protected applications.

The SAML 2.0 standard describes the messages that providers exchange, and how they exchange them. SAML 2.0 enables web SSO, for example, where the service managing the user’s identity does not belong to the same organization and does not use the same software as the service that the user wants to access.

The following terms are used in SAML and federation:

  • Identity Provider (IDP): The service that manages the user identity, for example AM.

  • Service Provider (SP): The service that a user wants to access. IG acts as a SAML 2.0 SP for SSO, providing an interface to applications that don’t support SAML 2.0.

  • Circle of trust (CoT): An IDP and SP that participate in the federation.

When an IDP and an SP participate in a federation, they agree on what security information to exchange, and mutually configure access to each other’s services.

After an IDP authenticates a user, it provides the SP with SAML assertions that attest to which user is authenticated, when the authentication succeeded, how long the assertion is valid, and so on. The SP uses the SAML assertions to make authorization decisions, for example, to let an authenticated user complete a purchase that gets charged to the user’s account at the IDP.

The IDP and SP usually communicate about a user identified by a name identifier. In SP-initiated SSO and IDP-initiated SSO, the NameID format can be any format supported by the IDP. For more information, refer to Use a non-transient NameID format.

SAML assertions can be signed and encrypted. ForgeRock recommends using *SHA-256 variants (rsa-sha256 or ecdsa-sha256).

SAML assertions can contain configurable attribute values, such as user meta-information or anything else provided by the IDP. The attributes of a SAML assertion can contain one or more values, made available as a list of strings. Even if an attribute contains a single value, it is made available as a list of strings.

SAML in deployments with multiple instances of IG

IG uses a Java fedlet to implement SAML. When IG acts as a SAML service provider, the session information is stored in the fedlet, not the session cookie. In deployments that use multiple instances of IG as a SAML service provider, it is therefore necessary to set up sticky sessions so that requests always hit the instance where the SAML interaction was started.

For information, refer to Session state considerations in AM’s SAML v2.0 guide.

About SP-initiated SSO

SP-initiated SSO occurs when a user attempts to access a protected application directly through the SP. Because the user’s federated identity is managed by the IDP, the SP sends a SAML authentication request to the IDP. After the IDP authenticates the user, it provides the SP with a SAML assertion for the user.

The following sequence diagram shows the flow of information in SP-initiated SSO, when IG acts as a SAML 2.0 SP:

saml-sp-initiated

About IDP-initiated SSO

IDP-initiated SSO occurs when a user attempts to access a protected application, using the IDP for authentication. The IDP sends an unsolicited authentication statement to the SP.

Before IDP-initiated SSO can occur:

  • The user must access a link on the IDP that refers to the remote SP.

  • The user must authenticate to the IDP.

  • The IDP must be configured with links that refer to the SP.

The following sequence diagram shows the flow of information in IDP-initiated SSO when IG acts as a SAML 2.0 SP:

saml-idp-initiated

Set up federation with unsigned/unencrypted assertions

For examples of the federation configuration files, refer to Example fedlet files. To set up multiple SPs, work through this section, and then SAML 2.0 and multiple applications.

  1. Set up the network:

    Add sp.example.com to your /etc/hosts file:

    127.0.0.1 localhost am.example.com ig.example.com app.example.com sp.example.com

    Traffic to the application is proxied through IG, using the host name sp.example.com.

  2. Configure a Java Fedlet:

    The SAML library component validates the SP’s AssertionConsumerService Location against the incoming IDP SAML Assertion, based on the request information, including the port. In sp.xml, always specify the port in the Location value of AssertionConsumerService, even when using defaults of 443 or 80, as follows:

    <AssertionConsumerService isDefault="true"
                              index="0"
                              Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
                              Location="https://sp.example.com:443/fedletapplication" />

    For more information about Java Fedlets, refer to Creating and configuring the fedlet in AM’s SAML v2.0 guide.

    1. Copy and unzip the fedlet zip file, Fedlet-7.3.0.zip, delivered with the AM installation, into a local directory.

      $ unzip $HOME/openam/Fedlet-7.3.0.zip
      
      Archive:  Fedlet-7.3.0.zip
      creating: conf/
      inflating: README
      inflating: conf/FederationConfig.properties
      inflating: conf/fedlet.cot-template
      inflating: conf/idp-extended.xml-template
      inflating: conf/sp-extended.xml-template
      inflating: conf/sp.xml-template
      inflating: fedlet.war
    2. For AM 6.5.2 and earlier versions, add the following lines to FederationConfig.properties :

      # Specifies implementation for
      # org.forgerock.openam.federation.plugin.rooturl.RootUrlProvider interface.
      # This property defines the default base url provider.
      com.sun.identity.plugin.root.url.class.default=org.forgerock.openam.federation.plugin.rooturl.impl.FedletRootUrlProvider
    3. In each file, search and replace the following properties:

      Replace this With this

      IDP_ENTITY_ID

      openam

      FEDLET_ENTITY_ID

      sp

      FEDLET_PROTOCOL://FEDLET_HOST:FEDLET_PORT/FEDLET_DEPLOY_URI

      http://sp.example.com:8080/saml

      fedletcot and FEDLET_COT

      Circle of Trust

      sp.example.com:8080/saml/fedletapplication

      sp.example.com:8080/saml/fedletapplication/metaAlias/sp

    4. Save the files as .xml, without the -template extension, so that the directory looks like this:

      conf
      ├── FederationConfig.properties
      ├── fedlet.cot
      ├── idp-extended.xml
      ├── sp-extended.xml
      └── sp.xml

      By default, AM as an IDP uses the NameID format urn:oasis:names:tc:SAML:2.0:nameid-format:transient to communicate about a user. For information about using a different NameID format, refer to Use a Non-Transient NameID Format.

  3. Set up AM:

    1. Select Identities, select the user demo, and change the last name to Ch4ng31t. Note that, for this example, the last name must be the same as the password.

    2. Select Applications > Federation > Circles of Trust, and add a circle of trust called Circle of Trust, with the default settings.

    3. Set up a remote service provider:

      1. Select Applications > Federation > Entity Providers, and add a remote entity provider.

      2. Drag in or import sp.xml created in the previous step.

      3. Select Circles of Trust: Circle of Trust.

    4. Set up a hosted identity provider:

      1. Select Applications > Federation > Entity Providers, and add a hosted entity provider with the following values:

        • Entity ID: openam

        • Entity Provider Base URL: http://am.example.com:8088/openam

        • Identity Provider Meta Alias: idp

        • Circles of Trust: Circle of Trust

      2. Select Assertion Processing > Attribute Mapper, map the following SAML attribute keys and values, and then save your changes:

        • SAML Attribute: cn, Local Attribute: cn

        • SAML Attribute: sn, Local Attribute: sn

      3. In a terminal, export the XML-based metadata for the IDP:

        $ curl -v \
        --output idp.xml \
        "http://am.example.com:8088/openam/saml2/jsp/exportmetadata.jsp?entityid=openam"

        The idp.xml file is created locally.

  4. Set up IG:

    1. Copy the edited fedlet files, and the exported idp.xml file into the IG configuration, at $HOME/.openig/SAML.

      $ ls -l $HOME/.openig/SAML
      
      FederationConfig.properties
      fedlet.cot
      idp-extended.xml
      idp.xml
      sp-extended.xml
      sp.xml
    2. In config.json, comment out or remove the baseURI:

      {
        "handler": {
          "_baseURI": "http://app.example.com:8081",
          ...
        }
      }

      Requests to the SamlFederationHandler must not be rebased, because the request URI must match the endpoint in the SAML metadata.

    3. Add the following route to IG, to serve .css and other static resources for the sample application:

      • Linux

      • Windows

      $HOME/.openig/config/routes/static-resources.json
      appdata\OpenIG\config\routes\static-resources.json
      {
        "name" : "sampleapp-resources",
        "baseURI" : "http://app.example.com:8081",
        "condition": "${find(request.uri.path,'^/css')}",
        "handler": "ReverseProxyHandler"
      }
    4. Add the following route to IG:

      • Linux

      • Windows

      $HOME/.openig/config/routes/saml.json
      appdata\OpenIG\config\routes\saml.json
      {
        "name": "saml",
        "condition": "${find(request.uri.path, '^/saml')}",
        "session": "JwtSession",
        "handler": {
          "type": "SamlFederationHandler",
          "config": {
            "useOriginalUri": true,
            "assertionMapping": {
              "username": "cn",
              "password": "sn"
            },
            "subjectMapping": "sp-subject-name",
            "redirectURI": "/home/federate"
          }
        }
      }

      Notice the following features of the route:

      • The route matches requests to /saml.

      • After authentication, the SamlFederationHandler extracts cn and sn from the SAML assertion, and maps them to the SessionContext, at session.username and session.password.

      • The handler stores the subject name as a string in the session field session.sp-subject-name, which is named by the subjectMapping property. By default, the subject name is stored in the session field session.subjectName.

      • The handler redirects the request to the /federate route.

      • The route uses the JwtSession implementation, meaning it stores encrypted session information in a browser cookie. The name is a reference to the JwtSession object defined in config.json. For information, see JwtSession.

    5. Add the following route to IG:

      • Linux

      • Windows

      $HOME/.openig/config/routes/federate.json
      appdata\OpenIG\config\routes\federate.json
      {
        "name": "federate",
        "condition": "${find(request.uri.path, '^/home/federate')}",
        "session": "JwtSession",
        "baseURI": "http://app.example.com:8081",
        "handler": {
          "type": "DispatchHandler",
          "config": {
            "bindings": [
              {
                "condition": "${empty session.username}",
                "handler": {
                  "type": "StaticResponseHandler",
                  "config": {
                    "status": 302,
                    "headers": {
                      "Location": [
                        "http://sp.example.com:8080/saml/SPInitiatedSSO?metaAlias=/sp"
                      ]
                    }
                  }
                }
              },
              {
                "handler": {
                  "type": "Chain",
                  "config": {
                    "filters": [
                      {
                        "type": "HeaderFilter",
                        "config": {
                          "messageType": "REQUEST",
                          "add": {
                            "x-username": ["${session.username[0]}"],
                            "x-password": ["${session.password[0]}"]
                          }
                        }
                      }
                    ],
                    "handler": "ReverseProxyHandler"
                  }
                }
              }
            ]
          }
        }
      }

      Notice the following features of the route:

      • The route matches requests to /home/federate.

      • If the user is not authenticated with AM, the username is not populated in the context. The DispatchHandler then dispatches the request to the StaticResponseHandler, which redirects it to the SP-initiated SSO endpoint.

        If the credentials are in the context, or after successful authentication, the DispatchHandler dispatches the request to the Chain.

      • The HeaderFilter adds headers for the first value for the username and password attributes of the SAML assertion.

      • The route uses the JwtSession implementation, meaning it stores encrypted session information in a browser cookie. The name is a reference to the JwtSession object defined in config.json. For information, see JwtSession.

    6. Restart IG.

  5. Test the setup:

    1. Log out of AM, and test the setup with the following links:

    2. Log in to AM with username demo and password Ch4ng31t.

      IG returns the response page showing that the the demo user has logged in.

For more control over the URL where the user agent is redirected, use the RelayState query string parameter in the URL of the redirect Location header. RelayState specifies where to redirect the user when the SAML 2.0 web browser SSO process is complete. It overrides the redirectURI set in the SamlFederationHandler.

The RelayState value must be URL-encoded. When using an expression, use a function to encode the value. For example, use ${urlEncodeQueryParameterNameOrValue(contexts.router.originalUri)}.

In the following example, the user is finally redirected to the original URI from the request:

"headers": {
  "Location": [
    "http://ig.example.com:8080/saml/SPInitiatedSSO?RelayState=${urlEncodeQueryParameterNameOrValue(contexts.router.originalUri)}"
  ]
}

Set up federation with signed/encrypted assertions

  1. Set up the example in Set up federation with unsigned/unencrypted assertions.

  2. Set up the SAML keystore:

    1. Find the values of AM’s default SAML keypass and storepass:

      $ more /path/to/am/security/secrets/default/.keypass
      $ more /path/to/am/security/secrets/default/.storepass
    2. Copy the SAML keystore from the AM configuration to IG:

      $ cp /path/to/am/security/keystores/keystore.jceks /path/to/ig/keystore.jceks
      Legacy keystore types such as JKS and JCEKS are supported but are not secure. Consider using the PKCS#12 keystore type.
  3. Configure the Fedlet in IG:

    1. In FederationConfig.properties, make the following changes:

      1. Delete the following lines:

        • com.sun.identity.saml.xmlsig.keystore=%BASE_DIR%/security/keystores/keystore.jks

        • com.sun.identity.saml.xmlsig.storepass=%BASE_DIR%/.storepass

        • com.sun.identity.saml.xmlsig.keypass=%BASE_DIR%/.keypass

        • com.sun.identity.saml.xmlsig.certalias=test

        • com.sun.identity.saml.xmlsig.storetype=JKS

        • am.encryption.pwd=@AM_ENC_PWD@

      2. Add the following line:

        org.forgerock.openam.saml2.credential.resolver.class=org.forgerock.openig.handler.saml.SecretsSaml2CredentialResolver

        This class is responsible for resolving secrets and supplying credentials.

        Be sure to leave no space at the end of the line.
    2. In sp.xml, make the following changes:

      1. Change AuthnRequestsSigned="false" to AuthnRequestsSigned="true".

      2. Add the following KeyDescriptor just before </SPSSODescriptor>

                <KeyDescriptor use="signing">
                    <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#" >
                        <ds:X509Data>
                            <ds:X509Certificate>
        
                            </ds:X509Certificate>
                        </ds:X509Data>
                    </ds:KeyInfo>
                </KeyDescriptor>
            </SPSSODescriptor>
      3. Copy the value of the signing certificate from idp.xml to this file:

        <KeyDescriptor use="signing">
          <ds:KeyInfo>
            <ds:X509Data>
              <ds:X509Certificate>
        
                MII...zA6
        
              </ds:X509Certificate>

        This is the public key used for signing so that the IDP can verify request signatures.

  4. Replace the remote service provider in AM:

    1. Select Applications > Federation > Entity Providers, and remove the sp entity provider.

    2. Drag in or import the new sp.xml updated in the previous step.

    3. Select Circles of Trust: Circle of Trust.

  5. Set up IG:

    1. In the IG configuration, set environment variables for the following secrets, and then restart IG:

      $ export KEYSTORE_SECRET_ID='a2V5c3RvcmU='
      $ export SAML_KEYSTORE_STOREPASS_SECRET_ID='<base64-encoded value of the SAML storepass>'
      $ export SAML_KEYSTORE_KEYPASS_SECRET_ID='<base64-encoded value of the SAML keypass>'

      The passwords are retrieved by a SystemAndEnvSecretStore, and must be base64-encoded.

    2. Remove saml.json from the configuration, and add the following route, replacing the path to keystore.jceks with your path:

      • Linux

      • Windows

      $HOME/.openig/config/routes/saml-secure.json
      appdata\OpenIG\config\routes\saml-secure.json
      {
        "name": "saml-secure",
        "condition": "${find(request.uri.path, '^/saml')}",
        "session": "JwtSession",
        "heap": [
          {
            "name": "SystemAndEnvSecretStore-1",
            "type": "SystemAndEnvSecretStore"
          },
          {
            "name": "KeyStoreSecretStore-1",
            "type" : "KeyStoreSecretStore",
            "config" : {
              "file" : "/path/to/ig/keystore.jceks",
              "storeType" : "jceks",
              "storePasswordSecretId" : "saml.keystore.storepass.secret.id",
              "entryPasswordSecretId" : "saml.keystore.keypass.secret.id",
              "secretsProvider" : "SystemAndEnvSecretStore-1",
              "mappings" : [ {
                "secretId" : "sp.signing.sp",
                "aliases" : [ "rsajwtsigningkey" ]
              }, {
                "secretId" : "sp.decryption.sp",
                "aliases" : [ "test" ]
              } ]
            }
          }
        ],
        "handler": {
          "type": "SamlFederationHandler",
          "config": {
            "useOriginalUri": true,
            "assertionMapping": {
              "username": "cn",
              "password": "sn"
            },
            "subjectMapping": "sp-subject-name",
            "redirectURI": "/home/federate",
            "secretsProvider" : "KeyStoreSecretStore-1"
          }
        }
      }

      Notice the following features of the route compared to saml.json:

      • The SamlFederationHandler refers to the KeyStoreSecretStore to provide the keys for the signed and encrypted SAML assertions.

      • The secret IDs, sp.signing.sp and sp.decryption.sp, follow a naming convention based on the name of the service provider, sp.

      • The alias for the signing key corresponds to the PEM in keystore.jceks.

    3. Restart IG.

  6. Test the setup:

    1. Log out of AM, and test the setup with the following links:

    2. Log in to AM with username demo and password Ch4ng31t.

      IG returns the response page showing that the the demo user has logged in.

Use a non-transient NameID format

By default, AM as an IDP uses the NameID format urn:oasis:names:tc:SAML:2.0:nameid-format:transient. For more information, refer to Hosted identity provider configuration properties in AM’s SAML v2.0 guide.

When the IDP uses another NameID format, configure IG to use that NameID format by editing the Fedlet configuration file sp-extended.xml:

  • To use the NameID value provided by the IDP, add the following attribute:

    <Attribute name="useNameIDAsSPUserID">
      <Value>true</Value>
    </Attribute>
  • To use an attribute from the assertion, add the following attribute:

    <Attribute name="autofedEnabled">
      <Value>true</Value>
    </Attribute>
    <Attribute name="autofedAttribute">
      <Value>sn</Value>
    </Attribute>

    This example uses the value in SN to identify the subject.

Although IG supports the persistent NameID format, IG does not store the mapping. To configure this behavior, edit the file sp-extended.xml:

  • To disable attempts to persist the user mapping, add the following attribute:

    <Attribute name="spDoNotWriteFederationInfo">
      <Value>true</Value>
    </Attribute>
  • To enable attempts to persist the user mapping, add the following attribute:

    <Attribute name="spDoNotWriteFederationInfo">
      <Value>false</Value>
    </Attribute>

If a login request doesn’t contain a NameID format query parameter, the value is defined by the presence and content of the NameID format list for the SP and IDP. For example, an SP-initiated login can be constructed with the binding and NameIDFormat as a parameter, as follows:

http://fedlet.example.org:7070/fedlet/SPInitiatedSSO?binding=urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST&NameIDFormat=urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified

When the NameID format is provided in a list, it is resolved as follows:

  • If both the IDP and SP have a list, the first matching NameID format in the lists.

  • If either the IDP or SP list is empty, the first NameID format in the other list.

  • If neither the IDP nor SP has a list, then AM defaults to transient, and IG defaults to persistent.

Example fedlet files

File Description

FederationConfig.properties

Fedlet properties

fedlet.cot

Circle of trust for IG and the IDP

idp.xml

Standard metadata for the IDP

idp-extended.xml

Metadata extensions for the IDP

sp.xml

Standard metadata for the IG SP

sp-extended.xml

Metadata extensions for the IG SP

FederationConfig.properties

The following example of $HOME/.openig/SAML/FederationConfig.properties defines the fedlet properties:

#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
#
# Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved
#
# The contents of this file are subject to the terms
# of the Common Development and Distribution License
# (the License). You may not use this file except in
# compliance with the License.
#
# You can obtain a copy of the License at
# https://opensso.dev.java.net/public/CDDLv1.0.html or
# opensso/legal/CDDLv1.0.txt
# See the License for the specific language governing
# permission and limitations under the License.
#
# When distributing Covered Code, include this CDDL
# Header Notice in each file and include the License file
# at opensso/legal/CDDLv1.0.txt.
# If applicable, add the following below the CDDL Header,
# with the fields enclosed by brackets [] replaced by
# your own identifying information:
# "Portions Copyrighted [year] [name of copyright owner]"
#
# $Id: FederationConfig.properties,v 1.21 2010/01/08 22:41:28 exu Exp $
#
# Portions Copyright 2016-2023 ForgeRock AS.

# If a component wants to use a different datastore provider than the
# default one defined above, it can define a property like follows:
# com.sun.identity.plugin.datastore.class.<componentName>=<provider class>

# com.sun.identity.plugin.configuration.class specifies implementation for
# com.sun.identity.plugin.configuration.ConfigurationInstance interface.
com.sun.identity.plugin.configuration.class=com.sun.identity.plugin.configuration.impl.FedletConfigurationImpl

# Specifies implementation for
# com.sun.identity.plugin.datastore.DataStoreProvider interface.
# This property defines the default datastore provider.
com.sun.identity.plugin.datastore.class.default=com.sun.identity.plugin.datastore.impl.FedletDataStoreProvider

# Specifies implementation for
# org.forgerock.openam.federation.plugin.rooturl.RootUrlProvider interface.
# This property defines the default base url provider.
com.sun.identity.plugin.root.url.class.default=org.forgerock.openam.federation.plugin.rooturl.impl.FedletRootUrlProvider

# com.sun.identity.plugin.log.class specifies implementation for
# com.sun.identity.plugin.log.Logger interface.
com.sun.identity.plugin.log.class=com.sun.identity.plugin.log.impl.FedletLogger

# com.sun.identity.plugin.session.class specifies implementation for
# com.sun.identity.plugin.session.SessionProvider interface.
com.sun.identity.plugin.session.class=com.sun.identity.plugin.session.impl.FedletSessionProvider

# com.sun.identity.plugin.monitoring.agent.class specifies implementation for
# com.sun.identity.plugin.monitoring.FedMonAgent interface.
com.sun.identity.plugin.monitoring.agent.class=com.sun.identity.plugin.monitoring.impl.FedletAgentProvider

# com.sun.identity.plugin.monitoring.saml2.class specifies implementation for
# com.sun.identity.plugin.monitoring.FedMonSAML2Svc interface.
com.sun.identity.plugin.monitoring.saml2.class=com.sun.identity.plugin.monitoring.impl.FedletMonSAML2SvcProvider

# com.sun.identity.saml.xmlsig.keyprovider.class specified the implementation
# class for com.sun.identity.saml.xmlsig.KeyProvider interface
com.sun.identity.saml.xmlsig.keyprovider.class=com.sun.identity.saml.xmlsig.JKSKeyProvider

# com.sun.identity.saml.xmlsig.signatureprovider.class specified the
# implementation class for com.sun.identity.saml.xmlsig.SignatureProvider
# interface
com.sun.identity.saml.xmlsig.signatureprovider.class=com.sun.identity.saml.xmlsig.AMSignatureProvider

com.iplanet.am.server.protocol=http
com.iplanet.am.server.host=am.example.com
com.iplanet.am.server.port=8080
com.iplanet.am.services.deploymentDescriptor=/openam
com.iplanet.am.logstatus=ACTIVE

# Name of the webcontainer.
# Even though the servlet/JSP are web container independent,
# Access/Federation Manager uses servlet 2.3 API request.setCharacterEncoding()
# to decode incoming non English characters. These APIs will not work if
# Access/Federation Manager is deployed on Sun Java System Web Server 6.1.
# We use gx_charset mechanism to correctly decode incoming data in
# Sun Java System Web Server 6.1 and S1AS7.0. Possible values
# are BEA6.1, BEA 8.1, IBM5.1 or IAS7.0.
# If the web container is Sun Java System Webserver, the tag is not replaced.
com.sun.identity.webcontainer=WEB_CONTAINER

# Identify saml xml signature keystore file, keystore password file
# key password file
com.sun.identity.saml.xmlsig.keystore=%BASE_DIR%/security/keystores/keystore.jks
com.sun.identity.saml.xmlsig.storepass=%BASE_DIR%/.storepass
com.sun.identity.saml.xmlsig.keypass=%BASE_DIR%/.keypass
com.sun.identity.saml.xmlsig.certalias=test

# Type of keystore used for saml xml signature. Default is JKS.
#
# com.sun.identity.saml.xmlsig.storetype=JKS

# Specifies the implementation class for
# com.sun.identity.saml.xmlsig.PasswordDecoder interface.
com.sun.identity.saml.xmlsig.passwordDecoder=com.sun.identity.fedlet.FedletEncodeDecode

# The following key is used to specify the maximum content-length
# for an HttpRequest that will be accepted by the OpenSSO
# The default value is 16384 which is 16k
com.iplanet.services.comm.server.pllrequest.maxContentLength=16384

# The following keys are used to configure the Debug service.
# Possible values for the key 'level' are: off | error | warning | message.
# The key 'directory' specifies the output directory where the debug files
# will be created.
# Trailing spaces are significant.
# Windows: Use forward slashes "/" separate directories, not backslash "\".
# Windows: Spaces in the file name are allowed for Windows.
#
com.iplanet.services.debug.level=message
com.iplanet.services.debug.directory=%BASE_DIR%%SERVER_URI%/debug

# The following keys are used to configure the Stats service.
# Possible values for the key 'level' are: off | file | console
# Stats state 'file' will write to a file under the specified directory,
# and 'console' will write into  webserver log files
# The key 'directory' specifies the output directory where the debug files
# will be created.
# Trailing spaces are significant.
# Windows: Use forward slashes "/" separate directories, not backslash "\".
# Windows: Spaces in the file name are allowed for Windows.
# Stats interval should be atleast 5 secs to avoid CPU saturation,
# the product would assume any thing less than 5 secs is 5 secs.
com.iplanet.am.stats.interval=60
com.iplanet.services.stats.state=file
com.iplanet.services.stats.directory=%BASE_DIR%/var/stats

# The key that will be used to encrypt and decrypt passwords.
am.encryption.pwd=@AM_ENC_PWD@

# SecureRandom Properties: The key
# "com.iplanet.security.SecureRandomFactoryImpl"
# specifies the factory class name for SecureRandomFactory
# Available impl classes are:
#   com.iplanet.am.util.JSSSecureRandomFactoryImpl (uses JSS)
#   com.iplanet.am.util.SecureRandomFactoryImpl (pure Java)
com.iplanet.security.SecureRandomFactoryImpl=com.iplanet.am.util.SecureRandomFactoryImpl

# SocketFactory properties: The key "com.iplanet.security.SSLSocketFactoryImpl"
# specifies the factory class name for LDAPSocketFactory
# Available classes are:
#    com.iplanet.services.ldap.JSSSocketFactory (uses JSS)
#    com.sun.identity.shared.ldap.factory.JSSESocketFactory    (pure Java)
com.iplanet.security.SSLSocketFactoryImpl=com.sun.identity.shared.ldap.factory.JSSESocketFactory

# Encryption: The key "com.iplanet.security.encryptor" specifies
# the encrypting class implementation.
# Available classes are:
#    com.iplanet.services.util.JCEEncryption
#    com.iplanet.services.util.JSSEncryption
com.iplanet.security.encryptor=com.iplanet.services.util.JCEEncryption

# Determines if JSS will be added with highest priority to JCE
# Set this to "true" if other JCE providers should be used for
# digial signatures and encryptions.
com.sun.identity.jss.donotInstallAtHighestPriority=true

# Configuration File (serverconfig.xml) Location
com.iplanet.services.configpath=@BASE_DIR@
fedlet.cot

The following example of $HOME/.openig/SAML/fedlet.cot defines a circle of trust between AM as the IDP, and IG as the SP:

cot-name=Circle of Trust
sun-fm-cot-status=Active
sun-fm-trusted-providers=openam, sp
sun-fm-saml2-readerservice-url=
sun-fm-saml2-writerservice-url=
idp.xml

The following example of $HOME/.openig/SAML/idp.xml defines a SAML configuration file for the AM IDP, idp:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<EntityDescriptor entityID="openam" 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:xenc11="http://www.w3.org/2009/xmlenc11#" xmlns:alg="urn:oasis:names:tc:SAML:metadata:algsupport" xmlns:x509qry="urn:oasis:names:tc:SAML:metadata:X509:query" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
        <KeyDescriptor use="signing">
            <ds:KeyInfo>
                <ds:X509Data>
                    <ds:X509Certificate>
...
                    </ds:X509Certificate>
                </ds:X509Data>
            </ds:KeyInfo>
        </KeyDescriptor>
        <KeyDescriptor use="encryption">
            <ds:KeyInfo>
                <ds:X509Data>
                    <ds:X509Certificate>
...
                    </ds:X509Certificate>
                </ds:X509Data>
            </ds:KeyInfo>
            <EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#rsa-oaep">
                <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
                <xenc11:MGF Algorithm="http://www.w3.org/2009/xmlenc11#mgf1sha256"/>
            </EncryptionMethod>
            <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc">
                <xenc:KeySize>128</xenc:KeySize>
            </EncryptionMethod>
        </KeyDescriptor>
        <ArtifactResolutionService index="0" Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://am.example.com:8088/openam/ArtifactResolver/metaAlias/idp"/>
        <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://am.example.com:8088/openam/IDPSloRedirect/metaAlias/idp" ResponseLocation="http://am.example.com:8088/openam/IDPSloRedirect/metaAlias/idp"/>
        <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://am.example.com:8088/openam/IDPSloPOST/metaAlias/idp" ResponseLocation="http://am.example.com:8088/openam/IDPSloPOST/metaAlias/idp"/>
        <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://am.example.com:8088/openam/IDPSloSoap/metaAlias/idp"/>
        <ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://am.example.com:8088/openam/IDPMniRedirect/metaAlias/idp" ResponseLocation="http://am.example.com:8088/openam/IDPMniRedirect/metaAlias/idp"/>
        <ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://am.example.com:8088/openam/IDPMniPOST/metaAlias/idp" ResponseLocation="http://am.example.com:8088/openam/IDPMniPOST/metaAlias/idp"/>
        <ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://am.example.com:8088/openam/IDPMniSoap/metaAlias/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://am.example.com:8088/openam/SSORedirect/metaAlias/idp"/>
        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://am.example.com:8088/openam/SSOPOST/metaAlias/idp"/>
        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://am.example.com:8088/openam/SSOSoap/metaAlias/idp"/>
        <NameIDMappingService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://am.example.com:8088/openam/NIMSoap/metaAlias/idp"/>
        <AssertionIDRequestService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://am.example.com:8088/openam/AIDReqSoap/IDPRole/metaAlias/idp"/>
        <AssertionIDRequestService Binding="urn:oasis:names:tc:SAML:2.0:bindings:URI" Location="http://am.example.com:8088/openam/AIDReqUri/IDPRole/metaAlias/idp"/>
    </IDPSSODescriptor>
</EntityDescriptor>
idp-extended.xml

The following example of $HOME/.openig/SAML/idp-extended.xml defines an AM-specific SAML descriptor file for the IDP:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
   DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.

   Copyright (c) 2002-2010 Sun Microsystems Inc. All Rights Reserved

   The contents of this file are subject to the terms
   of the Common Development and Distribution License
   (the License). You may not use this file except in
   compliance with the License.

   You can obtain a copy of the License at
   https://opensso.dev.java.net/public/CDDLv1.0.html or
   opensso/legal/CDDLv1.0.txt
   See the License for the specific language governing
   permission and limitations under the License.

   When distributing Covered Code, include this CDDL
   Header Notice in each file and include the License file
   at opensso/legal/CDDLv1.0.txt.
   If applicable, add the following below the CDDL Header,
   with the fields enclosed by brackets [] replaced by
   your own identifying information:
   "Portions Copyrighted [year] [name of copyright owner]"

   Portions Copyrighted 2010-2017 ForgeRock AS.
-->
<EntityConfig entityID="openam" hosted="0" xmlns="urn:sun:fm:SAML:2.0:entityconfig">
    <IDPSSOConfig>
        <Attribute name="description">
            <Value/>
        </Attribute>
        <Attribute name="cotlist">
            <Value>Circle of Trust</Value>
        </Attribute>
    </IDPSSOConfig>
    <AttributeAuthorityConfig>
        <Attribute name="cotlist">
            <Value>Circle of Trust</Value>
        </Attribute>
    </AttributeAuthorityConfig>
    <XACMLPDPConfig>
        <Attribute name="wantXACMLAuthzDecisionQuerySigned">
            <Value></Value>
        </Attribute>
        <Attribute name="cotlist">
            <Value>Circle of Trust</Value>
        </Attribute>
    </XACMLPDPConfig>
</EntityConfig>
sp.xml

The SAML library component validates the SP’s AssertionConsumerService Location against the incoming IDP SAML Assertion, based on the request information, including the port. Always specify the port in the Location value of AssertionConsumerService, even when using defaults of 443 or 80, as follows:

<AssertionConsumerService isDefault="true"
                          index="0"
                          Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
                          Location="https://sp.example.com:443/fedletapplication" />

The following example of $HOME/.openig/SAML/sp.xml defines a SAML configuration file for the IG SP, sp.

<!--
   DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.

   Copyright (c) 2002-2010 Sun Microsystems Inc. All Rights Reserved

   The contents of this file are subject to the terms
   of the Common Development and Distribution License
   (the License). You may not use this file except in
   compliance with the License.

   You can obtain a copy of the License at
   https://opensso.dev.java.net/public/CDDLv1.0.html or
   opensso/legal/CDDLv1.0.txt
   See the License for the specific language governing
   permission and limitations under the License.

   When distributing Covered Code, include this CDDL
   Header Notice in each file and include the License file
   at opensso/legal/CDDLv1.0.txt.
   If applicable, add the following below the CDDL Header,
   with the fields enclosed by brackets [] replaced by
   your own identifying information:
   "Portions Copyrighted [year] [name of copyright owner]"

   Portions Copyrighted 2010-2017 ForgeRock AS.
-->
<EntityDescriptor entityID="sp" xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
    <SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
        <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://sp.example.com:8080/saml/fedletSloRedirect" ResponseLocation="http://sp.example.com:8080/saml/fedletSloRedirect"/>
        <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://sp.example.com:8080/saml/fedletSloPOST" ResponseLocation="http://sp.example.com:8080/saml/fedletSloPOST"/>
        <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://sp.example.com:8080/saml/fedletSloSoap"/>
        <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
        <AssertionConsumerService isDefault="true" index="0" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://sp.example.com:8080/saml/fedletapplication/metaAlias/sp"/>
        <AssertionConsumerService index="1" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="http://sp.example.com:8080/saml/fedletapplication/metaAlias/sp"/>
    </SPSSODescriptor>
    <RoleDescriptor xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:query="urn:oasis:names:tc:SAML:metadata:ext:query" xsi:type="query:AttributeQueryDescriptorType" protocolSupportEnumeration= "urn:oasis:names:tc:SAML:2.0:protocol">
    </RoleDescriptor>
    <XACMLAuthzDecisionQueryDescriptor WantAssertionsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
    </XACMLAuthzDecisionQueryDescriptor>
</EntityDescriptor>
sp-extended.xml

The following example of $HOME/.openig/SAML/sp-extended.xml defines an AM-specific SAML descriptor file for the SP:

<!--
   DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.

   Copyright (c) 2002-2010 Sun Microsystems Inc. All Rights Reserved

   The contents of this file are subject to the terms
   of the Common Development and Distribution License
   (the License). You may not use this file except in
   compliance with the License.

   You can obtain a copy of the License at
   https://opensso.dev.java.net/public/CDDLv1.0.html or
   opensso/legal/CDDLv1.0.txt
   See the License for the specific language governing
   permission and limitations under the License.

   When distributing Covered Code, include this CDDL
   Header Notice in each file and include the License file
   at opensso/legal/CDDLv1.0.txt.
   If applicable, add the following below the CDDL Header,
   with the fields enclosed by brackets [] replaced by
   your own identifying information:
   "Portions Copyrighted [year] [name of copyright owner]"

   Portions Copyrighted 2010-2017 ForgeRock AS.
-->
<EntityConfig xmlns="urn:sun:fm:SAML:2.0:entityconfig" xmlns:fm="urn:sun:fm:SAML:2.0:entityconfig" hosted="1" entityID="sp">
    <SPSSOConfig metaAlias="/sp">
        <Attribute name="description">
            <Value></Value>
        </Attribute>
        <Attribute name="signingCertAlias">
            <Value></Value>
        </Attribute>
        <Attribute name="encryptionCertAlias">
            <Value></Value>
        </Attribute>
        <Attribute name="basicAuthOn">
            <Value>false</Value>
        </Attribute>
        <Attribute name="basicAuthUser">
            <Value></Value>
        </Attribute>
        <Attribute name="basicAuthPassword">
            <Value></Value>
        </Attribute>
        <Attribute name="autofedEnabled">
            <Value>false</Value>
        </Attribute>
        <Attribute name="autofedAttribute">
            <Value></Value>
        </Attribute>
        <Attribute name="transientUser">
            <Value>anonymous</Value>
        </Attribute>
        <Attribute name="spAdapter">
            <Value></Value>
        </Attribute>
        <Attribute name="spAdapterEnv">
            <Value></Value>
        </Attribute>
        <Attribute name="fedletAdapter">
            <Value></Value>
        </Attribute>
        <Attribute name="fedletAdapterEnv">
            <Value></Value>
        </Attribute>
        <Attribute name="spAccountMapper">
            <Value>com.sun.identity.saml2.plugins.DefaultLibrarySPAccountMapper</Value>
        </Attribute>
        <Attribute name="spAttributeMapper">
            <Value>com.sun.identity.saml2.plugins.DefaultSPAttributeMapper</Value>
        </Attribute>
        <Attribute name="spAuthncontextMapper">
            <Value>com.sun.identity.saml2.plugins.DefaultSPAuthnContextMapper</Value>
        </Attribute>
        <Attribute name="spAuthncontextClassrefMapping">
            <Value>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport|0|default</Value>
        </Attribute>
        <Attribute name="spAuthncontextComparisonType">
           <Value>exact</Value>
        </Attribute>
        <Attribute name="attributeMap">
           <Value>*=*</Value>
        </Attribute>
        <Attribute name="saml2AuthModuleName">
           <Value></Value>
       </Attribute>
       <Attribute name="localAuthURL">
           <Value></Value>
       </Attribute>
       <Attribute name="intermediateUrl">
           <Value></Value>
       </Attribute>
       <Attribute name="defaultRelayState">
           <Value></Value>
       </Attribute>
       <Attribute name="appLogoutUrl">
           <Value>http://sp.example.com:8080/saml/logout</Value>
       </Attribute>
       <Attribute name="assertionTimeSkew">
           <Value>300</Value>
       </Attribute>
       <Attribute name="wantAttributeEncrypted">
           <Value></Value>
       </Attribute>
       <Attribute name="wantAssertionEncrypted">
           <Value></Value>
       </Attribute>
       <Attribute name="wantNameIDEncrypted">
           <Value></Value>
       </Attribute>
       <Attribute name="wantPOSTResponseSigned">
           <Value></Value>
       </Attribute>
       <Attribute name="wantArtifactResponseSigned">
           <Value></Value>
       </Attribute>
       <Attribute name="wantLogoutRequestSigned">
           <Value></Value>
       </Attribute>
       <Attribute name="wantLogoutResponseSigned">
           <Value></Value>
       </Attribute>
       <Attribute name="wantMNIRequestSigned">
           <Value></Value>
       </Attribute>
       <Attribute name="wantMNIResponseSigned">
           <Value></Value>
       </Attribute>
       <Attribute name="cotlist">
           <Value>Circle of Trust</Value></Attribute>
       <Attribute name="saeAppSecretList">
       </Attribute>
       <Attribute name="saeSPUrl">
           <Value></Value>
       </Attribute>
       <Attribute name="saeSPLogoutUrl">
       </Attribute>
       <Attribute name="ECPRequestIDPListFinderImpl">
           <Value>com.sun.identity.saml2.plugins.ECPIDPFinder</Value>
       </Attribute>
       <Attribute name="ECPRequestIDPList">
           <Value></Value>
       </Attribute>
       <Attribute name="enableIDPProxy">
           <Value>false</Value>
       </Attribute>
       <Attribute name="idpProxyList">
           <Value></Value>
       </Attribute>
       <Attribute name="idpProxyCount">
           <Value>0</Value>
       </Attribute>
       <Attribute name="useIntroductionForIDPProxy">
           <Value>false</Value>
       </Attribute>
    </SPSSOConfig>
    <AttributeQueryConfig metaAlias="/attrQuery">
        <Attribute name="signingCertAlias">
            <Value></Value>
        </Attribute>
        <Attribute name="encryptionCertAlias">
            <Value></Value>
        </Attribute>
        <Attribute name="wantNameIDEncrypted">
           <Value></Value>
        </Attribute>
        <Attribute name="cotlist">
           <Value>Circle of Trust</Value>
        </Attribute>
    </AttributeQueryConfig>
    <XACMLAuthzDecisionQueryConfig metaAlias="/pep">
        <Attribute name="signingCertAlias">
            <Value></Value>
        </Attribute>
        <Attribute name="encryptionCertAlias">
            <Value></Value>
        </Attribute>
        <Attribute name="basicAuthOn">
            <Value>false</Value>
        </Attribute>
        <Attribute name="basicAuthUser">
            <Value></Value>
        </Attribute>
        <Attribute name="basicAuthPassword">
            <Value></Value>
        </Attribute>
        <Attribute name="wantXACMLAuthzDecisionResponseSigned">
            <Value></Value>
        </Attribute>
        <Attribute name="wantAssertionEncrypted">
            <Value></Value>
        </Attribute>
        <Attribute name="cotlist">
            <Value>Circle of Trust</Value>
        </Attribute>
   </XACMLAuthzDecisionQueryConfig>
</EntityConfig>

SAML 2.0 and multiple applications

The chapter extends the example in SAML with the service provider sp, to add a second service provider.

The new service provider has entity ID sp2 and runs on the host sp2.example.com. To prevent unwanted behavior, the service providers must have different values.

  1. Add sp2.example.com to your /etc/hosts file:

    127.0.0.1 localhost am.example.com ig.example.com app.example.com sp.example.com sp2.example.com
  2. In IG, configure the service provider files for sp2, using the files you created in Configure a Java Fedlet::

    1. In fedlet.cot, add sp2 to the list of sun-fm-trusted-providers:

      cot-name=Circle of Trust
      sun-fm-cot-status=Active
      sun-fm-trusted-providers=openam, sp, sp2
      sun-fm-saml2-readerservice-url=
      sun-fm-saml2-writerservice-url=
    2. Copy sp.xml to sp2.xml, and copy sp-extended.xml to sp2-extended.xml.

    3. In both files, search and replace the following strings:

      • entityID=sp: replace with entityID=sp2

      • sp.example.com: replace with sp2.example.com

      • metaAlias=/sp: replace with metaAlias=/sp2

      • /metaAlias/sp: replace with /metaAlias/sp2

    4. Restart IG.

  3. In AM, set up a remote service provider for sp2, as described in Set up federation with unsigned/unencrypted assertions:

    1. Select Applications > Federation > Entity Providers.

    2. Drag in or import sp2.xml created in the previous step.

    3. Select Circles of Trust: Circle of Trust.

  4. Add the following routes to IG:

    • Linux

    • Windows

    $HOME/.openig/config/routes/saml-sp2.json
    appdata\OpenIG\config\routes\saml-sp2.json
    {
      "name": "saml-sp2",
      "condition": "${find(request.uri.host, 'sp2.example.com') and find(request.uri.path, '^/saml')}",
      "handler": {
        "type": "SamlFederationHandler",
        "config": {
          "comment": "Use unique session properties for this SP.",
          "useOriginalUri": true,
          "assertionMapping": {
            "sp2Username": "cn",
            "sp2Password": "sn"
          },
          "authnContext": "sp2AuthnContext",
          "sessionIndexMapping": "sp2SessionIndex",
          "subjectMapping": "sp2SubjectName",
          "redirectURI": "/sp2"
        }
      }
    }
    • Linux

    • Windows

    $HOME/.openig/config/routes/federate-sp2.json
    appdata\OpenIG\config\routes\federate-sp2.json
    {
      "name": "federate-sp2",
      "condition": "${find(request.uri.host, 'sp2.example.com') and not find(request.uri.path, '^/saml')}",
      "baseURI": "http://app.example.com:8081",
      "handler": {
        "type": "DispatchHandler",
        "config": {
          "bindings": [
            {
              "condition": "${empty session.sp2Username}",
              "handler": {
                "type": "StaticResponseHandler",
                "config": {
                  "status": 302,
                  "headers": {
                    "Location": [
                      "http://sp2.example.com:8080/saml/SPInitiatedSSO?metaAlias=/sp2"
                    ]
                  }
                }
              }
            },
            {
              "handler": {
                "type": "Chain",
                "config": {
                  "filters": [
                    {
                      "type": "HeaderFilter",
                      "config": {
                        "messageType": "REQUEST",
                        "add": {
                          "x-username": ["${session.sp2Username[0]}"],
                          "x-password": ["${session.sp2Password[0]}"]
                        }
                      }
                    }
                  ],
                  "handler": "ReverseProxyHandler"
                }
              }
            }
          ]
        }
      }
    }
  5. Test the setup:

    1. Log out of AM, and test the setup with the following links:

    2. Log in to AM with username demo and password Ch4ng31t.

      IG returns the response page showing that the user has logged in.

Copyright © 2010-2023 ForgeRock, all rights reserved.