[cas-user] CAS v6.4 problem with OIDC claim name mappings in the ID Token

45 views
Skip to first unread message

John Wagenleitner

unread,
Jan 10, 2022, 11:28:00 PM1/10/22
to CAS Community
In CAS v6.3 (up to and including v6.3.7.4) we used the `cas.authn.oidc.claims-map` properties to map our LDAP attribute names to the standard claim names. This mapping worked for both the ID Token and the UserInfo (`/profile`) endpoint.

Here are the relevant properties we have set:

```
cas.authn.oidc.discovery.scopes=openid,profile,email
cas.authn.oidc.discovery.claims=sub,name,family_name,given_name,email
cas.authn.oidc.core.claims-map.email=mail
cas.authn.oidc.core.claims-map.name=cn
cas.authn.oidc.core.claims-map.family_name=sn
cas.authn.oidc.core.claims-map.given_name=givenName
```

This mapping is no longer working in CAS v6.4 (and also tested in the latest v6.4.4.2) for the generated ID Token. Our ID Token claims no longer contain the mapped names but instead contain the LDAP attribute names such as `mail`, `cn`, etc. The UserInfo endpoint does correctly contain the mapped claim names.

As a possible workaround, I tried using a service definition that included an `attributeReleasePolicy` using the `ReturnMappedAttributeReleasePolicy` class but that had no affect on the ID Token claim names.

I have reviewed all the OIDC settings and didn't spot anything that looks like it would address this issue.

Any help/advice would be appreciated,
John

--
- Website: https://apereo.github.io/cas
- Gitter Chatroom: https://gitter.im/apereo/cas
- List Guidelines: https://goo.gl/1VRrw7
- Contributions: https://goo.gl/mh7qDG
---
You received this message because you are subscribed to the Google Groups "CAS Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cas-user+u...@apereo.org.
To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/fdf662f8-e990-4b9a-b22a-57a6c643e0b1n%40apereo.org.

Frédéric Lohier

unread,
Jan 11, 2022, 3:57:13 AM1/11/22
to CAS Community
Hello,

Have you tried to set cas.authn.oidc.core.include-id-token-claims=true ?

