Security Assertion Markup Language SAML

These features are currently available only under Early Access Program .

About

The Security Assertion Markup Language ( SAML ) is a standard protocol for web browser Single Sign-On (SSO) using secure tokens. The SAML eliminates all local application passwords and instead uses standard cryptography and digital signatures to pass a secure sign-in token from an identity provider to a SaaS application.

When SAML integration is enabled user authentication requests to the management interface will be redirected to a remote Identity Provider (IdP) server URL. After user authentication to the remote Identity Provider, the user is redirected back to the management interface for the authentication session to be verified.

Supported SAML Features

Management Service supports Asynchronous Binding (Front Channel) with these binding types:

  • Single Login: HTTP redirect ( <AuthnRequest>) and H TTP POST (<Response>)

  • Single Logout: HTTP POST, HTTP Redirect (both Service Provider and IdP initiated)

Enabling the SAML integration for Management

Before starting

To use SAML a few things will need to be prepared in advance. Once SAML implementation is enabled the only way to authenticate in the management interface will be through the Identity Provider SSO credentials.

  1. Ensure that the server where the Management Service is installed can access the Identity Provider metadata URL. The metadata from the Identity Provider is downloaded by the Management service using the Identity Provider metadata URL.

    Proxy connections are not supported.

    The Identity Provider metadata URL must contain XML metadata.

    Example of Identity Provider metadata
    <EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" entityID="{EntityID of the Identity Provider}">
    <IDPSSODescriptor WantAuthnRequestsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
    <KeyDescriptor use="signing">
    <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:X509Data><ds:X509Certificate>{encoded certificate information}</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>{encoded certificate information}</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>
    <ArtifactResolutionService index="0" isDefault="true" Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="{public URL from IdP}"/>
    <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:{HTTP-Redirect/HTTP-POST/SOAP}" Location="{public URL from IdP}" ResponseLocation="{public URL from IdP}"/>
    {...}
    <ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:{HTTP-Redirect/HTTP-POST/SOAP}" Location="{public URL from IdP}" ResponseLocation="{public URL from 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:unspecified</NameIDFormat>
    <NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
    <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos</NameIDFormat>
    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:{HTTP-Redirect/HTTP-POST/SOAP}" Location="{public URL from IdP}"/>
    {...}
    </IDPSSODescriptor>
    </EntityDescriptor>
  2. If the URL of the Identity Provider metadata is secured (HTTPS), you need to store the certificate of the URL into Management Server Truststore (by default, it is located in <install_dir>\Management\conf\ssl-truststore).

    How to import the Identity provider server certificate

    1. Import the Identity provider server certificate into Management Server truststore using Java keytool. On the machine where the management interface is running, open the command line and run the following keytool command:

      keytool - import -alias <certificate-alias> -keystore <truststore-location> -file <certificate-location>

      • <certificate-alias> - a key under which will be the certificate stored in the truststore, e.g. saml-certificate

      • <truststore-location> - the location of the truststore, e.g. Management\conf\ssl-truststore

      • <certificate-location> - the location of the Identity provider server certificate to be imported

        • Keytool can import X.509 v1, v2, and v3 certificates, and PKCS#7, either in binary encoding format or in Base64

    2. Enter a password for store protection, default password is changeit

    3. Write yes to confirm you want to trust this certificate. If import was successful, the following message should appear: Certificate was added to keystore

    4. Restart YSoft SafeQ Management Service to apply the settings.

    In case your key/certificate is in a different format than specified, convert it following the guide in Conversions between different keystores and certificate types .

    In the case of Azure AD, the Identity provider server certificate is already trusted under DigiCert root CA.

  3. Ensure that there is at least one user in YSoft SafeQ Management Service (preferably with admin rights) with a "username" that matches a user in the Identity Provider by the property you have chosen as "samlAttributeAsId" (check the list of properties below).

    How the authentication works

    In order to generate the authentication in YSoft SafeQ Management Service based on the authentication coming from the Identity Provider, we are using already existing users in YSoft SafeQ Management Server database so we can use their access rights.

    Having SAML enabled as your Web Authentication Method when you try to access the management interface, you will be redirected to the Identity Provider login page. After login, the Identity Provider will redirect you back to the YSoft SafeQ management interface. This redirection is done in a form of an XML response, together with some information about the user (also called attributes) which can be configured in the Identity Provider. The property "samlAttributeAsId" is used to specify the name of the attribute that matches the "username" in the YSoft SafeQ Management Server database.

Configuration in YSoft SafeQ management interface

  1. Log into the YSoft SafeQ management interface using an admin account.

  2. Navigate to System > Configuration and change the filter to Advanced or Expert.

  3. Change the following system property settings:

    1. Set the value of the property webAuthenticationMethod to SAML v2 single sign-on in order to enable the single sign-on method using SAML.

    2. Set the value of the property samlServerAddress with the URL of the Management Server where users are to be redirected after Identity Provider authentication. The URL should contain "https" when the service works in HTTPS mode (redirect from HTTP to HTTPS may be unsupported in some SAML configurations).

  4. Using the configuration from the Identity Provider change the following system property settings:

    1. Set the value of the property samlAttributeAsId with the attribute from the Identity Provider which will be used to match the username in the management interface. The value should be blank if the SAML assertion contains the correct user attribute in the authentication subject. If the samlAttributeAsId is set then logout requests may not work as the IdP may expect NameId value in the logout request, not other attribute value.

    2. Set the value of the property samlIdentityProviderMetadataUrl with the metadata URL from the Identity Provider.

    3. Set the value of the property samlIdentityProviderLifetime with the session lifetime value in seconds from the Identity Provider. This property defines the timeout when the management interface considers the session as non-trusted. If the session lifetime does not match the Identity Provider configuration then authentication may fail.

    4. Set the value of the property samlServiceProviderId with the unique identifier of Service Provider (YSoft SafeQ 6) from the Identity Provider.

    5. Set the value of the property samlSingleLogout to Enabled if you want the user to be logged out from other Service Providers when you log out of the YSoft SafeQ management interface. The default value of the property is Disabled which means the user will NOT be logged out of all Service Providers which use the Identity Provider, only the local YSoft SafeQ management interface session will be destroyed.

  5. These additional configurations under the Expert filter may be changed according to the capabilities of your Identity Provider:

    1. samlUseNameQualifier to determine if your Identity Provider expects NameQualifier in SAML assertions ( YSoft SafeQ management interface uses urn:oasis:names:tc:SAML:2.0:nameid-format:entity Name ID format).

    2. samlLogoutRequestBindingType to specify what binding method used when samlSingleLogout is enabled

  6. Restart YSoft SafeQ Management Service to apply the settings.

Configure Identity Provider

Add Management Server Service Provider (SP) metadata into Identity Provider server configuration

After Management configuration adds the local metadata generated by Management into the remote Identity Provider server configuration. The remote Identity Provider configuration requires the Management metadata to configure authentication and register the Management callback endpoint URL. Management service will generate the metadata automatically the first time accessing the Management dashboard and it will be stored in <install_dir>\conf\sp-metadata.xml.

For specific configuration of supported identity providers, see section "Sample Identity Provider configurations" below (it is also possible to configure the IdP manually).

Provide Management Server callback endpoint URL to Identity Provider

For manual configuration, the Identity Provider may require the Management Server callback endpoint URL. The Management service endpoint URL is {samlServerAddress}/ security/saml/v2/callback where the value of samlServerAddress is configured in section Configuration in YSoft SafeQ management interface and points to the given Management Server.

Caveats & Limitations

  • No proxy support.

  • No HTTP Artifact binding support

  • No Synchronous Bindings (Back-Channel) support

  • SP SAML requests and responses are not signed

  • ADFS IdP is not fully supported

  • SAMLv2 Single sign-on feature and its setting are available only in single tenant mode due to the technical limitations of the integration.

  • To redirect the user after authentication the system property samlServerAddress can only be set to one Management Server URL. When using Management cluster deployment without a load balancer the other servers are not accessible for user authentication.

  • No protection against login via CSRF is implemented.

Using SAML SSO with Management Cluster

With load balancer

Recommended configuration is that the Management cluster will act as a single service provider e.g. single login URL and single callback URL with authentication result. The system property samlServerAddress must be set to the load balancer URL in front of the Management Service cluster.

Without load balancer

Only one Management Server can be configured for user authentication.

Recommended configuration is that each Management Server in the cluster acts as a standalone service provider, i.e. each server has its own login and callback URL. Due to the limitation of system configuration, only one Management Server URL can be registered in the system property samlServerAddress to redirect after user authentication.

SAML Troubleshooting in Management

Enabling additional logging for SAML troubleshooting

To enable additional SAML logging add this to log configuration file <install_dir>\Management\conf\log4j2.xml . Restart YSoft SafeQ Management Service to apply the settings.

<Logger name="org.pac4j" level="debug" additivity="false">
<AppenderRef ref="management_log_app"/>
</Logger>

Disabling SAML authentication

In case the SAML is not configured properly and the SSO login to Management is failing, the SAML authentication can be disabled in the Management database.

Disabling SAML authentication requires that the application settings be changed in the YSoft SafeQ database. Restart YSoft SafeQ Management Service to apply the settings.

Execute SQL command in PostgreSQL:

UPDATE cluster_mngmt.configuration_properties SET value = 'USERNAME_AND_PASSWORD' WHERE key = 'webAuthenticationMethod'

Execute SQL command in Microsoft SQL Server:

UPDATE cluster_mngmt.configuration_properties SET value = 'USERNAME_AND_PASSWORD' WHERE [key] = 'webAuthenticationMethod'

Enabling the SAML integration for End User Interface

Configuration in YSoft SafeQ management interface

  1. Log into the YSoft SafeQ management interface using an admin account.

  2. Navigate to System > Configuration and change the filter to Advanced or Expert.

  3. Change the following system property settings:

    1. Set the value of the property webAuthenticationMethodEUI to SAML v2 single sign-on in order to enable the single sign-on method using SAML.

    2. Set the value of the property samlIdentityProviderMetadataUrl with the metadata URL from the Identity Provider.

      Property samlIdentityProviderMetadataUrl is shared for the management interface and the end user interface.

  4. Using the configuration from the Identity Provider change the following system property settings:

    1. Set the value of the property samlAttributeAsId with the attribute from the Identity Provider which will be used to match the username in the management interface. The value should be blank if the SAML assertion contains the correct user attribute in the authentication subject. If the samlAttributeAsId is set then logout requests may not work as the IdP may expect NameId value in the logout request, not other attribute value.

    2. Set the value of the property samlIdentityProviderLifetime with the session lifetime value in seconds from the Identity Provider. This property defines the timeout when the management interface considers the session as non-trusted. If the session lifetime does not match the Identity Provider configuration then authentication may fail.

      Properties samlAttributeAsId, samlIdentityProviderLifetime are shared for the management interface and the end user interface.

    3. Set the value of the property samlSingleLogoutEUI to Enabled if you want the user to be logged out from other Service Providers when you log out of the YSoft end user interface. The default value of the property is Disabled which means the user will NOT be logged out of all Service Providers which use the Identity Provider, only local YSoft SafeQ end user interface session will be destroyed.

Configuration in YSoft SafeQ End User Interface

  1. If the URL of the Identity Provider metadata is secured (HTTPS), you need to store the certificate of the URL in end user server Truststore (by default, it is located in <install_dir>\SPOC\java\lib\security\cacerts).

    How to import the Identity provider server certificate

    1. Import the Identity provider server certificate into End User Interface truststore using Java keytool. On the machine where the End User Interface is running, open the command line and run the following keytool command:

      keytool - import -alias <certificate-alias> -keystore <truststore-location> -file <certificate-location>

      • <certificate-alias> - a key under which will be the certificate stored in the truststore, e.g. saml-certificate

      • <truststore-location> - the location of the truststore, e.g. SPOC\java\lib\security\cacerts

      • <certificate-location> - the location of the Identity provider server certificate to be imported

        • Keytool can import X.509 v1, v2, and v3 certificates, and PKCS#7, either in binary encoding format or in Base64

    2. Enter a password for store protection, the default password is changeit

    3. Write yes to confirm you want to trust this certificate. If the import was successful, the following message should appear: Certificate was added to keystore

    4. Restart End User Interface to apply the settings.

    In the case of Azure AD, the Identity provider server certificate is already trusted under DigiCert root CA.

  2. Import the Identity Provider SAML signing certificate into End User Interface keystore.

    How to import the Identity Provider SAML signing certificate

    1. On the machine where the End User Interface is running, open the command line and run the following java keytool command:

      keytool - import -alias <certificate-alias> -keystore <keystore-location> -file <certificate-location>

      • <certificate-alias> - a key under which will be the certificate stored in the keystore, e.g. saml-certificate

      • <keystore-location> - the location of the store, by default is in <install_dir>\SPOC\EUI\ui-conf\keystore.jks

      • <certificate-location> - the location of the Identity Provider SAML signing certificate to be imported

    2. Enter a password for keystore protection, the default password is: L1faMXVVpR

    3. Write yes to confirm you want to trust this certificate. If the import was successful, the following message should appear: Certificate was added to keystore

    4. Restart YSoft SafeQ End User Interface to apply the settings.

    In case your key/certificate is in a different format than specified, convert it following the guide in Conversions between different keystores and certificate types.

  3. Open file <install_dir>\SPOC\EUI\ui-conf\environment-configuration.properties and add or modify these properties

    safeq.authentication.address=tcp://127.0.0.1:5555
    saml.entityId=<EntityID of the Identity Provider>
    saml.baseUrl=https://<end-user-ip>:<end-user-port>/end-user
    Example of environment-configuration.properties
    safeq.authentication.address=tcp://127.0.0.1:5555
    saml.entityId=SafeQEndUserInterface
    saml.baseUrl=https://10.0.124.248:9443/end-user
  4. Restart the YSoft SafeQ End User Interface Windows service.

  5. Download End User Interface SAML spring_saml_metadata.xml from the following address:

    https://<end-user-ip>:<end-user-port>/end-user/saml/metadata
    Example of spring_saml_metadata.xml
    <md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" ID="SafeQEndUserInterface3" entityID="SafeQEndUserInterface3">
    <md:SPSSODescriptor AuthnRequestsSigned="true" WantAssertionsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
    <md:KeyDescriptor use="signing">
    <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:X509Data>
    <ds:X509Certificate>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
    I21b</ds:X509Certificate>
    <ds:X509Certificate>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</ds:X509Certificate>
    <ds:X509Certificate>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</ds:X509Certificate>
    </ds:X509Data>
    </ds:KeyInfo>
    </md:KeyDescriptor>
    <md:KeyDescriptor use="encryption">
    <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:X509Data>
    <ds:X509Certificate>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
    I21b</ds:X509Certificate>
    <ds:X509Certificate>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</ds:X509Certificate>
    <ds:X509Certificate>MIIGNzCCBB+gAwIBAgIBATANBgkqhkiG9w0BAQ0FADCBkDELMAkGA1UEBhMCY3oxDTALBgNVBAcT
    BEJybm8xGzAZBgNVBAoTElkgU29mdCBDb3Jwb3JhdGlvbjEMMAoGA1UECxMDUm5EMRowGAYDVQQD
    ExFZU29mdCBSbkQgcm9vdCBDQTEdMBsGCSqGSIb3DQEJARYOaW5mb0B5c29mdC5jb20xDDAKBgNV
    BAQTA0RaQTAgFw0xMzEyMTkxNDE1MTdaGA8yMDk5MTIxNzE0MTUxN1owgZAxCzAJBgNVBAYTAmN6
    MQ0wCwYDVQQHEwRCcm5vMRswGQYDVQQKExJZIFNvZnQgQ29ycG9yYXRpb24xDDAKBgNVBAsTA1Ju
    RDEaMBgGA1UEAxMRWVNvZnQgUm5EIHJvb3QgQ0ExHTAbBgkqhkiG9w0BCQEWDmluZm9AeXNvZnQu
    Y29tMQwwCgYDVQQEEwNEWkEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC6n3LNV4vI
    5Kdobz2dlwXPIwk6Vhk45p6lGHfbSuN0rxaMIaBiseL8jdIYBv6xOQT6O58/hbCa+/Et9o+cxG3m
    1HQ/DwgLK6OWWL3CPepkmRU/GgZQCZQ1619r0d534G1rRQIXWRhC3o5H4oVsk3vKz3oQrFPuzAbi
    LiKAIi9k9qvgzOKSt5YQV5pNCOygFV/A7YjMNXcnpekDxM1GObTh9/CNaErC8xP5ZthDhucnGDHX
    oqStamWmUICAO8d1jgoaDraxDwHZcDtmT4kXKjtOvpfIyVL/1+FSxE7qauKwtJ/e2IyX7ourgf2K
    hDGJawmF3gLZCj1MuRd5Zg+GBK61MTzyWnT+0J+HKEixFO8mqrgCdV7BmC2oJEyyJHeRpIcOUPJY
    DRorXrDmwzQB4hkLDiACnWQTI1Sc2Tkr7d0ZkuKipgf5YkGCZeG/c2geQ++04SxIu9Grb0SOh+LB
    DhvrQp70rgy1F+NzVjcqVW/vqyP32/M/AJO6+wuSZVMRNEzEdVEinPvm6WMgZhw0KH5O1KEFJ1r7
    72m/7mUMiOaukRps9NenmUvNq8YbO8ZfDFi0KrHPR+mLifczxIAie+xIJu0HJKTm0OoSz+rgxRQY
    aS3RsLIOJePtgcEIQlc5T9kUfvnVpFuBRxEAaQWhgApge4ALv7O2aF2l0focnkfM1QIDAQABo4GX
    MIGUMBIGA1UdEwEB/wQIMAYBAf8CAQIwHQYDVR0OBBYEFCdB3zHbLUTpzj7wSJmz7PJP+XokMB8G
    A1UdIwQYMBaAFCdB3zHbLUTpzj7wSJmz7PJP+XokMAsGA1UdDwQEAwIBBjARBglghkgBhvhCAQEE
    BAMCAAcwHgYJYIZIAYb4QgENBBEWD3hjYSBjZXJ0aWZpY2F0ZTANBgkqhkiG9w0BAQ0FAAOCAgEA
    fmmSihhS+mQkeUuVLodPRy4T9iZ+WTeVHqcHx4JlYWceqzSLXfaskyCsPIk9ZoShgmNhHnB8VEwG
    sjYdHpP9/MWG4uYgTQr04zvF/oYNkVfRRxWLQjj8jLAKnqOiaTPhr7XgOadNLWlggMZXqKvQhAah
    v3guei/A/oAfSEx/i7ZffEv/bb7SKSuaukXNSxgBwpzMdaAew1nDTrSiH/wYwTMF0hgD49JBboOo
    gvlz4qELcX8GGXQcnr9/cbABetkLH5r0gZHyAGb/PLRzs2Ur3g4UrntKlXY5tfr415D9m6CQJk42
    GKUlWjYQ77X6yFwc2RDWrmF6QvfWHDAXQ0eJUy+iqsMl0WgrBAIJPUBh8W2p/KYg0BpLwKSXR6xC
    0qEgkoV8vpTZZc+11UvFKT/4pXdJGnWmg5sbEhDT5FrT4GYNN3bBwkTLzK5ZzyvFLWJn0mdXrosW
    9WOR9gK22yU+BtijzHtmH3myVtamjnmmDZp6UNvGEJ2x4mxHGP/5w7D6ftxRVDkDyEZd5v0NvMCn
    41FRx9E1zI58bix8iT5TmD8J98EdkyptynNwsJz5eizn8/L7wiOZX8kgmlI3jU7BOikoMHDMC6oj
    pULuVtd2x5gvLjq7mug5E6ILmh0JzOHhjgfIDm2vW71rLi+OPZlsGA0JViyzEIQyARxnEXvDtY4=</ds:X509Certificate>
    </ds:X509Data>
    </ds:KeyInfo>
    </md:KeyDescriptor>
    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://10.0.124.248:9443/end-user/ui/saml/SingleLogout" />
    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://10.0.124.248:9443/end-user/ui/saml/SingleLogout" />
    <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>
    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://10.0.124.248:9443/end-user/ui/saml/SSO" index="0" isDefault="true" />
    </md:SPSSODescriptor>
    </md:EntityDescriptor>
  6. Import spring_saml_metadata.xml as a new Entity with set EntityId into Identity Provider, or configure manually.

Using SAML SSO in the management interface and EUI simultaneously

The samlIdentityProviderMetadataUrl property is shared between the management interface and end user interface, therefore, in order to set up different Metadata URLs for both subsystems, the following approach can be used:

  • Use the samlIdentityProviderMetadataUrl property in the management interface to store the Metadata URL you intend to use for Management

  • Override the variable for SPOC/EUI - modify the following file: <install_dir>\SPOC\conf\modules\spoc.conf , append the following line to the end:

spoc.conf
...
samlIdentityProviderMetadataUrl=<EUI_Metadata_URL>
  • Restart the following services to apply the override: YSoft SafeQ Spooler Controller, YSoft SafeQ End User Interface

Troubleshooting

"Signature trust establishment failed for metadata entry"

The following error may occur while configuring SAML:

MetadataCredentialResolver: PKIX path construction failed for untrusted credential: [subjectName='CN=XXXXXX']: unable to find valid certification path to requested target
PKIXSignatureTrustEngine: Signature trust could not be established via PKIX validation of signing credential
BaseSignatureTrustEngine: Failed to establish trust of KeyInfo-derived credential
BaseSignatureTrustEngine: Failed to verify signature and/or establish trust using any KeyInfo-derived credentials
PKIXSignatureTrustEngine: PKIX validation of signature failed, unable to resolve valid and trusted signing key
SignatureValidationFilter: Signature trust establishment failed for metadata entry "http://some-url.com/"
AbstractReloadingMetadataProvider: Error filtering metadata from "http://some-url.com/"
org.opensaml.saml2.metadata.provider.FilterException: Signature trust establishment failed for metadata entry

It means that the metadata contains a certificate that is not trusted by the end user interface. You need to add the Identity Provider SAML signing certificate to the keystore of the application where the error occurred (Management / End User Interface). Follow the next steps for retrieving the certificate:

  1. Locate the missing certificate:

    1. These certificates can be found within the Identity Provider metadata, inside the tag <ds:X509Certificate>.

    2. To verify it is the right certificate, check the Canonical Name (CN) of the certificate the log "PKIX path construction failed for the untrusted credential: [subjectName='CN=XXXXXX'].

    3. The certificate in the metadata is encrypted, so you need to first convert it into the .cer file and then you are able to open it

  2. Create a new file with extension .cer (ie. signature.cer)

  3. Paste the content of the <ds:X509Certificate> into the file, with the header and footer as follows:

    Example of certificate
    -----BEGIN CERTIFICATE-----
    MIIC7jCCAdagAwIBAgIQa+pSaOoDP6ZL3qAi564CxzANBgkqhkiG9w0BAQs
    FADAzMTEwLwYDVQQDEyhBREZTIFNpZ25pbmcgLSBzdHN0ZXN0LXJlcGx5bm
    V0LnJlcGx5Lml0MB4XDTE0MDQyMTAwMzUyNVoXDTE1MDQyMTAwMzUyNVowM
    zExMC8GA1UEAxMoQURGUyBTaWduaW5nIC0gc3RzdGVzdC1yZXBseW5ldC5y
    ZXBseS5pdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJyI7Se
    +UGGHOGRcwHF8LrmivtcPJyNKyicPJ8UJ8pIsEmgYBnJIrpS05RkYtdUdk+
    aumDlc3ACt23FxGDLy9hkJJlRbZwklzh4W3RqGC3W5Y+t7KeIuB8d7ZrrLb
    2AoJpVHICRagsLjjHMwz9sJUt+PZdUFFc0pZckHba3TY2Y+MgPYVsyjlEkf
    QrwL0ggh23g9Pe1VQ9HaInXZvwVMGWZ1oL4Uk0cW11URa8x53ZOWMQSsksi
    MUlquItssiuJjRnI9Df+GaDxbQJi51esY2EF1o2JxqGJSA71Apy9EahDho8
    eFkfOS0fYbVNBU5X/Wn7BKsf2Rmg3r6mQM94+gAA8CAwEAATANBgkqhkiG9
    w0BAQsFAAOCAQEAIX5FEt5JWtINzy4C0LtTtta3DMOsLIBH3raRr53+6MKG
    sPP75VAt7fYUutopuk5Y2o++sVPuEuTzcogz5Dj8eglDESkPwR0PrlClVcG
    FLFEx9qOOidYIEa90g462niIOgkNkIpb1JRrmZEFo+yrYYdFSR2iXzC3O1f
    7JAhNwi+d4a8cOTrqynqL6p1z+hiWEub39FlWDPacELw9HSDIYY151hiiPz
    vIRQDBOjDg3Ws8fRwYNjJH4ElwjP2z+1r+sktD/kkh8jj3iWhT37JnQG72D
    7c63ovYICwEZUqS4L3vepO0pv6xewkUbfX4KBQbUPaVVgmVUcSecj85mvMx
    42g==
    -----END CERTIFICATE-----
  4. Put the certificate in the keystore used by SAML as described in step "Import the Identity Provider SAML signing certificate".


If using Azure AD, the cert can also be downloaded from AAD portal (SAML SSO configuration page under given enterprise application)

"The message is not signed with expected signature algorithm. Message is signed with..."

The following error may occur during authentication in YSoft SafeQ End User Interface with Active Directory Federation Services. Identity Provider rejects communication from YSoft SafeQ due to SHA-1 signature algorithm being used, which is not trusted by some Identity Providers. The preferred solution is to update to Build 59 which uses SHA-256 signature algorithm instead.

"NameID element must be present as part of the Subject in the Response message, please enable it in the IDP configuration"

The following error may occur after authentication:

AuthNResponse;FAILURE;130.237.65.59;safeQ6-ref;http://login.customer.com/adfs/services/trust;;;org.opensaml.common.SAMLException: NameID element must be present as part of the Subject in the Response message, please enable it in the IDP configuration
at org.springframework.security.saml.websso.WebSSOProfileConsumerImpl.processAuthenticationResponse(WebSSOProfileConsumerImpl.java:288)
at org.springframework.security.saml.SAMLAuthenticationProvider.authenticate(SAMLAuthenticationProvider.java:88)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174)
at org.springframework.security.saml.SAMLProcessingFilter.attemptAuthentication(SAMLProcessingFilter.java:92)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:185)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.saml.metadata.MetadataGeneratorFilter.doFilter(MetadataGeneratorFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:347)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:263)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.multipart.support.MultipartFilter.doFilterInternal(MultipartFilter.java:122)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at com.ysoft.ui.system.configuration.ContentSecurityPolicyFilter.doFilter(ContentSecurityPolicyFilter.java:35)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
at org.apache.tomcat.util.net.Nio2Endpoint$SocketProcessor.doRun(Nio2Endpoint.java:1685)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.net.AbstractEndpoint.processSocket(AbstractEndpoint.java:1167)
at org.apache.tomcat.util.net.Nio2Endpoint$Nio2SocketWrapper$2.completed(Nio2Endpoint.java:613)
at org.apache.tomcat.util.net.Nio2Endpoint$Nio2SocketWrapper$2.completed(Nio2Endpoint.java:591)
at org.apache.tomcat.util.net.SecureNio2Channel$1.completed(SecureNio2Channel.java:996)
at org.apache.tomcat.util.net.SecureNio2Channel$1.completed(SecureNio2Channel.java:925)
at java.base/sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:127)
at java.base/sun.nio.ch.Invoker$2.run(Invoker.java:219)
at java.base/sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:834)

