Inteligr8 Auth ACS Platform Module
This module extends the capabilities of OAuth within the Alfresco Content Services Platform.
It specifically provides the capability of using OAuth/JWT group/role claims to synchronize with ACS User Groups and possibly ACS Roles.
Installing
The installation is like any JAR-based module. Just place the library within the classpath.
Compatibility
| Module Version | ACS Version |
|---|---|
| v1.0.0 | 25.1.x |
| v1.1.0 | 25.2.x |
Later versions have unknown support. The latest may work with it, depending on package and class renames done by Hyland/Alfresco.
Terminology
- ACS User Group
- A group within the ACS repository. These persist and are attached to users and ACLs. These are the glue to give users permissions to data.
- ACS Role
- A role within the ACS repository. These do not persist and are only attached to a user. Like
ROLE_ADMINISTRATOR. - ACS Authority
- A user, user group, or role within the ACS repository. This encompasses all of it.
- OAuth Claim
- A claim or claim key is the claim key in a JSON Web Token (JWT). The identity provider makes claims; some of them may be
preferred_usernameorgroups. It is claiming this information about the user, which the application may accept if desired. - OAuth Group/Role
- A group, role, or claim value is the value associated with a claim key in a JSON Web Token (JWT). There is no differentiator between groups and roles in the identity provider space. A claim like
groupsorrealm_access.rolestypically hold a simple array of strings. Keycloak calls them roles internally. Other providers call them entitlements or groups.
Configuration
Assuming you configured the ACS Identity Service Authentication subsystem, nothing else is required. However, the results may not be what is desired.
The configuration factors in the possibility that you have multiple authorization servers. That is non-typical, but important to realize when you see how the configuration values are separated.
Global
The following properties apply to all authorization servers in the chain. This means they can only be set in the global context, which is done with Java startup user properties, the alfresco-global.properties, or a custom Alfresco Model Package (AMP) alfresco-global.properties. It cannot be in a subsystem's properties.
You can find the default configuration here.
| Property | Default | Details |
|---|---|---|
inteligr8.auth.sync.createMissingAuthorities |
true |
Whenever a claim value maps to an ACS authority, if the ACS authority doesn't exist, create it. It will be created in the configured zone(s). |
inteligr8.auth.handlers.microprofile-jwt.claim |
groups |
This pre-configures the standard microprofile-jwt client scope for use by this library. |
inteligr8.auth.handlers.keycloak-realm.claim |
realm_access.roles |
This pre-configures the Keycloak claim that may exist in the bearer token or user-info metadata. |
inteligr8.auth.handlers.keycloak-client.claim |
resource_access.*.roles |
This pre-configures the Keycloak claim that may exist in the bearer token or user-info metadata. |
You may defined your own handler with the same notation. If you do so, it also cannot be done in the subsystem, but must be done globally. The handler name is used in the subsystem specific inteligr8.auth.handlers property, where it is enabled. Simply defining a handler like above does not enable it.
Per Authorization Server
The following properties apply to individual authorization servers in the chain. This means they can be overridden anywhere: Java startup user properties, any alfresco-global.properties, or in that specific subsystem properties. The latter is recommended when reasonable and required if you have multiple authorization servers configured.
You can find the default configuration here.
| Property | Default | Details |
|---|---|---|
inteligr8.auth.primaryAuthorityZone |
AUTH.EXT.OAUTH |
All users authenticated and groups created or granted membership by this authorization server will be associated to this zone. This defines the limits for which group memberships are subject to synchronization for this authorization server. |
inteligr8.auth.otherAuthorityZones |
A comma-delimited list of ACS authority zones. All groups created by this authorization server will be associated to these zones. You could put APP.DEFAULT or others if desired. If one doesn't exist, it will be created. |
|
inteligr8.auth.bootstrap.authorities |
See source | This creates an set of groups, if they don't already exist, on startup. It also places them within other groups. By default, these are groups associated with Alfresco OOTB groups, kept separately for encapsulation purposes. |
inteligr8.auth.defaultMapper.includes |
.* |
A comma-delimited list of regular expressions. When there is no matching mapper, what claim values should be transformed anyway? By default this will match everything, as long as the claim value does't match the excludes patterns. |
inteligr8.auth.defaultMapper.excludes |
users,offline_access,service_account |
A comma-delimited list of regular expressions. When there is no matching mapper, what claim values should not be transformed, even if explicitly matched by includes? |
inteligr8.auth.defaultMapper.replacementId |
GROUP_OAUTH_$0 |
A regular expression replacement expression. $0 is replaced by the full claim value. The claim value is always uppercased and all special characters are replaced by underscores. |
inteligr8.auth.defaultMapper.replacementName |
$0 |
A regular expression replacement expression. $0 is replaced by the full claim value. |
inteligr8.auth.transformer.allowedCharacters |
A-Z0-9_ |
A regular expression pattern fragment of acceptable characters in the mapped ACS authority ID. All ACS authority IDs will be capitalized. You may include a - if desired. |
inteligr8.auth.mappers |
See source | This defines claim value to ACS authority mappings. All ACS User Groups must be prefixed by GROUP_ as you could use ACS Roles too (ROLE_). |
In addition to these, you could define the same defaultMapper and mappers properties in each handler. For instance: inteligr8.auth.handlers.microprofile-jwt.defaultMapper.replacementId=GROUP_JWT_$0 or inteligr8.auth.handlers.keycloak-realm.mappers=.... These are considered before the global specifications, not replaced by them.