According to OIDC spec, if you are using response-type=code , the id_token should not contain the user claims. But, if you are using response_type=id_token, then the id_token should include the user claims.
According to CAS 6.4 doc, if you set cas.authn.oidc.core.include-id-token-claims=true , it will force the release of user claims in the id_token.
However, in my tests with CAS 6.4.4.2, even with response_type=id_token, user claims are not included in the id_token (tried to GET an URL like https://mycasserver.com/cas/oidc/oidcAuthorize?response_type=id_token&client_id=myclient&scope=openid%20profile%20email&redirect_uri=https://serviceredirecturi). Not a blocker for me for the moment, but if you find a fix, I'm interested.

  • cas.authn.oidc.core.include-id-token-claims=true

As per OpenID Connect Core section 5.4, "The Claims requested by the profileemailaddress, and phone scope values are returned from the userinfo endpoint", except for response_type=id_token, where they are returned in the id_token (as there is no access token issued that could be used to access the userinfo endpoint). The Claims requested by the profile, email, address, and phone scope values are returned from the userinfo endpoint when a response_type value is used that results in an access token being issued. However, when no access token is issued (which is the case for the response_type value id_token), the resulting Claims are returned in the ID Token.

Setting this flag to true will force CAS to include claims in the ID token regardless of the response type. Note that this setting MUST ONLY be used as a last resort, to stay compliant with the specification as much as possible. DO NOT use this setting without due consideration.

Note that this setting is set to true by default mainly provided to preserve backward compatibility with previous CAS versions that included claims into the ID token without considering the response type. The behavior of this setting may change and it may be removed in future CAS releases.

To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/CALRGK0qskgHk3fpbRKEqJ1CHZNYHByEJQjFj9%2BSyk%2BBMOr2V8g%40mail.gmail.com.

John Wagenleitner

unread,
Jan 11, 2022, 2:01:45 PM1/11/22
to cas-...@apereo.org
Hi Frédéric,

Thanks for the reply. In our case the claims are being included in the ID Token, they just don't have the names we mapped and instead have the names as they come from our attribute store. We are using `respone_type=code` and a `scope=openid`.

I had not tried `cas.authn.oidc.core.include-id-token-claims=true` since the docs mentioned that is the default setting. I just tested again with it set to `true` and there is no change, the claims appear in the ID Token but not with the desired names. I also tried with it set to `false` and in that case the claims did not appear in the ID Token.

John

You received this message because you are subscribed to a topic in the Google Groups "CAS Community" group.
To unsubscribe from this topic, visit https://groups.google.com/a/apereo.org/d/topic/cas-user/gqYDgnT2T5o/unsubscribe.
To unsubscribe from this group and all its topics, send an email to cas-user+u...@apereo.org.

--
- Website: https://apereo.github.io/cas
- Gitter Chatroom: https://gitter.im/apereo/cas
- List Guidelines: https://goo.gl/1VRrw7
- Contributions: https://goo.gl/mh7qDG
---
You received this message because you are subscribed to the Google Groups "CAS Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cas-user+u...@apereo.org.
To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/CAON9TV3_S0GygUt_ip4nxujf8r7M-b0_%2BLXbYsDVs7XcN_ocuw%40mail.gmail.com.

Rodolphe Prin

unread,
Jan 31, 2022, 3:22:51 AM1/31/22
to CAS Community, John Wagenleitner
Hi,
I noticed the same behavior.
Version : 6.4.4.2

`cas.authn.oidc.core.include-id-token-claims=true`  allows to get the claims in the token, but with the wrong name. 

Rodolphe
To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/051090c9-8870-4075-8416-3380752f9d86n%40apereo.org.

Stef

unread,
Mar 6, 2022, 2:22:33 AM3/6/22
to cas-...@apereo.org
Hi,

Do you know if this problem has been solved in 6.4.6 ?

Stéphane
To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/CAENLzaZSxDzKvXzD99ukkb1bKCSskyqm36znAVB5sJSKk1DJbw%40mail.gmail.com.

John Wagenleitner

unread,
Mar 6, 2022, 10:17:59 AM3/6/22
to cas-...@apereo.org
I haven't tried v6.4.6, but the same problem does still occur with v6.5.0.

--
- Website: https://apereo.github.io/cas
- Gitter Chatroom: https://gitter.im/apereo/cas
- List Guidelines: https://goo.gl/1VRrw7
- Contributions: https://goo.gl/mh7qDG
---
You received this message because you are subscribed to the Google Groups "CAS Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cas-user+u...@apereo.org.
To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/CAON9TV1vWxe3u3hu2bf_5VCxS-LR-Lcv%3Drc__8GkyPueK24CSQ%40mail.gmail.com.

Jae Liu

unread,
Mar 8, 2022, 9:40:13 PM3/8/22
to CAS Community, John Wagenleitner
I used CAS v6.4 it's ok for me.

I think there something wrong with your configuration. You defined the scopes (scopes=openid,profile,emai), CAS will use these as attributes release policy, the scopes email will only release attributes email and email_verified, profile will release name, given_name. family_name, so the attributes in your claims-map do not have value, so the IDToken does have value.

To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/4fcf2216-ed97-45ec-98ad-52b173b4abcdn%40apereo.org.

John Wagenleitner

unread,
Mar 9, 2022, 10:47:16 AM3/9/22
to Jae Liu, CAS Community
Hi Jae,

Thanks for the reply, are you able to share any of your config?

In my case both the IDToken and the userinfo endpoint contain claims such as `mail` and `cn`. But the `claims-map` only seems to work for the userinfo endpoint, which returns both claims `mail` and `email` and `cn` and `name`, though I would have not expected it to include both the original CAS attribute (from LDAP such as cn) and the mapped claim (such as email) and think in versions prior to v6.4 it returned only `email` as a claim name for that particular value.

so the attributes in your claims-map do not have value, so the IDToken does have value.

In my claim-map I'm mapping `cn` to `name`. The IDToken we receive does include `cn` as a claim. Based on my mapping settings, I would have expected the claim name to be `name` and not `cn` both in the IDToken and in the userinfo endpoint and this is how it worked prior to v6.4.

John
To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/CAON9TV2JXD8YxKVzwZbyRsehyxGM%3D1UjQwWvwdDuPi-YC-nLbQ%40mail.gmail.com.

Rodolphe Prin

unread,
Mar 10, 2022, 3:48:19 AM3/10/22
to CAS Community, John Wagenleitner, CAS Community
Hi,
this is what I did to deal with that problem :
in my case I was retrieving attributes from the authentication source (LDAP) with the following configuration
```
cas.authn.ldap[0].principal-attribute-list=displayName,givenName,mail,sn
cas.authn.ldap[0].additional-attributes=memberOf
```
and then trying to map these attributes to standard OIDC claim names
```
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.groups=memberOf
```
With this configuration I had wrong claim names in the token (for example givenName instead of name), as mentionned in this thread.

I changed my configuration to resolve attributes with the attribute repository method, wich allows mapping attributes directly from the attibute source.
It seems though that this is not the recommended way when the authentication source is the same as the attribute source, as mentionned here (https://apereo.github.io/cas/6.4.x/integration/Attribute-Resolution.html#person-directory)
So my new configuration is
```
# cas.authn.ldap[0].principal-attribute-list=
# cas.authn.ldap[0].additional-attributes=
cas.person-directory.active-attribute-repository-ids=ldapRepository
cas.authn.attribute-repository.ldap[0].order=0
cas.authn.attribute-repository.ldap[0].ldap-url=xxxxxxxxx
cas.authn.attribute-repository.ldap[0].base-dn=xxxxxxx
cas.authn.attribute-repository.ldap[0].search-filter=xxxxxxxxxx
cas.authn.attribute-repository.ldap[0].bind-dn=xxxxxxx
cas.authn.attribute-repository.ldap[0].bind-credential=xxxxxxxxx

cas.authn.attribute-repository.ldap[0].attributes.cn=name
cas.authn.attribute-repository.ldap[0].attributes.givenName=given_name
cas.authn.attribute-repository.ldap[0].attributes.mail=email
cas.authn.attribute-repository.ldap[0].attributes.sn=family_name
cas.authn.attribute-repository.ldap[0].attributes.memberOf=groups
```
This way the "CAS" attributes are directly matching standard OIDC claim names, so no need to define OIDC attributes mappings, and I bypass the "seems to be a" bug.

This impacts however every attributes release, not only OIDC services. So for every other services that needs releasing attributes I formely mapped, I was forced to map them at the service level so that they get their original "LDAP" name, for instance : ```
"attributeReleasePolicy": {
"@class": "org.apereo.cas.services.ReturnMappedAttributeReleasePolicy",
"allowedAttributes" : {
"@class" : "java.util.TreeMap",
/*in : out */
"email" : "mail",
"name": "displayname"
}
},
```
I do not know if this can apply to your case, but I hope it helps...

Rodolphe
To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/c3b61db7-0abf-4c65-9c1f-a5afdc2388ddn%40apereo.org.

John Wagenleitner

unread,
Mar 10, 2022, 6:22:32 PM3/10/22
to Rodolphe Prin, CAS Community
Hi Rodolphe,

Thank you for sharing the information, this is really helpful. This work-around may be something we look into implementing.

John
To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/CAON9TV1EscU_BV-U_Hq%3DTU9zNekc9XK4dsU%2B7Vfjhb2w-_jbog%40mail.gmail.com.

Jae Liu

unread,
Mar 15, 2022, 4:53:37 AM3/15/22
to CAS Community, John Wagenleitner, CAS Community, Jae Liu
Hi John,

I removed the claims-map in config and following are my attributeReleasePolicy

  attributeReleasePolicy:
  {
    @class: org.apereo.cas.services.ChainingAttributeReleasePolicy
    policies:
    [
      java.util.ArrayList
      [
        {
          @class: org.apereo.cas.services.ReturnAllowedAttributeReleasePolicy
          principalAttributesRepository:
          {
            @class: org.apereo.cas.authentication.principal.DefaultPrincipalAttributesRepository
            mergingStrategy: REPLACE
            ignoreResolvedAttributes: false
          }
          order: 0
          allowedAttributes:
          [
            java.util.ArrayList
            [
              mail
              displayName
                          sAMAccountName
                          userPrincipalName
            ]
          ]
        }
        {
          @class: org.apereo.cas.services.ReturnMappedAttributeReleasePolicy
          allowedAttributes:
          {
            @class: java.util.TreeMap
                        email: groovy { return attributes[ 'mail' ].get(0) }
                        email_verified: groovy { if(!attributes[ 'mail' ].isEmpty() && attributes[ 'mail' ].get(0).endsWith('@xxxx.com')){ return true } else { return false } }
                        name: groovy { return attributes[ 'displayName' ].get(0) }
                        nickname: groovy { return attributes[ 'sAMAccountName' ].get(0) }
                        preferred_username: groovy { return attributes[ 'userPrincipalName' ].get(0) }
          }
          principalAttributesRepository:
          {
            @class: org.apereo.cas.authentication.principal.DefaultPrincipalAttributesRepository
            mergingStrategy: REPLACE
            ignoreResolvedAttributes: false
          }
          order: 1
        }
      ]
    ]
    mergingPolicy: REPLACE
    order: 0
  }

also removed the scopes

  scopes:
  [
    java.util.HashSet
    []
  ]
To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/4881a01b-e747-4844-85e2-281344c42223n%40apereo.org.

John Wagenleitner

unread,
Mar 18, 2022, 2:19:51 PM3/18/22
to Jae Liu, CAS Community
Hi Jae,

Thank you very much for your email. That is a good work-around/fix for the issue. I removed the `scopes` key in the service definition file completely and in the `cas.properties` removed all of the `cas.authn.oidc.core.claims-map` entries.

I used the following attribute release policy in my service definition to do the mappings (had tried this before, but it doesn't work with the `scopes` set):

"""
"attributeReleasePolicy" : {
"@class": "org.apereo.cas.services.ReturnMappedAttributeReleasePolicy",
"allowedAttributes": {
"@class": "java.util.TreeMap",
    "mail": "email",
"cn": "name",
"sn": "family_name",
"givenName": "given_name"
}
}
"""

With those changes (using CAS v6.5.0), now the correct names (email, name, family_name, given_name) appear in both the IDToken and userinfo endpoint.

Thanks again,
John
To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/CAON9TV2cXu3htvTeu%3D%2BAh06j83b2KSNejjduNV_ZYJMLngUDtw%40mail.gmail.com.

Jae Liu

unread,
Mar 22, 2022, 3:20:18 AM3/22/22
to CAS Community, John Wagenleitner, CAS Community, Jae Liu
Hi John,

did you use the user profile endpoint?
are the user profile values in the endpoint response array not string

To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/2f969b31-9389-4d0e-8f0c-6a95572a30d3n%40apereo.org.

John Wagenleitner

unread,
Mar 22, 2022, 10:23:21 AM3/22/22
to Jae Liu, CAS Community
Hi Jae,

Yes, after the changes I checked both the IDToken and user profile endpoint. What I noticed is that the IDToken only contains the mapped name whereas the user profile endpoint contains both the original names and the mapped names, both with values. But in our case that is ok.

Here is what the response from our user profile endpoint response looks like, which is the same as when we had the `claims-map` entries:

```
{
"cn": "John Doe",
"email": "jd...@example.edu",
"family_name": "Doe",
"given_name": "John",
"mail": "jd...@example.edu",
"name": "John Doe",
"sub": "jdoe",
"service": "https://cas.example.edu/account/idplogin",
"auth_time": 1647958411,
"id": "jdoe",
"client_id": "local-o...@example.edu"
}
```

John
To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/CAON9TV1jg%2Bpq7uMtB%3DtuqW3KoeGsvyjeQdP79D1Degav%3DFQctA%40mail.gmail.com.
Reply all
Reply to author
Forward
0 new messages