It means that the response from the identity provider does not contain the NameID element in the subject element as it can be seen in the following sample SAML Response message extract:

<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">slesarik</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData InResponseTo="a3ifad5j61226fij2af653d986a1fgd"
NotOnOrAfter="2021-07-01T08:45:24.796Z"
Recipient="https://10.0.116.169:9443/end-user/saml/SSO" /></saml:SubjectConfirmation>
</saml:Subject>

To fix this error the identity provider needs to be configured to include the NameID element, this depends on the identity provider being used, see sample configurations below.

Azure error "AADSTS7500525: There was an XML error in the SAML message at line 2, position 753. Verify that the XML content of the SAML messages conforms to the SAML protocol specifications."

Set the configuration value samlUseNameQualifier in the management interface to Disabled.

"Signature is not trusted"

org.pac4j.saml.exceptions.SAMLSignatureValidationException: Signature is not trusted
at org.pac4j.saml.profile.impl.AbstractSAML2ResponseValidator.validateSignature(AbstractSAML2ResponseValidator.java:121) ~[pac4j-saml-3.6.1.jar:?]
at org.pac4j.saml.sso.impl.SAML2AuthnResponseValidator.validateAssertionSignature(SAML2AuthnResponseValidator.java:563) ~[pac4j-saml-3.6.1.jar:?]
at org.pac4j.saml.sso.impl.SAML2AuthnResponseValidator.validateAssertion(SAML2AuthnResponseValidator.java:341) ~[pac4j-saml-3.6.1.jar:?]
at org.pac4j.saml.sso.impl.SAML2AuthnResponseValidator.validateSamlSSOResponse(SAML2AuthnResponseValidator.java:263) ~[pac4j-saml-3.6.1.jar:?]
at org.pac4j.saml.sso.impl.SAML2AuthnResponseValidator.validate(SAML2AuthnResponseValidator.java:110) ~[pac4j-saml-3.6.1.jar:?]
at org.pac4j.saml.profile.impl.AbstractSAML2MessageReceiver.receiveMessage(AbstractSAML2MessageReceiver.java:81) ~[pac4j-saml-3.6.1.jar:?]
at org.pac4j.saml.sso.impl.SAML2WebSSOProfileHandler.receive(SAML2WebSSOProfileHandler.java:35) ~[pac4j-saml-3.6.1.jar:?]
at org.pac4j.saml.credentials.extractor.SAML2CredentialsExtractor.extract(SAML2CredentialsExtractor.java:74) ~[pac4j-saml-3.6.1.jar:?]
at org.pac4j.saml.credentials.extractor.SAML2CredentialsExtractor.extract(SAML2CredentialsExtractor.java:26) ~[pac4j-saml-3.6.1.jar:?]

