---
title: Signed/encrypted SAML v2.0 assertions
description: Set up the example in Unsigned/unencrypted SAML v2.0 assertions.
component: pinggateway
version: 2025.11
page_id: pinggateway:gateway-guide:federation-setup-signed-handler
canonical_url: https://docs.pingidentity.com/pinggateway/2025.11/gateway-guide/federation-setup-signed-handler.html
revdate: 2025-10-22T14:04:06Z
---

# Signed/encrypted SAML v2.0 assertions

1. Set up the example in [Unsigned/unencrypted SAML v2.0 assertions](federation-setup-handler.html).

2. Set up the SAML keystore:

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

      ```console
      $ more /path/to/am/secrets/default/.keypass
      $ more /path/to/am/secrets/default/.storepass
      ```

   2. Copy the SAML keystore from the AM configuration to PingGateway:

      ```console
      $ cp /path/to/am/secrets/keystores/keystore.jceks /path/to/ig/secrets/keystore.jceks
      ```

      |   |                                                                                                                        |
      | - | ---------------------------------------------------------------------------------------------------------------------- |
      |   | Legacy keystore types such as JKS and JCEKS are supported but aren't secure. Consider using the PKCS#12 keystore type. |

3. Configure the Fedlet in PingGateway:

   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>`

         ```xml
                 <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:

         ```xml
         <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 PingGateway:

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

      ```console
      $ 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-handler.json` from the configuration and add the following route, replacing the path to `keystore.jceks` with your path:

      * Linux

        `$HOME/.openig/config/routes/saml-handler-secure.json`

      * Windows

        `%appdata%\OpenIG\config\routes\saml-handler-secure.json`

      ```json
      {
        "name": "saml-handler-secure",
        "condition": "${find(request.uri.path, '^/saml')}",
        "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"
          }
        }
      }
      ```

      Source: [saml-handler-secure.json](../_attachments/config/routes/saml-handler-secure.json)

      Notice the following features of the route compared to `saml-handler.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 PingGateway.

6. Test the setup:

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

      * [IdP-initiated SSO](http://am.example.com:8088/openam/idpssoinit?metaAlias=/idp\&spEntityID=sp)

      * [SP-initiated SSO](http://ig.example.com:8080/home/federate)

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

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