In AEM 5.6, Adobe introduced the “Adobe Granite SAML 2.0 Authentication Handler” to handle basic SAML based Single Sign-On. AEM 6 is now out and comes with new configuration options for SAML authentication. This post takes a high-level look at setting up a local developer environment with SSO, the new SSO configuration options part of AEM 6, and common gotchas that may be encountered.
Note: SAML SSO in AEM 6 requires at least Service Pack 1. Service Pack 1 fixes a bug that prevents the HTTP POST binding from functioning. A 403 Forbidden error will result if Service Pack 1 is not installed.
The guidelines below apply to a localhost apache server running https://simplesamlphp.org/ as the IdP. This is a good alternative to Shibboleth for local developer environment testing. Install instructions can be found here and IdP configuration instructions can be found here (skip Step 6, this configuration is not compatible with the SAML handler).
Once the SimpleSAMLphp IdP has been configured, AEM’s SAML Authentication Handler can be set up.
Basic SAML Authentication Handler Setup
This is the path to protect from anonymous access. See the ‘Limitations and Gotchas’ section below for more information.
This can be found on the SimpleSAMLphp status page. Go to the Federation tab. Select “Show Metadata” under “SAML 2.0 IdP Metadata” and locate the SingleSignOnService URL.
Service Provider Entity ID
This is the $metadata key added in Step 7 of the IdP configuration instructions.
Assuming the SimpleSAMLphp ‘example-userpass’ authentication source is being used (see simplesamlphp/config/authsources.php), this would be ‘uid’.
Public/Private Signing Keys
In CRXDE, create a new folder /etc/key/saml with two binary properties named idp_cert and private. idp_cert is used to validate the signature generated by the IdP’s SAMLResponse. private is used to sign the SAMLRequest sent to the IdP.
If SimpleSAMLphp is being used, the idp_cert is the .crt file created in Step 4 of the IdP setup instructions.
Private is created with the following steps:
- cd /var/simplesamlphp/cert
- Create the .crt and .pem file: openssl req -newkey rsa:2048 -new -x509 -days 3652 -nodes -out sp.crt -keyout sp.pem
- Convert the .pem to .der: openssl pkcs8 -topk8 -inform PEM -outform DER -in sp.pem -out sp.der –nocrypt
- Upload sp.der using CRXDE with the name ‘private’
- Update simplesamlphp/metadata/saml20-sp-remote.php so that it looks similar to the following:
At this point, authentication against the SimpleSAMLphp IdP should complete successfully. Visit a page within the configured Path value to test.
New SAML Handler Configurations in AEM 6
This is a comma-separated list of groups that SSO users are automatically added to.
These are saml:Attribute elements from the SAMLResponse that will be stored along with the CRX user. Simulate these values by updating the ‘example-userpass’ authentication source in simplesamlphp/config/authsources.php with additional key/value pairs.
Handle Logout & Logout URL
This allows logouts to propagate back to the IdP and potentially to other SPs as well. Before enabling single logout, check out this Shibboleth article on the issues involved with implementing Single Logout. To give single logout a test, fill out the Logout URL by going back to the SimpleSAMLphp page that lists the IDP URL (SingleSignOnService) and copy the SingleLogoutService URL.
Limitations and Gotchas
There are a number of oddities surrounding use of the SAML Authentication Handler.
User Must Exist in AEM
Users logging in via the handler must exist, or if missing must be created in, AEM (“Autocreate CRX Users” must be checked). This is because the Sling authentication framework, which the SamlAuthenticationHandler is a part of, extracts user credentials from the SAMLResponse and logs into the JCR repository using those credentials.
Sitewide Anonymous Access with Optional Authentication
The authentication handler is built around protecting content from anonymous access via the Path configuration. If all pages on the AEM site need to be accessible anonymously, but authentication also needs to be an option, the Path configuration value can be set to a non-existent path. This will enable SAML authentication but also allow anonymous access to all pages on the site. If this strategy is used, make sure that the SAMLReponse POSTs to the correct saml_login path (see next item).
The Path configuration and saml_login
The IdP’s SAMLResponse must be posted to the page ‘saml_login’. However, the ‘saml_login’ page must be within the path that the authentication handler protects (i.e. the Path configuration). For instance, if the Path configuration is ‘/‘ the IdP can post to localhost:4502/saml_login. If the Path is ‘/content/geometrixx’ the IdP can post to localhost:4502/content/geometrixx/saml_login or localhost:4502/content/geometrixx/does-not-exist/saml_login but localhost:4502/content/saml_login will not work.
IdP Initiated Login and RelayState
In SP1, ensuring a user returns to the page they were on before logging in is done with the saml_request_path cookie and not the typical RelayState parameter found with most SSO implementations. Therefore, though IdP initiated authentication will finish successfully, the end user will not get sent to the page specified by RelayState. Consequently, if a custom login link is implemented on an AEM page (SP initiated login), make sure to set the saml_request_path cookie before sending the browser to the IdP.
No Resource Found Error
This most likely results from the logged-in user not having the appropriate permissions to view the page. To resolve this issue, make sure the SSO user is being given Read permissions to folders such as /content. This accomplished by configuring the authentication handler to add SSO users to a user group that has all necessary permissions set.