The reason for this issue is most probably that the Azure Identity provider changed metadata on its side.


1. Restart Management Service to obtain new IdP metadata and try again.

2. If the problem persists, enhance the log4j configuration file (<installation dir>\Management\conf\log4j2.xml) by improved logging of signature library

<Logger name="org.opensaml.xmlsec.signature" level="debug" additivity="false">
<AppenderRef ref="management_log_app"/>
</Logger>

3. Restart Management Service, and analyze logs or contact support.

Enable additional logging for troubleshooting EUI

To enable additional logging, update the following configuration file: <install_dir> \SPOC\EUI\webapps\end-user\WEB-INF\classes\logback.xml - change the level attribute in the root tag (default loglevel is INFO)

<root level="${root.loglevel:-DEBUG}">

Restart YSoft SafeQ End User Interface to apply the changes.

Sample Identity Provider SAML configurations

Azure Active Directory (AAD)

AAD configuration for Management Service

Create app in Azure

  1. Home → Azure Active Directory → Enterprise applications → New Application → Create your own application

  2. Name your app

  3. Select the "Integrate any other application you don't find in the gallery (Non-gallery)" option

images/download/attachments/160475617/image2021-8-19_13-40-59.png

Select SAML as sign-on method

Single sign-on → SAML
images/download/attachments/160475617/image2021-8-19_13-46-16.png

