# OpenID Connect not parsing multi-value (array/list) user attributes

**URL:** <https://discuss.elastic.co/t/openid-connect-not-parsing-multi-value-array-list-user-attributes/212025>\
**Category:** Elasticsearch\
**Tags:** elastic-stack-security\
**Created:** [December 16, 2019, 3:04pm UTC](https://discuss.elastic.co/t/openid-connect-not-parsing-multi-value-array-list-user-attributes/212025 "2019-12-16T15:04:23Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Chris\_Samo](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/chris_samo/32/46830_2.png) [@Chris\_Samo](https://discuss.elastic.co/u/Chris_Samo)\
**Post date:** [December 16, 2019, 3:04pm UTC](https://discuss.elastic.co/t/openid-connect-not-parsing-multi-value-array-list-user-attributes/212025/1 "2019-12-16T15:04:23Z")

</div>

We've setup Elasticsearch (7.5.0) to provide authentication and authorisation using OpenID Connect (a Keycloak setup in this case). Within the OIDC provider, we've mapped a custom User Attribute to be present as a field in the UserInfo response (also tried adding the same to the Access and ID Tokens, but the same problem persists).

This all works fine in Elasticsearch for AuthN and Role/Group based AuthZ (using a role mapping in ES to assign Roles to authentications users from the realm). It also works when passing a single value (i.e. a String) via the attribute, but when setting the OIDC Mapper to pass a multi-value (i.e. Array/List) of values back, Elasticsearch seems to simply ignore the field and it doesn't appear in the authenticated User's metadata.

I think this is a problem with the [OpenIdConnectRealm](https://github.com/elastic/elasticsearch/blob/master/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/oidc/OpenIdConnectRealm.java#L218) parsing of attributes from the Claims/UserInfo - it checks the `instanceof` types of the claim Values is one of:

- String
- Boolean
- Number
- Collections  
But this last check seems invalid, presumably it should be [Collection](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Collection.html) (i.e. to handle List, Set, Map objects) and not [Collections](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Collections.html) (i.e. a class of static helper methods for dealing with Collection Objects... which isn't likely to ever be found in the serialised ID/Access Token or UserInfo objects from a OP).

To hopefully help a little with further diagnostics/discussion:

- Example (sanitised) Access Token from OpenID Connect Provider when mapping `department` User Attribute as single-value field:

```json
{
  "jti": "...",
  "exp": 1576508489,
  "nbf": 0,
  "iat": 1576508189,
  "iss": "...",
  "aud": [
    "realm-management",
    "account"
  ],
  "sub": "...",
  "typ": "Bearer",
  "azp": "elastic",
  "auth_time": 0,
  "session_state": "...",
  "acr": "1",
  "realm_access": {
    "roles": [
      ...
    ]
  },
  "resource_access": {
    "realm-management": {
      "roles": [
       ...
      ]
    },
    "account": {
      "roles": [
        "manage-account",
        "manage-account-links",
        "view-profile"
      ]
    }
  },
  "scope": "openid profile email",
  "email_verified": false,
  "department": "accounts",
  "name": "Chris S",
  "groups": [
    ...
  ],
  "preferred_username": "chris.s@...",
  "given_name": "Chris",
  "family_name": "S",
  "email": "chris.s@..."
}

```

- Logging in to Kibana via OIDC and calling `GET /_security/_authenticate` from the Dev Tools console, I see (sanitised):

```json
{
  "username" : "...",
  "roles" : [
    "department_abac_test",
    "superuser"
  ],
  "full_name" : "chris.s",
  "email" : "chris.s@...",
  "metadata" : {
    "oidc(iss)" : "...",
    "oidc(email)" : "chris.s@...",
    "oidc(auth_time)" : 1576504468,
    "oidc(email_verified)" : false,
    "oidc(sub)" : "...",
    "oidc(azp)" : "elastic",
    "oidc(department)" : "accounts",
    "oidc(name)" : "Chris S",
    "oidc(family_name)" : "S",
    "oidc(acr)" : "1",
    "oidc(id_token_hint)" : "...",
    "oidc(jti)" : "...",
    "oidc(given_name)" : "Chris",
    "oidc(session_state)" : "...",
    "oidc(s_hash)" : "...",
    "oidc(at_hash)" : ...,
    "oidc(typ)" : "ID",
    "oidc(preferred_username)" : "chris.s@...",
    "oidc(nonce)" : "..."
  },
  "enabled" : true,
  "authentication_realm" : {
    "name" : "oidc1",
    "type" : "oidc"
  },
  "lookup_realm" : {
    "name" : "oidc1",
    "type" : "oidc"
  }
}

```

- Example (sanitised) showing the same when `department` is set to multi-value field:

```json
  ...
  "department": [
    "accounts",
    "it"
  ],
  ...

```

- With multi-value mapper setting enabled, the `_authenticate` response does not contain an entry for `oidc(department)` at all and I can't apply a role mapping to assign my test role based upon the user attribute

---

<div class="post-metadata">

**Author:** ![TimV](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/timv/32/13162_2.png) [@TimV](https://discuss.elastic.co/u/TimV)\
**Post date:** [December 16, 2019, 8:55pm UTC](https://discuss.elastic.co/t/openid-connect-not-parsing-multi-value-array-list-user-attributes/212025/2 "2019-12-16T20:55:27Z")

</div>

Yes, that `Collections` check is definitely a bug and it looks like it's the cause of the problem you're facing.

I've opened [an issue](https://github.com/elastic/elasticsearch/issues/50250) for this.  
I can't think of any sort of useful workaround for you though.

---

<div class="post-metadata">

**Author:** ![Chris\_Samo](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/chris_samo/32/46830_2.png) [@Chris\_Samo](https://discuss.elastic.co/u/Chris_Samo)\
**Post date:** [December 16, 2019, 9:14pm UTC](https://discuss.elastic.co/t/openid-connect-not-parsing-multi-value-array-list-user-attributes/212025/3 "2019-12-16T21:14:30Z")

</div>

Thanks for confirming, will watch issue for updates

Only possible workaround I've been considering is to use a delimited single value field, e.g. `accounts,it` then regex for mappings on the ES side (but I've not tried this yet and it's not ideal)

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [January 13, 2020, 9:14pm UTC](https://discuss.elastic.co/t/openid-connect-not-parsing-multi-value-array-list-user-attributes/212025/4 "2020-01-13T21:14:35Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
