Configuration
Contents
The application is configured via a file called com.enonic.app.entraidprovider.cfg, using the properties format.
Since the configuration is extensive, documentation has been broken down into several sections below. All available configuration options listed here.
General
Enonic uses ID providers to provide auth for various endpoints such as Admin/websites and APIs. This application is a based on OpenID Connect ID provider and supports most of its features. At the same time it is primarily focused on Microsoft Entra as the OIDC provider, and adds support fetching groups from Microsoft Graph API.
This application may back multiple ID providers, most properties are prefixed with a named ID Provider i.e. idprovider.[idprovidername].[configkey] = [value], where idprovidername is a unique name matching the ID provider in Enonic XP.
For ease of reading we omit the idprovider.<name>. prefix in most of the documentation below. See the examples for a complete setup. |
ID provider setup
The application can automatically initialize, one or more ID providers using the following configuration fields:
# ID provider setup
autoinit=(true|false) (1)
idprovider.<name>.displayName=(string, optional) (2)
idprovider.<name>.description=(string, optional) (3)
| 1 | When true, each id provider declared by <name> in this configuration file will automatically be created in Enonic XP |
| 2 | Optionally provide a "pretty" name for the ID provider |
| 3 | Optional description for the ID provider |
Client
The Client parameters are mandatory for the Authorization Code Flow, but not used for Auto Login.You can obtain these values from Microsoft Entra admin center when creating a client/application there.
# Client
clientId=(string) (1)
clientSecret=(space separated strings) (2)
method=(post|basic|jwt)(3)
usePkce=(true|false) (4)
| 1 | Client ID you obtain from your Microsoft Entra admin center. |
| 2 | Client Secret you obtain from Microsoft Entra admin center. A space-separated list of secrets used for rotation. The new secret can be added as a fallback to the old one. |
| 3 | Optionally specify the method for how client ID and client secret will be passed to the OIDC server. The values correspond to client_secret_basic, client_secret_post and private_key_jwt methods, respectively. |
| 4 | usePkce - If set to false, the app will not use PKCE for the Authorization Code Flow. |
You may disable Authorization Code Flow by omitting clientId in your configuration. |
Authorization server
These values can be obtained from your Microsoft Entra admin center when registering a new Client/application.
# Authorization server
oidcWellKnownEndpoint=(string) (1)
issuer=(string)
authorizationUrl=(string)
tokenUrl=(string)
userinfoUrl=(string) (2)
jwksUri=(string) (3)
| 1 | When oidcWellKnownEndpoint is set, the values for issuer, authorizationUrl, tokenUrl, userinfoUrl and jwksUri will automatically be fetched from the well-known endpoint - and you do not need to fill them in.
|
||
| 2 | userinfoUrl if provided, the app will use this URL to retrieve the user claims to create/update the User in Enonic. (When useUserinfo is set to false this value is not used) |
||
| 3 | jwksUri - JSON Web Key Set (JWKS) - The app will use this URL to retrieve the public keys used to verify the signature of the Bearer Token during Auto Login, and ID Token in the Auth Code Flow. For Autologin flow, this property must exist. |
Rules
Additional rules enforced on user creation
# Rules
rules.allowedTenants=(space separated strings) (1)
| 1 | If you use a multi-tenant configuration, specify space-separated tenant IDs. Use * if you want to allow any tenant even from unknown organizations. |
User mappings
This section describes how users are mapped from OIDC to Enonic.
For Authorization Code Flow, user data are synched with Enonic on every login. The user’s displayName and email will be updated from the same sources as for user creation. |
# User mappings
useUserinfo=(true|false) (1)
claimUsername=(string, optional, defaults to "oid") (2)
scopes=(space separated strings, defaults to "profile email") (3)
mappings.displayName=(string, required, defaults to @@{userinfo.preferred_username}) (4)
mappings.email=(string, required, defaults to @@{userinfo.email}) (5)
defaultGroups=(space separated group keys) (6)
| 1 | When useUserinfo is set to false the claims from userinfoUrl will be ignored, and you must specify your own claims below. |
| 2 | Set this if useUserinfo is false.claimUsername is important, as this represents the unique identifier that will keep the Enonic user and the OIDC user in sync. |
| 3 | Set this if useUserinfo is false. Defines which scopes to fetch from the OIDC server. |
| 4 | Template for the displayName uses the format @@{expression}, e.g. @@{userinfo.preferred_username}. |
| 5 | email mapping uses @@{expression} format, e.g. @@{userinfo.email}. |
| 6 | defaultGroups makes all users member of the specified Enonic groups. The group name must be in the format group:[idprovidername]:[groupname], e.g. group:myidprovider:authors. |
Additional endpoints
You may optionally specify additional Endpoints to fetch and store more user data in the Enonic user profile.
# Additional Endpoints
additionalEndpoints.0.name=(string, required) (1)
additionalEndpoints.0.url=(string, required)
| 1 | name must be a unique string that will be mapped to a scope within the Enonic user profile, where the values will be stored. |
| For multiple endpoints, simply add more lines, and iterate the array counter. |
Autologin
Autologin is a concept in Enonic XP, where every request (without an existing session) may automatically be logged in. This is for instance useful if you want to support authentication for an API, rather than a regular website.
This application supports automatically logging in users when the client passes a special header: Authorization: Bearer <token> - The token must be a valid JWT for your ID provider.
To enable Autologin, you need to specify the jwksUri in the ID Provider configuration or oidcWellKnownEndpoint that ID Provider uses to obtain the value for the jwksUri automatically. |
# Autologin
autoLogin.createUser=(true|false) (1)
autoLogin.createSession=(false|true) (2)
autoLogin.wsHeader=(false|true) (3)
autoLogin.allowedAudience=(space separated strings) (4)
| 1 | If you disable 'createUser', the user will be logged in, but not persisted as a user within Enonic. If true, a user will be created automatically if it doesn’t exist. |
| 2 | Optionally create a session in Enonic when the user is logged in. By default, the user will be logged in with REQUEST scope. |
| 3 | ID provider will look for a token in the Sec-WebSocket-Protocol header. |
| 4 | allowedAudience is a list of space-separated strings. If set, the app will only accept tokens with an audience that matches one of the values in this list. It is highly recommended to set this value to make sure the correct tokens are used for the auto login. |
endSession
OpenID Connect Front-Channel Logout is optional and might not be supported by your authentication server. You can check if the endpoint is available in the OpenID Configuration (.well-known/openid-configuration) under the field end_session_endpoint. There might also be another custom endpoint available that achieves the same purpose. The ID Provider Configuration schema tries to be dynamic enough to handle all cases.
# EndSession
endSession.url=(string, required) (1)
endSession.idTokenHintKey=(string) (2)
endSession.postLogoutRedirectUriKey=(string) (3)
endSession.additionalParameters.[0..N].key=(string)
endSession.additionalParameters.[0..N].value=(string)
| 1 | url: should contain the value of end_session_endpoint in Entra admin center. |
| 2 | idTokenHintKey should optionally set the id_token_hint for Entra admin center. |
| 3 | postLogoutRedirectUriKey optionally set the post_logout_redirect_uri in your Entra admin center. |
User Events
userEventPrefix=(string, optional, defaults to "app.name") (1)
userEventMode=(off|local|distributed, optional, defaults to "local") (2)
| 1 | userEventPrefix is used to customize the type of user events such as login, create, and modify. By default, the application name is used as the prefix. For instance, the login event will look like <userEventPrefix>.user.login. To listen for this event, use custom.<userEventPrefix>.user.login. |
| 2 | userEventMode allows you to disable user events or specify whether they should be distributed in the cluster or locally. |
Fetch groups from Microsoft Graph API
createAndUpdateGroupsOnLoginFromGraphApi= (true or false, optional, defaults to "false") (1)
pageSize= (number, optional) (2)
groupPrefix= (string, optional, defaults to "azure-ad-") (3)
# Configures the proxy settings for communication with the Microsoft Graph API
proxy.host= (string, required) (4)
proxy.port= (number between 0 and 65535, optional) (5)
proxy.user= (string, optional) (6)
proxy.password= (string, optional) (7)
# Group Filter. Allows you to filter which user groups are imported from Microsoft Graph API.
# To use this, you must define an array of rules. The array is zero-indexed (starts at 0).
groupFilter.[0..N].groupProperty= (string, required) (8)
groupFilter.[0..N].regexp= (string, required) (9)
groupFilter.[0..N].and= (true or false, optional) (10)
| 1 | Create and update groups via Graph API. Automatically create and update groups upon user login, based on data returned from the Graph API. To sync groups from the Graph API to Enonic XP, you must grant the Directory.Read.All and Directory.AccessAsUser.All API permissions. |
| 2 | The page size for responses from the Graph API. If the result set exceeds this limit, the Graph API returns an @odata.nextLink property along with the first page of results. |
| 3 | Allows you to specify a prefix for Enonic XP groups to which the user will be added. |
| 4 | The proxy server hostname. |
| 5 | The proxy server port number. |
| 6 | The username for proxy authentication. |
| 7 | The password for proxy authentication. |
| 8 | The name of the property on the Graph API group object to check against. This must be a valid property returned by the Graph API (e.g., properties found in the MemberOf response). List of properties (e.g., description, displayName, id, visibility). |
| 9 | The Regular Expression to apply to the groupProperty. |
| 10 | If set to true, this rule is combined with the previous filter in the array using an AND operator. |
Group filter example
idprovider.myidp.groupFilter.0.groupProperty=description
idprovider.myidp.groupFilter.0.regexp=\\\$XP\\\$
idprovider.myidp.groupFilter.0.and=false
idprovider.myidp.groupFilter.1.groupProperty=displayName
idprovider.myidp.groupFilter.1.regexp=^XP
idprovider.myidp.groupFilter.1.and=false
idprovider.myidp.groupFilter.2.groupProperty=id
idprovider.myidp.groupFilter.2.regexp=12345-12345-12345-12345
idprovider.myidp.groupFilter.2.and=false
idprovider.myidp.groupFilter.3.groupProperty=visibility
idprovider.myidp.groupFilter.3.regexp=Public
idprovider.myidp.groupFilter.3.and=true
All options
All available configuration options
# ID provider setup
autoinit=(true | false)
idprovider.<name>.displayName=(string)
idprovider.<name>.description=(string)
# Client
idprovider.<name>.clientId=(string)
idprovider.<name>.clientSecret=(string)
idprovider.<name>.method=(post|basic|jwt)
idprovider.<name>.usePkce=(true|false)
# Authorization server
idprovider.<name>.oidcWellKnownEndpoint=(string)
idprovider.<name>.issuer=(string)
idprovider.<name>.authorizationUrl=(string)
idprovider.<name>.tokenUrl=(string)
idprovider.<name>.userinfoUrl=(string)
idprovider.<name>.jwksUri=(string)
# Rules
idprovider.<name>.rules.allowedTenants=(space separated strings, or * for all)
# User mappings
idprovider.<name>.useUserinfo=(true|false)
idprovider.<name>.claimUsername=(string)
idprovider.<name>.scopes=(space separated strings, defaults to "profile email")
idprovider.<name>.mappings.displayName=(string, required, defaults to @@{userinfo.preferred_username})
idprovider.<name>.mappings.email=(string, required, defaults to @@{userinfo.email})
idprovider.<name>.defaultGroups=(space separated group keys)
# Additional Endpoints
idprovider.<name>.additionalEndpoints.0.name=(string, required)
idprovider.<name>.additionalEndpoints.0.url=(string, required)
# Autologin
idprovider.<name>.autoLogin.createUser=(true|false)
idprovider.<name>.autoLogin.createSession=(true|false)
idprovider.<name>.autoLogin.wsHeader=(false|true)
idprovider.<name>.autoLogin.allowedAudience=(space separated strings)
# User Events
idprovider.<name>.userEventPrefix=(string, defaults to the current application name)
idprovider.<name>.userEventMode=(off|local|distributed, defaults to 'local')
# EndSession
idprovider.<name>.endSession.url=(string, required)
idprovider.<name>.endSession.idTokenHintKey=(string)
idprovider.<name>.endSession.postLogoutRedirectUriKey=(string)
idprovider.<name>.endSession.additionalParameters.0.key=(string, required)
idprovider.<name>.endSession.additionalParameters.0.value=(string, required)
# Fetch groups from Microsoft Graph API
idprovider.<name>.createAndUpdateGroupsOnLoginFromGraphApi= (true or false, optional, defaults to "false")
idprovider.<name>.pageSize= (number, optional)
idprovider.<name>.groupPrefix= (string, optional, defaults to "azure-ad-")
idprovider.<name>.proxy.host= (string, required)
idprovider.<name>.proxy.port= (number between 0 and 65535, optional)
idprovider.<name>.proxy.user= (string, optional)
idprovider.<name>.proxy.password= (string, optional)
idprovider.<name>.groupFilter.[0..N].groupProperty= (string, required)
idprovider.<name>.groupFilter.[0..N].regexp= (string, required)
idprovider.<name>.groupFilter.[0..N].and= (true or false, optional)