When SAML method is created, the summary appears

images/download/attachments/160475617/image2021-8-23_15-20-50.png

Leave the page open for further processing and move to the management interface.

Set up Management Service

Before configuring Azure, you may specify certain configuration in the management interface:

Configuration

Value for Azure FS

Note

samlServiceProviderId

per your requirements

EntityID that will be used to identify your app in Azure.

samlAttributeAsId

per your requirements


samlServerAddress

e.g. https://mymanagement

Azure requires your Management instance to be on https:// protocol

samlSingleLogout

per your requirements


samlIdentityProviderLifetime

28800

8 hours is Azure default, can be changed but must match on both sides https://www.pac4j.org/1.9.x/docs/clients/saml.html#b-maximum-authentication-time

samlUseNameQualifier

Disabled

Requirement for Azure

samlLogoutRequestBindingType

HTTP-Redirect

Requirement for Azure

samlIdentityProviderMetadataUrl

Value of App Federation Metadata Url from screenshot above, usually like " https://login.microsoftonline.com/<app-guid>/federationmetadata/2007-06/federationmetadata.xml?appid=<app-id> "


webAuthenticationMethod

SAML v2 single sign-on


If you now restart Management service and go to its login screen (it is not necessary to log in as login fails), an XML file will appear in your installation folder that you will use below - <install_dir> \conf\sp-metadata.xml.

