Custom User Provisioning Logic with Groovy
AuthM supports custom Groovy scripts that allow dynamic determination of user attributes and group memberships during the authentication process. This provides fine-grained control over user provisioning and group assignment based on identity provider (IdP) data.
Purpose
Custom provisioning logic is especially useful when:
- The identity provider (IdP) returns user claims that need to be transformed or mapped.
- Users and groups should be auto-created or updated during login.
- You want to enforce specific rules or filters before finalizing authentication.
Configuration Requirements
To enable and use a custom Groovy provisioning script:
- Set the script path in the AuthM configuration file:
...
openid.configs[x].post-authentication-script=<script_name>.groovy
or
...
saml2.configs[x].post-authentication-script=<script_name>.groovy
- Place the script file under the directory specified by the property:
groovy-scripts-directory=<absolute_path_to_scripts_folder>
Script Environment
When your Groovy script executes, the following global variables are available:
Variable | Description |
---|---|
log | A logger instance for logging within the script. |
idpType | The IdP type of authentication: OpenId or Saml2 |
externalUsername | The external username retrieved from the IdP |
attributes | A map of all claims (attributes) returned from the IdP. |
user | A User object representing the existing user (if already present in the system). If the user does not exist yet, this will be null . |
Return Format
The script must return a Map
containing the following optional keys:
Key | Type | Description |
---|---|---|
User | Map | A map with the user data to be created or updated. |
Groups | List<String> | A list of groups that the user should be assigned to. |
Example:
groovy
return [
User: [
username: attributes.email,
email: attributes.email,
fullName: attributes.name
],
Groups: ['default-users', 'admins']
]
Auto-Provisioning & Group Mapping
- If the user does not exist (user == null), the User map will be used to create the user.
- If the user exists, the User map will be used to update the user.
- Any groups listed in the Groups list will be created (if needed) and assigned to the user.
INFO
- Group assignment is handled automatically.
- Returning null or an empty map will skip user and group provisioning but allow authentication to continue (if permitted).
WARNING
Be cautious with logic that depends on claim availability — always check for nulls.
Examples:
- Creating/updating a user after a successful authentication
groovy
// log.info("user attributes {{ attributes: ${attributes} }}")
//
// attributes: [
// primaryPhone:[+000 000 000 000],
// firstName:[John],
// lastName:[Doe],
// displayName:[john Doe],
// notOnOrAfter:2025-05-28T09:19:31.577Z,
// email:[email protected],
// notBefore:2025-05-28T09:09:31.577Z],
// roles: [admin]
// }}
def contact = attributes["primaryPhone"]?.get(0)
contact = contact != null ? contact.replaceAll(" ", "") : null
def user = [
name : attributes["displayName"][0],
email : attributes["email"],
contact : contact,
externalUsername: externalUsername
]
// Keep existing groups that are part of the CoB Platform
def finalGroups = user?.groups.findAll { it -> it == "System" } ?: []
// Add roles returned from IDP as user groups
attributes.roles.each {it -> finalGroups << "FUNC ${IT}" }
return [user: user, groups: finalGroups]