Tomcat SAML authentication

The example bellow is given for Google SAML Identity Provider (IdP) provider but this can be transposed to other providers.

Note: This document only applies to version 4.0 and above.

Webapp settings

Important: before to do those changes, check that you have a user login with ADMIN and DESIGNER responsabilities that you can log in with.

The changes to be done are :

Google settings

Declare a new SAML app on Google Admin Console (in Apps > SAML apps) for the application (the SAML ACS URL and start URL will be <url>/saml):

Client ID

If you configure several SAML apps you must choose a unique entity ID for each of them.

Application settings

Note: this section is depprecated as of version 4.0.P23 for which the authentication providers configuration is done using the AUTH_PROVIDERS JSON system parameters. See this document for details.

Add the IDP settings of your Google SAML app as system parameters:

<?xml version="1.0" encoding="UTF-8"?>
<simplicite xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.simplicite.fr/base" xsi:schemaLocation="http://www.simplicite.fr/base http://www.simplicite.fr/schemas/base.xsd">
<object>
    <name>SystemParam</name>
    <action>upsert</action>
    <data>
        <sys_code>SAML_IDP_ENTITY_ID</sys_code>
        <sys_value><![CDATA[https://accounts.google.com/o/saml2?idpid=<Your Google IDP ID>]]></sys_value>
        <sys_type>PRV</sys_type>
        <row_module_id.mdl_name>MyModule</row_module_id.mdl_name>
    </data>
    <data>
        <sys_code>SAML_IDP_SSO_URL</sys_code>
        <sys_value><![CDATA[https://accounts.google.com/o/saml2/idp?idpid=<Your Google IDP ID>]]></sys_value>
        <sys_type>PRV</sys_type>
        <row_module_id.mdl_name>MyModule</row_module_id.mdl_name>
    </data>
    <data>
        <sys_code>SAML_IDP_CERTIFICATE</sys_code>
        <sys_value><![CDATA[[-----BEGIN CERTIFICATE-----
(...)
-----END CERTIFICATE-----]]></sys_value>
        <sys_type>PRV</sys_type>
        <row_module_id.mdl_name>MyModule</row_module_id.mdl_name>
    </data>
</object>
</simplicite>

Additional settings

Depending on the SSO strategies others configurations are possible :

system parameter value Description
SAML_ASSERTIONS_ENCRYPTED true/false Indicates a requirement for the Assertions received by this SP to be encrypted
SAML_ASSERTIONS_SIGNED true/false Indicates a requirement for the elements received by this SP to be signed.
SAML_AUTHNREQUEST_SIGNED true/false Indicates whether the messages sent by this SP will be signed.
SAML_IDP_SLO_URL Logout IDP URL SLO endpoint info of the IdP. URL Location of the IdP where the SP will send the SLO Request
SAML_LOGOUTREQUEST_SIGNED true/false Indicates whether the messages sent by this SP will be signed.
SAML_LOGOUTRESPONSE_SIGNED true/false Indicates whether the messages sent by this SP will be signed.
SAML_SP_CERTIFICATE -----BEGIN CERTIFICATE-----xxxx-----END CERTIFICATE Usually x509cert of the SP are provided .
SAML_SP_PRIVATEKEY -----BEGIN RSA PRIVATE KEY-----yyy-----END RSA PRIVATE KEY Private key of the SP.
SAML_USERINFO_MAPPINGS Json type Define an SSO User mapping. Only firstname, lastname, email and phone can be mapped.

Grant hooks

Then you can implement GrantHooks's parseAuth method to handle the returned Google account identifier if required.

The example bellow checks and removes the domain part of the account name in parseAuth and creates/updates the corresponding application user on the fly in pre/postLoadGrant.

importPackage(Packages.com.simplicite.objects.System);

GrantHooks.parseAuth = function(sys, auth) {
    // Check if the account is in authorized domain
    var domain = sys.getParameter("MY_GOOGLE_DOMAIN", "simplicite.fr");
    if (!auth.matches("^.*@" + domain + "$")) {
        console.error("Invalid domain for account = " + auth);
        return null;
    }
    // Remove domain from account to get plain login
    return auth.replaceFirst("@" + domain, "");
};