Import metadata to Azure

  1. Locate the file created in your YSoft SafeQ Management installation folder: <install_dir> \conf\sp-metadata.xml

  2. Go back to Azure app registration page

  3. Single sign-on → Upload metadata file

  4. Make sure EntityId, Reply URL and Logout URL are correctly imported from metadata.

    images/download/attachments/160475617/image2021-8-19_14-5-12.png

AAD configuration for End User Interface

Create app in Azure

  1. Home → Azure Active Directory → Enterprise applications → New Application → Create your own application

  2. Name your app

  3. Select "Integrate any other application you don't find in the gallery (Non-gallery)" option

images/download/attachments/160475617/image2021-8-19_13-40-59.png

Select SAML as sign-on method

Single sign-on → SAML
images/download/attachments/160475617/image2021-8-19_13-46-16.png

Configure Basic SAML Configuration

Create your unique Identifier (Entity ID) or use the default one
Set Reply URL to https://<EUI_IP>:9443/end-user/saml/SSO, where <EUI_IP> is the IP address of the end user interface
images/download/attachments/160475617/azure_entityId_setup.png

When the SAML method is created, the summary appears

images/download/attachments/160475617/image2021-8-23_15-20-50.png

Leave the page open for further processing and move to the management interface.

Set up Management Service

