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

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

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>

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, "");
};