SSO module
Security and authentication Unbundled: Extension
Edition |
DX Core |
License |
|
Issues |
|
Maven site |
|
Latest |
4.0.2 |
| The SSO module handles authentication for the instance on which it is installed. Read this page carefully and test the module on a development environment before proceeding to ensure installation does not break your instance. |
The Magnolia SSO (single sign-on) module delegates authentication from a Magnolia instance to an OpenID Connect identity and access management application. The current iteration of the module has been successfully tested with open source Keycloak and cloud identity management software Okta, but all providers that follow the protocol should also be supported.
As Magnolia is already capable of full-fledged security, the intent is to only replace the authentication mechanism. A user on a third-party system with roles and groups is mapped to the equivalent Magnolia user roles and groups.
SSO module version 4.0.0+ is compiled with Java 11, so you need Java 11 or higher for runtime.
|
Installing with Maven
Maven is the easiest way to install the module. Add the following to your bundle:
<dependency>
<groupId>info.magnolia.sso</groupId>
<artifactId>magnolia-sso</artifactId>
<version>4.0.2</version> (1)
</dependency>
| 1 | Should you need to specify the module version, do it using <version>. |
|
Depending on your setup,
You can fix them with the following exclusion dependency in your parent
|
Prerequisites
A running Open ID Connect (OIDC) IAM instance on which you have administrative rights is required for the setup to work. Any IAM instance should work, as long as it is configured in the manner described in this document.
If you use Keycloak and intend to deploy it by code, then take a look at the SsoModuleIT class and the module’s test Docker Compose setup. The module’s integration tests configure Keycloak from scratch. |
| Prerequisite | Description | ||
|---|---|---|---|
a user |
required Their username and password are used to access Admincentral. They should have names as well as an email. |
||
a group |
required When the user logs in, they have to belong to at least one group defined in the group mappings. That’s how the necessary access to Magnolia is granted.
|
||
an OIDC client |
required With the following properties: |
||
a name |
required Must be the same as the one used in the YAML configuration of the module. |
||
the |
required |
||
a confidential access type |
required This is required to generate credentials. |
||
credentials |
required Those must be shared with the YAML configuration of the module. |
||
a redirect URI |
required That points back to Magnolia, e.g. |
||
a Group Membership mapper |
required By convention, this is required in order to include the user’s groups in the
|
If you are not using a default Magnolia bundle, check that your Apache Tomcat cookie processor implementation has sameSiteCookies set to lax: <CookieProcessor sameSiteCookies="Lax" />.
For more information, see Troubleshooting .
|
SSO user profile information
User profile preferences related to the Magnolia instance for SSO users is stored in the profiles workspace that may only be accessed by the superuser.
The following information is stored in the profiles workspace for SSO users:
-
Full name
-
Email
-
Favorite apps
-
Language
-
Last login
-
Previous login
-
Timezone
-
Completed intro status (Magnolia app launcher tour)
-
Usage metrics acknowledgement status
| SSO users can set their user preferences for timezone and language in AdminCentral. |
The information for each user is stored based on the username from the third-party IdP. If you change a user’s username in your IdP, their preferences are reset in Magnolia.
Configuring via yaml
This section explains how to configure the SSO module for Magnolia 6.3.
It focuses on configuring the setup for an OIDC provider.
This must be done with a resource file located by default in /magnolia-sso/config.yaml.
If the magnolia.sso.config property is added to the magnolia.properties file, this path can be configured so that environment-specific configurations may be defined.
From version 3.x, the SSO module no longer supports configuration via a YAML decorator.
|
-
Create
config.yamlunder<magnolia.resources.dir>/magnolia-sso/.Take a look at the full
.yamlfile here. Required fields are marked with callouts. We’ll go through each part of it in the subsequent steps.config.yamlcallbackUrl: /.auth (1) postLogoutRedirectUri: http://localhost:8080 authorizationGenerators: (1) - name: fixedRoleAuthorization fixed: targetRoles: - superuser targetGroups: - publishers - name: groupsAuthorization groups: targetProperty: groups mappings: - name: superusers targetGroups: - publishers targetRoles: - superuser clients: (1) oidc.name: defaultOidcClient (2) oidc.id: 0o...x7 oidc.secret: aK...th6 oidc.clientAuthenticationMethod: client_secret_basic oidc.scope: openid profile email oidc.discoveryUri: https://YOUR_URI/oauth2/aus...0x7/.well-known/openid-configuration oidc.preferredJwsAlgorithm: RS256 oidc.authorizationGenerators: groupsAuthorization oidc.callbackUrl: /.auth oidc.postLogoutRedirectUri: http://localhost:8080 (2) userFieldMappings: (1) name: preferred_username removeEmailDomainFromUserName: false removeSpecialCharactersFromUserName: false fullName: name email: email language: locale1 Required field. 2 Optional field. -
callbackUrlrequires a global configuration (this step) or a configuration in the clients section. Skip this step to specify it in theclientssection.If you specify callbackUrlat the top of the configuration and in theclientssection, the client configuration overrides the general setting at the top. Any client configuration overrides the general setting at the top.Specify the
callbackUrlfor each client. It is a relative path to the SSOCallbackServlet (For example,/.auth).callbackUrl: /.auth (1) ...1 This relative URL doesn’t need to match defaultBaseURL, the default base URL of the server root. DefaultUrlResolvercompletes relative URLs usingdefaultUrlResolver.setCompleteRelativeUrl(true)from pac4j. For more details, see Field descriptions. -
If desired, set a
postLogoutRedirectUri. This is optional and is the URI to which users are redirected after logging out. Skip this step to specify it in theclientssection.If you specify postLogoutRedirectUriat the top of the configuration and in theclientssection, the client configuration overrides the general setting at the top. If it isn’t set to a value either globally or in theclientssection, it redirects to therequestUrlwhen logging out.callbackUrl: /.auth postLogoutRedirectUri: http://localhost:8080 (1) ...1 If undefined, it goes back to the user’s current URL. For more details, see Field descriptions. -
If desired, set a
callbackUrlResolverType. This is optional and is to use path parameters instead of query parameters. Skip this step if you are using a standard that supports query parameters.For use cases that don’t support query parameters, such as certain Azure setups or social logins, you may configure the callback URLs to use path parameters as described below.
- config.yaml
-
callbackUrl: /.auth postLogoutRedirectUri: http://localhost:8080 callbackUrlResolverType: path (1) ...1 If undefined, the default method is query parameters. For more details, see Field descriptions.
- Configuration app
-
In addition to the configuration above, you must add a setting for the servlet.
/server/filters/servlets/SSOCallbackServlet/mappings/-.auth Node name
Value
⸬ -.auth
⬩ pattern
/.auth/*
/.auth/*allows any client. Alternatively,/.auth/client1allows onlyclient1.
-
List the
authorizationGenerators.This defines the groups and roles for your client. These are needed for groups generators and fixed role generators. If you want a custom generator, follow the steps here.
callbackUrl: /.auth postLogoutRedirectUri: http://localhost:8080 authorizationGenerators: (1) - name: groupsAuthorization groups: targetProperty: groups (2) mappings: - name: superusers (3) targetGroups: - publishers targetRoles: - superuser1 This step simply defines your mappings. You need to call it inside your clients:configuration in thisconfig.yamlto use it. For more details, see Field descriptions.2 targetPropertymaps to the groups in your IDP. By default, the value isgroupsbut if your IDP uses a different term, you can configure it here.3 If you are using a full path option (such as the option with Keycloak), ensure that is reflected here ( /superusers). Otherwise, specify the groupnameas shown in the example. -
Configure the
clientssection.You can define general settings for callbackUrlandpostLogoutRedirectUriat the top of the configuration. Any client configuration overrides the general setting at the top.-
Specify the
callbackUrlfor each client. It is a relative path to the SSOCallbackServlet (For example,/.auth).clients: ... oidc.callbackUrl: /.auth (1) ...1 This relative URL doesn’t need to match defaultBaseURL, the default base URL of the server root. DefaultUrlResolvercompletes relative URLs usingdefaultUrlResolver.setCompleteRelativeUrl(true)from pac4j. For more details, see Field descriptions. -
Optionally, set a
postLogoutRedirectUrifor each client. It is the URI to which users are redirected after logging out.clients: ... oidc.callbackUrl: /.auth oidc.postLogoutRedirectUri: http://localhost:8080 (1) ...1 If undefined, it goes back to the user’s current URL. For more details, see Field descriptions. -
Specify the remaining
oidcproperties for each client.... clients: oidc.id: 0o...x7 (1) oidc.secret: aK...th6 (1) oidc.clientAuthenticationMethod: client_secret_basic (2) oidc.scope: openid profile email (3) oidc.discoveryUri: https://YOUR_URI/.well-known/openid-configuration (4) oidc.preferredJwsAlgorithm: RS256 (5) oidc.authorizationGenerators: groupsAuthorization (6) oidc.callbackUrl: /.auth oidc.postLogoutRedirectUri: http://localhost:8080 oidc.id.2: 0o...g3 (7) oidc.secret.2: l3...jE3 oidc.clientAuthenticationMethod.2: client_secret_basic oidc.scope.2: openid profile email oidc.discoveryUri.2: https://YOUR_URI/.well-known/openid-configuration oidc.preferredJwsAlgorithm.2: RS256 oidc.authorizationGenerators.2: groupsAuthorization oidc.callbackUrl.2: http://localhost:8080/.auth oidc.postLogoutRedirectUri.2: http://localhost:8080 oidc.id.3: 0o...x7 oidc.secret.3: aK...th6 oidc.authorizationGenerators.3: CustomAuthorizationGenerator (8)1 You’ll find the idandsecretwith your OIDC provider configuration.2 Defines how the client credentials (client ID and secret) are passed to the token endpoint. Supported methods are: client_secret_basic,client_secret_postandprivate_key_jwt.3 Defines the user data that the Magnolia instance should be allowed to request from OIDC. For more on scope, see here. Theopenid,profile, andemailscopes are mandatory. For more details, see Field descriptions.4 The IAM instance’s auth endpoint URL. This must be tweaked according to your OIDC provider. 5 The preferredJwsAlgorithm. This is typicallyRS256.6 Defines the authorization generator names to use for the client as set in the authorizationGeneratorssection in thisconfig.yamlfile. For more details, see Field descriptions.7 Define a second client with the .2suffix. For more details, see Field descriptions.8 It’s possible to define custom authorization generators as well. If you want a custom generator, follow the steps here.
-
-
Update your custom field mappings under
userFieldMappingsproperty. For more details, see Field descriptions.... userFieldMappings: name: preferred_username (1) removeEmailDomainFromUserName: false (2) removeSpecialCharactersFromUserName: false (3) fullName: name email: email language: locale1 Required nameis a required field for the Magnolia User. Typically the value that you get from the Oidc profile attribute name ispreferred_usernameoremail.2 Optional removeEmailDomainFromUserNameisfalseby default. This is a built-in formatter to remove the email domain from the name attribute (e.g.,test-user@domain.comwill betest-userif this config is set totrue).3 Optional removeSpecialCharactersFromUserNameisfalseby default. This is a built-in formatter to remove all special characters from the attribute except dots, hyphens, and underscores.
Field descriptions
| Callout | Description | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Required The URL of Magnolia’s callback servlet. You can set For the relative path, |
|||||||||||||||||||||||||||||||||||
|
Optional The URI to where the user is returned after logging out. This must be an absolute URL. If the property isn’t defined, it falls back to the user’s current request URL.
For example, if the URL is set to If the property is defined, for example as |
||||||||||||||||||||||||||||||||||
|
Optional Setting this property to If the property isn’t defined, query parameters are the default resolver type.
For one OIDC client, there is no need to pass a parameter because at least two OIDC clients are required to make the If the property is defined, and set to |
||||||||||||||||||||||||||||||||||
|
Required A list of configured authorization generators as part of a specified client. Currently, we support both Fixed and Group authorization. After defining these here, you need to call them in the This generator should be used when different security levels in the IDP should be mapped to equivalent Magnolia roles and groups. Given a user’s groups on a third-party IAM management instance, the generator maps the group(s) to one or multiple Magnolia roles. The following example maps the the IDP
The fixed role generator gives all users the same permissions.
|
||||||||||||||||||||||||||||||||||
Required A set of properties for different clients (Oidc and DirectBearerAuthClient with
An
|
|||||||||||||||||||||||||||||||||||
|
Required Authentication services use different attribute names for user information. Because of this, it is necessary to map the retrieved response to a standard set of user attributes used within the SSO module. This contains key-value pair mappings where the
|
Minimal configuration
A minimal configuration is shown below using all the default values mentioned in the previous section.
callbackUrl: /.auth (1)
authorizationGenerators:
- name: groupsAuthorization
groups:
targetProperty: groups
mappings:
- name: superusers
targetRoles:
- superuser
clients:
oidc.id: <CLIENT_ID> (2)
oidc.secret: <CLIENT_SECRET> (2)
oidc.discoveryUri: <http://localhost:8180/realms/mgnl/.well-known/openid-configuration> (2)
oidc.authorizationGenerators: groupsAuthorization (2)
userFieldMappings:
name: email
fullName: name
email: email
language: locale
| 1 | Required field as a general setting or in oidc.callbackUrl. |
| 2 | Required field. |
Environment-specific configuration
To create environment-specific configuration files:
-
Add the
magnolia.sso.configproperty to themagnolia.propertiesfile. -
Set different paths for the
config.yamlfile for your environments:-
Default:
WEB-INF/config/default/magnolia.properties -
Author environment:
WEB-INF/config/magnoliaAuthor/magnolia.properties -
Public environment:
WEB-INF/config/magnoliaPublic/magnolia.properties
-
-
The system looks for the file in the resources directory, typically
magnolia.resources.dir.Example of different default and author environment configuration file paths# Example config in WEB-INF/config/default/magnolia.properties magnolia.sso.config=/default/config.yaml # Example config in WEB-INF/config/magnoliaAuthor/magnolia.properties magnolia.sso.config=/ssoAuthor/config.yaml
The config.yaml file is loaded as a resource file.
However, the path is configurable.
You must not place the SSO module config.yaml file under WEB-INF/config/default or WEB-INF/config/magnoliaAuthor because these folders are not watched by the Magnolia resource mechanism and an exception is thrown on startup if the YAML file is present there.
|
If the magnolia.sso.config property is not added, the module uses the /magnolia-sso/config.yaml path by default.
Configuring a fallback login
SSO 4.0 and later supports the use of both SSO and Magnolia JCR-based login mechanisms at the same time. The JCR login acts as a secondary authentication method, for example, to safeguard your access to the Magnolia instance if your IdP is not available.
When you configure JAAS to have both JCR- and SSO-based authentication entries as described below, users can log in using the default Magnolia login when they navigate to /.magnolia/jcrlogin, for example http://localhost:8080/magnoliaAuthor/.magnolia/jcrlogin.
When they log out, users also fall back to the default login screen corresponding to their authentication method.
Configuring the URL
You can configure the default URL by updating the patternString property and the postLogoutRedirectUrl property to match.
If the two properties don’t match, the login/logout doesn’t fall back to the URL.
-
Set your login URL using the
patternStringproperty underserver/filters/securityCallback/clientCallbacks/ssoFallback/originalUrlPattern.📁 server
📁 filters
📁 securityCallback
⸬ clientCallbacks
⸬ ssoFallback
⬩ class
info.magnolia.cms.security.auth.callback.FormClientCallback
⬩ loginForm
/defaultMagnoliaLoginForm/login.html
⸬ originalUrlPattern
⬩ class
info.magnolia.cms.util.SimpleUrlPattern
⬩ patternString
/.magnolia/jcrlogin⬩ enabled
true
⸬ ssoLocationFragmentRedirect
⸬ sso
If ssoFallbackdoesn’t exist on your instance, ensure that you add it as the first node underclientCallbacks, including subnodes for itsclassandloginForm. For the fallback to work, you must place it before thessocontent node, as shown above. -
Update the
postLogoutRedirectUrlproperty with the same URL underserver/filters/login/loginHandlers/Form@postLogoutRedirectUrl. This means users are also logged out back to the correct login URL.📁 server
📁 filters
📁 login
⸬ loginHandlers
⸬ Form
⸬ allowedMethods
⬩ class
info.magnolia.cms.security.auth.login.FormLogin
⬩ defaultLoginRedirectUrl
/.magnolia/admincentral⬩ postLogoutRedirectUrl
/.magnolia/jcrlogin⬩ class
info.magnolia.cms.security.auth.login.LoginFilter
Preserving Admincentral URLs upon login
Fragments in a URL are preserved if there’s no domain redirect during login.
This is because fragments are handled in the browser and are never sent to the server.
However, when domain changes occur, a redirect happens and fragments aren’t sent to the server by default.
By enabling magnolia.admincentral.sso.remember-location, the original request URL including the location fragment is first stored in the browser before the login flow starts, and is restored afterwards upon successful login.
This way, users reach the page they want.
magnolia.admincentral.sso.remember-location=true
Configuring JAAS
Ensure the JAAS security setup configuration is in the WEB-INF/config/jaas.config file.
The configuration should appear as follows for SSO installations when using both SSO and the optional fallback JCR-based authentication:
magnolia { (1)
info.magnolia.jaas.sp.jcr.JCRAuthenticationModule requisite;
info.magnolia.jaas.sp.jcr.JCRAuthorizationModule required;
};
sso-authentication { (2)
info.magnolia.sso.jaas.SsoAuthenticationModule requisite;
info.magnolia.jaas.sp.jcr.JCRAuthorizationModule required;
};
| 1 | Optional fallback default JCR-based login authentication and authorization |
| 2 | SSO login authentication and authorization |
If you don’t want to use the fallback default JCR-based login, you can disable it.
SSO module compatibility
| Module version | Third-party APIs tested against | Released with | ||
|---|---|---|---|---|
|
Keycloak
|
Magnolia CMS |
||
|
Keycloak
|
Magnolia CMS |
||
|
Keycloak
|
Magnolia CMS |
||
|
Keycloak
|
Magnolia CMS |
||
|
Azure Active Directory
|
|||
|
Google Cloud Identity |
|||
|
Keycloak 9.0.3 |
|||
|
Okta 2021.03.3+ |