Before configuring Azure, you may specify certain configuration in the management interface:

Configuration

Value for Azure FS

Note

samlAttributeAsId

per your requirements, e.g. name


samlSingleLogoutEUI

per your requirements


samlIdentityProviderLifetime

28800

8 hours is Azure default, can be changed but must match on both sides https://www.pac4j.org/1.9.x/docs/clients/saml.html#b-maximum-authentication-time

euiSamlIncludeScoping

Disabled

Requirement for Azure

euiSamlBinding

HTTP-POST

Requirement for Azure

samlIdentityProviderMetadataUrl

Value of App Federation Metadata Url from screenshot above, usually like " https://login.microsoftonline.com/<app-guid>/federationmetadata/2007-06/federationmetadata.xml?appid=<app-id> "

Do not set this value if using SAML integration with Management!

webAuthenticationMethodEUI

SAML v2 single sign-on


Now restart Management Service to apply changes.

Link Unique User Identifier property between Azure and MGMT

Azure AD has already configured attribute "name" matching "user.userprincipalname" by default. So if you did set samlAttributeAsId="name" above, you can skip this step.

  1. Navigate to: User Attributes & Claims → Edit → Add new claim

  2. Set Name to the value of attribute samlAttributeAsId set during Management Service setup above

  3. Set Source to Attribute

  4. Set Source attribute to attribute you want to use to identify Azure AD users like "user.userprincipalname"

  5. Save

    images/download/attachments/160475617/azure_attrribute_mapper.png


