SAML 2.0 authentication
- Topics:
- Security
CREATED FOR:
- Intermediate
- Developer
Learn how to set up and authenticate end-users (not AEM authors) to a SAML 2.0 compatible IDP of your choosing.
What SAML for AEM as a Cloud Service?
SAML 2.0 integration with AEM Publish (or Preview), allows end users of an AEM-based web experience to authenticate to a non-Adobe IDP (Identity Provider), and access AEM as a named, authorized user.
The typical flow of an AEM Publish SAML integration is as follows:
-
User makes a request to AEM Publish the indicates authentication is required.
- User requests a CUGs/ACL protected resource.
- User requests a resource that is subject to an Authentication Requirement.
- User follows a link to AEM’s login endpoint (i.e.
/system/sling/login
) that explicitly requests the login action.
-
AEM makes an AuthnRequest to the IDP, requesting IDP to start authentication process.
-
User authenticates to IDP.
- User is prompted by the IDP for credentials.
- User is already authenticated with the IDP and does not have to provide further credentials.
-
IDP generates a SAML assertion containing the user’s data, and signs it using the IDP’s private certificate.
-
IDP sends the SAML assertion via HTTP POST, by way of the user’s web browser (RESPECTIVE_PROTECTED_PATH/saml_login), to AEM Publish.
-
AEM Publish receives the SAML assertion, and validates the SAML assertion’s integrity and authenticity using the IDP public certificate.
-
AEM Publish manages the AEM user record based on the SAML 2.0 OSGi configuration, and the contents of the SAML Assertion.
- Creates user
- Synchronizes user attributes
- Updates AEM user group membership
-
AEM Publish sets the AEM
login-token
cookie on the HTTP response, which is used to authenticate subsequent requests to AEM Publish. -
AEM Publish redirects user to URL on AEM Publish as specified by the
saml_request_path
cookie.
Configuration walk-through
This video walks through of setting up SAML 2.0 integration with AEM as a Cloud Service Publish service, and using Okta as the IDP.
Prerequisites
The following are required when setting up SAML 2.0 authentication:
- Deployment Manager access to Cloud Manager
- AEM Administrator access to AEM as a Cloud Service environment
- Administrator access to the IDP
- Optionally, access to a public/private keypair used to encryption SAML payloads
SAML 2.0 is only supported to authenticate uses to AEM Publish or Preview. To manage the authentication of AEM Author using and IDP, integrate the IDP with Adobe IMS.
Install IDP public certificate on AEM
The IDP’s public certificate is added to AEM’s Global Trust Store, and used to validate the SAML assertion sent by the IDP is valid.
- User authenticates to IDP.
- IDP generates a SAML assertion containing the user’s data.
- IDP signs the SAML assertion using the IDP’s private certificate.
- IDP initiates a client-side HTTP POST to AEM Publish’s SAML endpoint (
.../saml_login
) that includes the signed SAML assertion. - AEM Publish receives the HTTP POST containing the signed SAML assertion, can validate the signature using the IDP public certificate.
-
Obtain the public certificate file from the IDP. This certificate allows AEM to validate the SAML assertion provided to AEM by the IDP.
The certificate is in PEM format, and should resemble:
-----BEGIN CERTIFICATE----- MIIC4jCBAcoCCQC33wnybT5QZDANBgkqhkiG9w0BAQsFADAyMQswCQYDVQQGEwJV ... m0eo2USlSRTVl7QHRTuiuSThHpLKQQ== -----END CERTIFICATE-----
-
Log in to AEM Author as an AEM Administrator.
-
Navigate to Tools > Security > Trust Store.
-
Create or open the Global Trust Store. If creating a Global Trust Store, store the password some place safe.
-
Expand Add certificate from CER file.
-
Select Select Certificate File, and upload the certificate file provided by the IDP.
-
Leave Map Certificate to User blank.
-
Select Submit.
-
The newly added certificate appears above the Add certificate from CRT file section.
-
Make note of the alias, as this value is used in the SAML 2.0 Authentication Handler OSGi configuration.
-
Select Save & Close.
The Global Trust Store is configured with the IDP’s public certificate on AEM Author, but since SAML is only used on AEM Publish, the Global Trust Store must be replicated to AEM Publish for the IDP public certificate to be accessible there.
-
Navigate to Tools > Deployment > Packages.
-
Create a package
- Package name:
Global Trust Store
- Version:
1.0.0
- Group:
com.your.company
- Package name:
-
Edit the new Global Trust Store package.
-
Select the Filters tab, and add a filter for the root path
/etc/truststore
. -
Select Done and then Save.
-
Select the Build button for the Global Trust Store package.
-
Once built, select More > Replicate to activate the Global Trust Store node (
/etc/truststore
) to AEM Publish.
Create authentication-service keystore
Creating a keystore for authentication-service is required when the SAML 2.0 authentication handler OSGi configuration property handleLogout
is set to true
or when AuthnRequest signing/SAML assertion ecryption is required
-
Log in to AEM Author as an AEM Administrator, to upload the private key.
-
Navigate to Tools > Security > Users, and select authentication-service user, and select Properties from the top action bar.
-
Select the Keystore tab.
-
Create or open the keystore. If creating a keystore, keep the password safe.
- A public/private keystore is installed into this keystore only if AuthnRequest signing/SAML assertion encryption is required.
- If this SAML integration supports logout, but not AuthnRequest signing/SAML assertion, then an empty keystore is sufficient.
-
Select Save & Close.
-
Create a package containing the updated authentication-service user.
Use the following temporary workaround using packages:
-
Navigate to Tools > Deployment > Packages.
-
Create a package
- Package name:
Authentication Service
- Version:
1.0.0
- Group:
com.your.company
- Package name:
-
Edit the new Authentication Service Key Store package.
-
Select the Filters tab, and add a filter for the root path
/home/users/system/cq:services/internal/security/<AUTHENTICATION SERVICE UUID>/keystore
.- The
<AUTHENTICATION SERVICE UUID>
can be found by navigating to Tools > Security > Users, and selecting authentication-service user. The UUID is the last part of the URL.
- The
-
Select Done and then Save.
-
Select the Build button for the Authentication Service Key Store package.
-
Once built, select More > Replicate to activate the Authentication Service key store to AEM Publish.
-
Install AEM public/private key pair
Installing the AEM public/private key pair is optional
AEM Publish can be configured to sign AuthnRequests (to IDP), and encrypt SAML assertions (to AEM). This is achieved by providing a private key to AEM Publish, and it’s matching public key to the IDP.
The AuthnRequest (the request to the IDP from AEM Publish that initiates the login process) can be signed by AEM Publish. To do this, AEM Publish signs the AuthnRequest using the private key, that the IDP then validates the signature using the public key. This guarantees to the IDP that AuthnRequest was initiated, and requested by AEM Publish, and not a malicious third party.
- User makes an HTTP request to AEM Publish that results in an SAML authentication request to the IDP.
- AEM Publish generates the SAML request to send to the IDP.
- AEM Publish signs the SAML request using AEM’s private key.
- AEM Publish initiates the AuthnRequest, an HTTP client-side redirect to the IDP that contains the signed SAML request.
- IDP receives the AuthnRequest, and validates the signature using AEM’s public key, guaranteeing AEM Publish initiated the AuthnRequest.
- AEM Publish then validates the decrypted SAML assertion’s integrity and authenticity using the IDP public certificate.
All HTTP communication between IDP and AEM Publish should be over HTTPS, and thus secure by default. However, as required, SAML assertions can be encrypted in the event extra confidentiality is required on top of that provided by HTTPS. To do this, the IDP encrypts the SAML Assertion data using the private key, and AEM Publish decrypts the SAML assertion using the private key.
- User authenticates to IDP.
- IDP generates a SAML assertion containing the user’s data, and signs it using the IDP’s private certificate.
- IDP then encrypts the SAML assertion with AEM’s public key, which requires the AEM private key to decrypt.
- The encrypted SAML assertion is sent, by way of the user’s web browser to AEM Publish.
- AEM Publish receives the SAML assertion, and decrypts it using AEM’s private key.
- IDP prompts user to authenticate.
Both AuthnRequest signing, and SAML assertion encryption are optional, however they are both enabled, using the SAML 2.0 authentication handler OSGi configuration property useEncryption
, meaning both or neither can be used.
-
Obtain the public key, private key (PKCS#8 in DER format), and certificate chain file (this may be the public key) used to sign the AuthnRequest, and encrypt the SAML assertion. The keys are typically provided by the IT organization’s security team.
- A self-signed key pair can be generated using openssl:
$ openssl req -x509 -sha256 -days 365 -newkey rsa:4096 -keyout aem-private.key -out aem-public.crt # Provide a password (keep in safe place), and other requested certificate information # Convert the keys to AEM's required format $ openssl rsa -in aem-private.key -outform der -out aem-private.der $ openssl pkcs8 -topk8 -inform der -nocrypt -in aem-private.der -outform der -out aem-private-pkcs8.der
-
Upload the public key to the IDP.
- Using the
openssl
method above, the public key is theaem-public.crt
file.
- Using the
-
Log in to AEM Author as an AEM Administrator, to upload the private key.
-
Navigate to Tools > Security > Trust Store, and select authentication-service user, and select Properties from the top action bar.
-
Navigate to Tools > Security > Users, and select authentication-service user, and select Properties from the top action bar.
-
Select the Keystore tab.
-
Create or open the keystore. If creating a keystore, keep the password safe.
-
Select Add private key from DER file, and add the private key and chain file to AEM:
- Alias: Provide a meaningful name, often the name of the IDP.
- Private key file: Upload the private key file (PKCS#8 in DER format).
- Using the
openssl
method above, this is theaem-private-pkcs8.der
file
- Using the
- Select certificate chain file: Upload the accompanying chain file (this may be the public key).
- Using the
openssl
method above, this is theaem-public.crt
file
- Using the
- Select Submit
-
The newly added certificate appears above the Add certificate from CRT file section.
- Make note of the alias as this is used in the SAML 2.0 authentication handler OSGi configuration
-
Select Save & Close.
-
Create a package containing the updated authentication-service user.
Use the following temporary workaround using packages:
-
Navigate to Tools > Deployment > Packages.
-
Create a package
- Package name:
Authentication Service
- Version:
1.0.0
- Group:
com.your.company
- Package name:
-
Edit the new Authentication Service Key Store package.
-
Select the Filters tab, and add a filter for the root path
/home/users/system/cq:services/internal/security/<AUTHENTICATION SERVICE UUID>/keystore
.- The
<AUTHENTICATION SERVICE UUID>
can be found by navigating to Tools > Security > Users, and selecting authentication-service user. The UUID is the last part of the URL.
- The
-
Select Done and then Save.
-
Select the Build button for the Authentication Service Key Store package.
-
Once built, select More > Replicate to activate the Authentication Service key store to AEM Publish.
-
Configure SAML 2.0 authentication handler
AEM’s SAML configuration is performed via the Adobe Granite SAML 2.0 Authentication Handler OSGi configuration.
The configuration is an OSGi factory configuration, meaning a single AEM as a Cloud Service Publish service may have multiple SAML configuration’s covering discrete resources trees of the repository; this is useful for multi-site AEM deployments.
Adobe Granite SAML 2.0 Authentication Handler OSGi configuration
path
/
idpUrl
idpCertAlias
idpHttpRedirect
false
true
for IDP initiated authentication.idpIdentifier
serviceProviderEntityId
is used instead.assertionConsumerServiceURL
AssertionConsumerServiceURL
URL attribute in the AuthnRequest specifying where the <Response>
message must be sent to AEM.serviceProviderEntityId
useEncryption
true
spPrivateKeyAlias
and keyStorePassword
to be set.spPrivateKeyAlias
authentication-service
user’s key store. Required if useEncryption
is set to true
.keyStorePassword
useEncryption
is set to true
.defaultRedirectUrl
/
/content/wknd/us/en/html
).userIDAttribute
uid
Subject:NameId
.createUser
true
userIntermediatePath
/home/users/<userIntermediatePath>/jane@wknd.com
). Requires createUser
to be set to true
.synchronizeAttributes
[ "saml-attribute-name=path/relative/to/user/node" ]
(for example, [ "firstName=profile/givenName" ]
). See the full list of native AEM attributes.addGroupMemberships
true
groupMembershipAttribute
groupMembership
addGroupMemberships
to be set to true
.defaultGroups
[ "wknd-user" ]
). Requires addGroupMemberships
to be set to true
.nameIdFormat
urn:oasis:names:tc:SAML:2.0:nameid-format:transient
storeSAMLResponse
false
samlResponse
value is stored on the AEM cq:User
node.handleLogout
false
logoutUrl
to be set.logoutUrl
handleLogout
is set to true
.clockTolerance
60
digestMethod
http://www.w3.org/2001/04/xmlenc#sha256
signatureMethod
http://www.w3.org/2001/04/xmldsig-more#rsa-sha256
identitySyncType
default
or idp
default
from
default for AEM as a Cloud Service.service.ranking
5002
path
.AEM user attributes
AEM uses the following user attributes, which can be populated via the synchronizeAttributes
property in the Adobe Granite SAML 2.0 Authentication Handler OSGi configuration. Any IDP attributes can be synchronized to any AEM user property, however mapping to AEM use attribute properties (listed below) allows AEM to naturally use them.
rep:User
nodeMrs
)profile/title
profile/givenName
profile/familyName
profile/jobTitle
profile/email
profile/street
profile/city
profile/postalCode
profile/country
profile/phoneNumber
profile/aboutMe
-
Create an OSGi configuration file in your project at
/ui.config/src/main/content/jcr_root/wknd-examples/osgiconfig/config.publish/com.adobe.granite.auth.saml.SamlAuthenticationHandler~saml.cfg.json
and open in your IDE.- Change
/wknd-examples/
to your/<project name>/
- The identifier after the
~
in the filename should uniquely identify this configuration, so it may be the name of the IDP, such as...~okta.cfg.json
. The value should be alphanumeric with hyphens.
- Change
-
Paste the following JSON into the
com.adobe.granite.auth.saml.SamlAuthenticationHandler~...cfg.json
file, and update thewknd
references as needed.{ "path": [ "/content/wknd", "/content/dam/wknd" ], "idpCertAlias": "$[env:SAML_IDP_CERT_ALIAS;default=certalias___1652125559800]", "idpIdentifier": "$[env:SAML_IDP_ID;default=http://www.okta.com/exk4z55r44Jz9C6am5d7]", "idpUrl": "$[env:SAML_IDP_URL;default=https://dev-5511372.okta.com/app/dev-5511372_aemasacloudservice_1/exk4z55r44Jz9C6am5d7/sso/saml]", "serviceProviderEntityId": "$[env:SAML_AEM_ID;default=https://publish-p123-e456.adobeaemcloud.com]", "useEncryption": false, "createUser": true, "userIntermediatePath": "wknd/idp", "synchronizeAttributes":[ "firstName=profile/givenName" ], "addGroupMemberships": true, "defaultGroups": [ "wknd-users" ] }
-
Update the values as required by your project. See the SAML 2.0 Authentication Handler OSGi configuration glossary above for configuration property descriptions
-
It is recommended, but not required, to use OSGi environment variables and secrets, when values may change out of sync with the release cycle, or when the values different between similar environment types/service tiers. Default values can be set using the
$[env:..;default=the-default-value]"
syntax as shown above.
OSGi configurations per environment (config.publish.dev
, config.publish.stage
, and config.publish.prod
) can be defined with specific attributes if the SAML configuration varies between environments.
Use encryption
When encrypting the AuthnRequest and SAML assertion, the following properties are required: useEncryption
, spPrivateKeyAlias
, and keyStorePassword
. The keyStorePassword
contains a password therefore the value must not be stored in the OSGi configuration file, but rather injected using secret configuration values
-
Open
/ui.config/src/main/content/jcr_root/wknd-examples/osgiconfig/config.publish/com.adobe.granite.auth.saml.SamlAuthenticationHandler~saml.cfg.json
in your IDE. -
Add the three properties
useEncryption
,spPrivateKeyAlias
, andkeyStorePassword
as shown below.{ "path": [ "/content/wknd", "/content/dam/wknd" ], "idpCertAlias": "$[env:SAML_IDP_CERT_ALIAS;default=certalias___1234567890]", "idpIdentifier": "$[env:SAML_IDP_ID;default=http://www.okta.com/abcdef1235678]", "idpUrl": "$[env:SAML_IDP_URL;default=https://dev-5511372.okta.com/app/dev-123567890_aemasacloudservice_1/abcdef1235678/sso/saml]", "serviceProviderEntityId": "$[env:SAML_AEM_ID;default=https://publish-p123-e456.adobeaemcloud.com]", "useEncryption": true, "spPrivateKeyAlias": "$[env:SAML_AEM_KEYSTORE_ALIAS;default=aem-saml-encryption]", "keyStorePassword": "$[secret:SAML_AEM_KEYSTORE_PASSWORD]", "createUser": true, "userIntermediatePath": "wknd/idp" "synchronizeAttributes":[ "firstName=profile/givenName" ], "addGroupMemberships": true, "defaultGroups": [ "wknd-users" ] }
-
The three OSGi configuration properties required for encryption are:
useEncryption
set totrue
spPrivateKeyAlias
contains the keystore entry alias for the private key used by the SAML integration.keyStorePassword
contains an OSGi secret configuration variable containing theauthentication-service
user keystore’s password.
Configure Referrer filter
During the SAML authentication process, the IDP initiates a client-side HTTP POST to AEM Publish’s .../saml_login
end point. If the IDP and AEM Publish exist on different origin, AEM Publish’s Referrer Filter is configured via OSGi configuration to allow HTTP POSTs from the IDP’s origin.
-
Create (or edit) an OSGi configuration file in your project at
/ui.config/src/main/content/jcr_root/wknd-examples/osgiconfig/config.publish/org.apache.sling.security.impl.ReferrerFilter.cfg.json
.- Change
/wknd-examples/
to your/<project name>/
- Change
-
Ensure the
allow.empty
value is set totrue
, theallow.hosts
(or if you prefer,allow.hosts.regexp
) contains the IDP’s origin, andfilter.methods
includesPOST
. The OSGi configuration should be similar to:{ "allow.empty": true, "allow.hosts.regexp": [ ], "allow.hosts": [ "$[env:SAML_IDP_REFERRER;default=dev-123567890.okta.com]" ], "filter.methods": [ "POST", ], "exclude.agents.regexp": [ ] }
AEM Publish supports a single Referrer filter configuration, so merge the SAML configuration requirements, with any existing configurations.
OSGi configurations per environment (config.publish.dev
, config.publish.stage
, and config.publish.prod
) can be defined with specific attributes if the allow.hosts
(or allow.hosts.regex
) vary between environments.
Configure Cross-Origin Resource Sharing (CORS)
During the SAML authentication process, the IDP initiates a client-side HTTP POST to AEM Publish’s .../saml_login
end point. If the IDP and AEM Publish exist on different hosts/domains, AEM Publish’s CRoss-Origin Resource Sharing (CORS) must be configured to allow HTTP POSTs from the IDP’s host/domain.
This HTTP POST request’s Origin
header usually has a different value than the AEM Publish host, thus requiring CORS configuration.
When testing SAML authentication on the local AEM SDK (localhost:4503
), the IDP may set the Origin
header to null
. If so, add "null"
to the alloworigin
list.
-
Create an OSGi configuration file in your project at
/ui.config/src/main/content/jcr_root/wknd-examples/osgiconfig/config.publish/com.adobe.granite.cors.impl.CORSPolicyImpl~saml.cfg.json
- Change
/wknd-examples/
to your project name - The identifier after the
~
in the filename should uniquely identify this configuration, so it may be the name of the IDP, such as...CORSPolicyImpl~okta.cfg.json
. The value should be alphanumeric with hyphens.
- Change
-
Paste the following JSON into the
com.adobe.granite.cors.impl.CORSPolicyImpl~...cfg.json
file.
{
"alloworigin": [
"$[env:SAML_IDP_ORIGIN;default=https://dev-1234567890.okta.com]",
"null"
],
"allowedpaths": [
".*/saml_login"
],
"supportedmethods": [
"POST"
]
}
OSGi configurations per environment (config.publish.dev
, config.publish.stage
, and config.publish.prod
) can be defined with specific attributes if the alloworigin
and allowedpaths
varies between environments.
Configure AEM Dispatcher to allow SAML HTTP POSTs
After successful authentication to the IDP, the IDP will orchestrate an HTTP POST back to AEM’s registered /saml_login
end point (configured in the IDP). This HTTP POST to /saml_login
is blocked by default at Dispatcher, so it must be explicitly allowed using the following Dispatcher rule:
- Open
dispatcher/src/conf.dispatcher.d/filters/filters.any
in your IDE. - Add to the bottom of the file, an allow rule for HTTP POSTs to URLs that end with
/saml_login
.
...
# Allow SAML HTTP POST to ../saml_login end points
/0190 { /type "allow" /method "POST" /url "*/saml_login" }
If URL rewriting at the Apache webserver is configured (dispatcher/src/conf.d/rewrites/rewrite.rules
), ensure that requests to the .../saml_login
end points are not accidentally mangled.
Dynamic Group Membership
Dynamic Group Membership is a feature in Apache Jackrabbit Oak that increases the performance of group evaluation and provisioning. This section describes how users and groups are stored when this feature is enabled and how to modify the configuration of the SAML Authentication Handler to enable it for new or existing environments.
How to enable Dynamic Group Membership for SAML Users in new environments
To significantly enhance group evaluation performance in new AEM as a Cloud Service environments, the activation of the Dynamic Group Membership feature is recommended in new environments.
This is also a necessary step when data synchronization is activated. More details here .
To do this, add the following property to the OSGI configuration file:
/apps/example/osgiconfig/config.publish/com.adobe.granite.auth.saml.SamlAuthenticationHandler~example.cfg.json
With this configuration, users and groups are created as Oak External Users. In AEM, external users and groups have a default rep:principalName
composed by [user name];[idp]
or [group name];[idp]
.
Remark that Access Control Lists (ACL) are associated with the PrincipalName of users or groups.
When deploying this configuration in an existing deployment where previously identitySyncType
was not specified or set to default
, new users and groups will be created and ACL must be applied to these new users and groups. Note that external groups cannot contain local users. Repoinit can be used to create ACL for SAML External groups, even if they will be only created when the user will perform a login.
To avoid this refactoring on ACL, a standard migration feature has been implemented.
How memberships are stored in local and external groups with dynamic group membership
On local groups the group members are stored in the oak attribute: rep:members
. The attribute contains the list of uid of every member of the group. Additional details can be found here.
Example:
{
"jcr:primaryType": "rep:Group",
"rep:principalName": "operators",
"rep:managedByIdp": "SAML",
"rep:members": [
"635afa1c-beeb-3262-83c4-38ea31e5549e",
"5e496093-feb6-37e9-a2a1-7c87b1cec4b0",
...
],
...
}
External groups with dynamic group membership do not store any member in the group entry.
The group membership is instead stored in the users entries. Additional documentation can be found here. For example this is the OAK node for the group:
{
"jcr:primaryType": "rep:Group",
"jcr:mixinTypes": [
"rep:AccessControllable"
],
"jcr:createdBy": "",
"jcr:created": "Tue Jul 16 2024 08:58:47 GMT+0000",
"rep:principalName": "GROUP_1;aem-saml-idp-1",
"rep:lastSynced": "Tue Jul 16 2024 08:58:47 GMT+0000",
"jcr:uuid": "d9c6af8a-35c0-3064-899a-59af55455cd0",
"rep:externalId": "GROUP_1;aem-saml-idp-1",
"rep:authorizableId": "GROUP_1;aem-saml-idp-1"
}
This is the node for a user member of that group:
{
"jcr:primaryType": "rep:User",
"jcr:mixinTypes": [
"rep:AccessControllable"
],
"surname": "Test",
"rep:principalName": "testUser",
"rep:externalId": "test;aem-saml-idp-1",
"rep:authorizableId": "test",
"rep:externalPrincipalNames": [
"projects-users;aem-saml-idp-1",
"GROUP_2;aem-saml-idp-1",
"GROUP_1;aem-saml-idp-1",
"operators;aem-saml-idp-1"
],
...
}
How to enable Dynamic Group Membership for SAML Users in existing environments
As explained in the previous section, the format of external users and groups is slightly different from the one used for local users and groups. It’s possible to define a new ACL for external groups and provision new external users, or use the migration tool as described below.
Enabling dynamic group membership for existing environments with external users
The SAML Authentication handler creates external users when the following property is specified: "identitySyncType": "idp"
. In this case, dynamic group membership can be enabled modifying this property to: "identitySyncType": "idp_dynamic"
. No migration is required.
Automatic migration to dynamic group membership for existing environments with local users
The SAML Authentication handler creates local users when the following property is specified: "identitySyncType": "default"
. This is also the default value when the property is not specified. In this section we describe the steps performed by the automatic migration procedure.
When this migration is enabled, it is carried out during user authentication and consists of the following steps:
- The local user is migrated to an external user while maintaining the original username. This implies that migrated local users, now acting as external users, retain their original username instead of following the naming syntax mentioned in the previous section. One additional property will be added called:
rep:externalId
with the value of[user name];[idp]
. The userPrincipalName
is not modified. - For each external group received in the SAML Assertion, an external group is created. If a corresponding local group exists, the external group is added to the local group as a member.
- The user is added as member of the external group.
- The local user is then removed from all the Saml local groups he was member of. Saml local groups are identified by the OAK property:
rep:managedByIdp
. This property is set by the Saml Authentication handler when the attributesyncType
is not specified or set todefault
.
For instance, if before the migration user1
is a local user and a member of local group group1
, after the migration the following changes will occur:user1
becomes an external user. The attribute rep:externalId
is added to his profile.user1
becomes member of external group: group1;idp
user1
is no longer a direct member of local group: group1
group1;idp
is a member of the local group: group1
.user1
is then a member of the local group: group1
though inheritance
The group membership for external groups is stored in the user profile in the property rep:externalPrincipalNames
How to configure automatic migration to dynamic group membership
- Enable the property
"identitySyncType": "idp_dynamic_simplified_id"
in SAML OSGi configuration file:com.adobe.granite.auth.saml.SamlAuthenticationHandler~...cfg.json
: - Configure the new OSGi service with Factory PID starting with:
com.adobe.granite.auth.saml.migration.SamlDynamicGroupMembershipMigration~
. For example, a PID can be:com.adobe.granite.auth.saml.migration.SamlDynamicGroupMembershipMigration~myIdP
. Set the following property:
{
"idpIdentifier": "<value of IDP Identifier (idpIdentifier)" property from the "com.adobe.granite.auth.saml.SamlAuthenticationHandler" configuration to be migrated>"
}
To migrate multiple SAML configurations, multiple OSGi factory configurations for com.adobe.granite.auth.saml.migration.SamlDynamicGroupMembershipMigration
must be created, each specifying an idpIdentifier
to migrate.
Deploying SAML configuration
The OSGi configurations must be committed to Git and deployed to AEM as a Cloud Service using Cloud Manager.
$ git remote -v
adobe https://git.cloudmanager.adobe.com/myOrg/myCloudManagerGit/ (fetch)
adobe https://git.cloudmanager.adobe.com/myOrg/myCloudManagerGit/ (push)
$ git add .
$ git commit -m "SAML 2.0 configurations"
$ git push adobe saml-auth:develop
Deploy the target Cloud Manager Git branch (in this example, develop
), using a Full Stack deployment pipeline.
Invoking the SAML authentication
The SAML authentication flow can be invoked from an AEM Site web page, by creating a specially crafted links, or a buttons. The parameters described below can be programmatically set as needed, so for instance, a log in button may set the saml_request_path
, which is where the user is taken upon successful SAML authentication, to different AEM pages, based on the context of the button.
Secured Caching while using SAML
On the AEM publish instance, most pages are typically cached. However, for SAML-protected paths, caching should either be disabled or secured caching enabled using the auth_checker configuration. For more information, please refer to the details provided here
Please be aware that if you cache protected paths without enabling the auth_checker, you may experience unpredictable behavior.
GET request
SAML authentication can be invoked by creating a HTTP GET request in the format:
HTTP GET /system/sling/login
and providing query parameters:
resource
path
property.saml_request_path
For example, this HTML link will trigger the SAML log in flow, and upon success take the user to /content/wknd/us/en/protected/page.html
. These query parameters can be programmaticaly set as needed.
<a href="/system/sling/login?resource=/content/wknd&saml_request_path=/content/wknd/us/en/protected/page.html">
Log in using SAML
</a>
POST request
SAML authentication can be invoked by creating a HTTP POST request in the format:
HTTP POST /system/sling/login
and providing the form data:
resource
path
property.saml_request_path
For example, this HTML button will use a HTTP POST to trigger the SAML log in flow, and upon success, take the user to /content/wknd/us/en/protected/page.html
. These form data parameters can be programmaticaly set as needed.
<form action="/system/sling/login" method="POST">
<input type="hidden" name="resource" value="/content/wknd">
<input type="hidden" name="saml_request_path" value="/content/wknd/us/en/protected/page.html">
<input type="submit" value="Log in using SAML">
</form>
Dispatcher configuration
Both the HTTP GET and POST methods require client access to AEM’s /system/sling/login
endpoints, and thus they must be allowed via AEM Dispatcher.
Allow the necessary URL patterns based on if GET or POST isused
# Allow GET-based SAML authentication invocation
/0191 { /type "allow" /method "GET" /url "/system/sling/login" /query "*" }
# Allow POST-based SAML authentication invocation
/0192 { /type "allow" /method "POST" /url "/system/sling/login" }