Write an Okta Groups Claim Expression to Match Against Two Differently Named Groups
Last Updated:
Overview
An Okta Expression Language statement filters a groups claim to include a list of the user's groups where the group names match one of two different patterns. This configuration allows the resulting claim to contain only the specific groups required by the application.
Applies To
- Okta Identity Engine (OIE)
- Okta Classic Engine
- OpenID Connect (OIDC)
- OAuth 2.0
- Okta Expression Language
Solution
How to write an expression that will return user group membership details?
Groups.startsWith / Groups.contains / Groups.endsWith
The following group expression can be used to retrieve a list of groups the User is a member of, where the group starts with "A_SUBSTRING" or "APP_B". This expression must be written in this conditional-based format so that it can gracefully handle the case where the user is not a member of a group matching one (or both) of the Groups.startsWith expressions.
Arrays.isEmpty(Arrays.toCsvString(Groups.startsWith("active_directory","A_SUBSTRING",100))) ?
Arrays.isEmpty(Arrays.toCsvString(Groups.startsWith("active_directory","APP_B",100))) ? {} : Groups.startsWith("active_directory","APP_B",100) :
Arrays.isEmpty(Arrays.toCsvString(Groups.startsWith("active_directory","APP_B",100))) ? Groups.startsWith("active_directory","A_SUBSTRING",100) :
Arrays.flatten(Groups.startsWith("active_directory","APP_B",100),Groups.startsWith("active_directory","A_SUBSTRING",100))
Note on Groups.* functions
This example is written to match against groups from Active Directory, but the first argument to the startsWith function can be changed to match local Okta groups (replace active_directory with OKTA) or Groups from another application source (such as Google, Workday, etc.). Use of the function Groups.startsWith can be changed to Groups.endsWith or Groups.contains, depending on where the provided pattern will appear in the target groups' names.
Also, keep in mind that claims that evaluate to null values will not be included in tokens, so if this evaluates to `{}` because the user is not a member of a group that matches either substring, the claim will be absent from the token. Keep this in mind if the integration relies on getting this claim back for every user.
user.getGroups
The newer getGroups function provides a simpler way to write such an expression. More information in Get groups for users | Okta Expression Language overview, which covers configuration of Legacy Groups claims and Custom Claims, and Group functions | Okta Expression Language in Identity Engine, which covers configuration of Federated Token Claims.
Org Authorization Server
If creating a groups claim that will return the list of matching groups by name, where the group either starts with "A_SUBSTRING" or "APP_B", at the application level as a Token Claim (allowing the claim to appear in only the ID token when using the Org Authorization Server), as described in the Configure custom claims for app integrations documentation, the collection projection must be .![profile.name].
Example:
user.getGroups({'group.profile.name': {'A_SUBSTRING', 'APP_B'}}).![profile.name]
Custom Authorization Server
If creating a groups claim that will return the list of matching groups by name, where the group either starts with "A_SUBSTRING" or "APP_B", at the Authorization Server level instead (allowing the claim to appear in either the ID or Access Token when using this Custom Authorization Server), as described in the Customize tokens returned from Okta with custom claims documentation, the collection projection must be .![name].
Example:
user.getGroups({'group.profile.name': {'A_SUBSTRING', 'APP_B'}}).![name]
Related Resources
- Okta Expression Language - Group functions | Okta Developer
- Okta Expression Language - Get groups for users | Okta Developer
- Add Group Claims Using the getGroups Function in a Custom Authorization Server | Okta Support Center
- How to Use getGroups to Create a Groups Claim Using the Federated Claims Feature | Okta Support Center