Setup End User Interface

  1. Configure the "environment-configuration.properties" file located in SPOC/EUI/ui-conf

    1. Set safeq.authentication.address=tcp://127.0.0.1:5555

    2. Set saml.entityId=Entity Id you configured in step "Configure Basic SAML Configuration" above

    3. Set saml.baseUrl=https://<EUI_IP>:9443/end-user

    4. If using SAML integration with Management, also set saml.idpUrl.local=Value of App Federation Metadata Url from the screenshot in step "Configure Basic SAML Configuration" above

  2. Import Azure certificate

    1. Download certificate from Single sign-on → SAML Signing Certificate → Certificate (Raw)

      images/download/attachments/160475617/azure_certificate_import.png


    2. Import downloaded certificate to End User Interface keystore.

      How to import the certificate

      1. Import the Identity Provider SAML signing certificate into End User Interface keystore using Java keytool. On the machine where the End User Interface is running, open the command line and run the following keytool command:

        keytool - import -alias <certificate-alias> -keystore <keystore-location> -file <certificate-location>

        • <certificate-alias> - a key under which will be the certificate stored in the truststore, e.g. saml-certificate

        • <keystore-location> - the location of the keystore, e.g. SPOC\EUI\ui-conf\keystore.jks

        • <certificate-location> - the location of the Identity Provider SAML signing certificate to be imported

          • Keytool can import X.509 v1, v2, and v3 certificates, and PKCS#7, either in binary encoding format or in Base64

      2. Enter a password for keystore protection. The default password is L1faMXVVpR.

      3. Write yes to confirm you want to trust this certificate. If import was successful, the following message should appear: Certificate was added to keystore

  3. Restart End User Interface Service

  4. Generate metadata for Azure by navigating to address https://<EUI_IP>:9443/end-user/saml/metadata. This will download metadata file spring_saml_metadata.xml.

  5. Import metadata to Azure

    1. Navigate to Single sign-on → Upload metadata file

    2. Upload the spring_saml_metadata.xml file.

    3. Make sure EntityId, Reply URL and Logout URL are correctly imported from metadata.

      images/download/attachments/160475617/azure_metadata_correctly_imported.png

KeyCloak

  1. Import Service Provider metadata (Clients → Create → Import → Save)

  2. Add mapper to the client to include username attribute (Mappers → Create → User Property → fill "username" to all fields → Save)

Active Directory Federation Services (AD FS)


AD FS 4.0 Sample Configuration
@RuleTemplate = "LdapClaims"
@RuleName = "Send Claims"
c:[Type == http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname, Issuer == "AD AUTHORITY"]
=> issue(store = "Active Directory", types = (http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier, "username"), query = ";sAMAccountName,sAMAccountName;{0}", param = c.Value);

For older versions of Active Directory Federation Services, you can follow also the official integration guide: https://docs.spring.io/spring-security-saml/docs/current/reference/htmlsingle/#d5e1750.