OIDC scopes
IAM appliance’s CAS supports two ways of working with scopes: custom scopes and scope-less claims.
Custom scopes
This is a more traditional way of specifying returned data. It is closely tied to the official OIDC protocol specification and is vital in scenarios where explicit user consent is needed, because scope defines an attribute set the user consents to be transferred to the SP.
It is more heavyweight and (re)configuring it also means restarting the CAS.
Scope-less claims
Scope-less claims do not need any configuration in CAS property file and are also defined on per-service level. They also allow for dynamic user profile attribute resolution and better value handling.
It is very handy in (but not limited to) scenarios where you do not have an user store but you still need to supply some predefined set of attributes in the userinfo response, i.e. when using Client Credentials grant.
However, scope-less claims rely on the SP to specify only the openid
as requested scope. Therefore an user cannot consent to specific data set to be given to the SP. Also if the SP uses some programming library that enables only explicitly-specified scopes to pass, this configuration becomes unusable.
Configuring custom OIDC scope
Prepare CAS server property snippet with custom scope definition 001-oidc.properties
and place it into /data/volumes/cas/cas.properties.d/
. We used name cust
for our custom scope but you can name if however you want.
001-oidc.properties
file.# IF NEEDED, configure CAS to read additional attributes from the appliance LDAP -> list them in the docker-compose-cas.yml file, not here # IF NEEDED, list all scopes you want to use with OIDC cas.authn.oidc.discovery.scopes=openid,profile,email,address,phone,offline_access,cust # define custom scope 'cust' and list all claims that belong to it cas.authn.oidc.core.user-defined-scopes.cust=name,family_name,email,some_custom_claim # IF NEEDED, define custom claims cas.authn.oidc.discovery.claims=sub,name,preferred_username,family_name,given_name,middle_name,given_name,profile,picture,nickname,website,zoneinfo,locale,updated_at,birthdate,email,email_verified,phone_number,phone_number_verified,address,some_custom_claim # define claim to attribute mapping # syntax: # cas.authn.oidc.core.claims-map.$claim=$attributeFromCas cas.authn.oidc.core.claims-map.name=displayName cas.authn.oidc.core.claims-map.given_name=givenName cas.authn.oidc.core.claims-map.email=mail cas.authn.oidc.core.claims-map.family_name=sn cas.authn.oidc.core.claims-map.phone_number=telephoneNumber
When you are done, restart the CAS.
systemctl restart iam-cas
Configuring scope-less claims
This configuration is done per-service. We assume you have already mapped all necessary attributes through the docker-compose-cas.yml
configuration.
For the scope-less claims to work, the service:
-
Must allow (and use) only the
openid
scope. -
Must explicitly define an attribute release policy.
-
We recommend using
Return Mapped
or similar policy and not to use "all-in" policies likeReturn All
. TheReturn Mapped
policy allows you to specify, rename, remap and generate the attributes, so we deem it the most versatile. Play around a bit with the settings until you find the policy that suits you the best.
-
{ "@class" : "org.apereo.cas.services.OidcRegisteredService", "clientId": "rlc-oidc-test", "clientSecret": "rlc-test", "serviceId" : "^https://your.application.url", "name": "OIDC-RLC", "id": 201, "subjectType": "pairwise", "scopes" : [ "java.util.HashSet", [ "openid" ]], "supportedGrantTypes": [ "java.util.HashSet", [ "AUTHORIZATION_CODE", "REFRESH_TOKEN" ] ], "supportedResponseTypes": [ "java.util.HashSet", [ "CODE", "TOKEN" ] ], "bypassApprovalPrompt": true, "attributeReleasePolicy" : { "@class" : "org.apereo.cas.services.ReturnMappedAttributeReleasePolicy", "allowedAttributes" : { "@class" : "java.util.TreeMap", "attributeInCasThatWeWantToRenameForOIDC" : "attribute_in_oidc", "another_attribute" : "another_attribute", "generated_static_attribute_in_oidc" : "groovy { return ['somevalue'] }" } } }