Claims must have a single object value 'id_token'

Id_token

Hi,
I want to use openId connect with google credentials. Curently, I am following this https://extensions.xwiki.org/xwiki/bin/view/Extension/OpenID%20Connect/OpenID%20Connect%20Authenticator/ which ask to edit xwiki.properties to configure openId connect but It has not information with Google. But this link https://developers.google.com/identity/protocols/oauth2/openid-connect#authenticationuriparameters provides information about google configuration.

The picture content contains the information about error.

I started hitting this after upgrading from 1.29.1 to 1.31.
(XWiki version 13.10.3)

I see that some mult-config options were added in 1.30 - Extension Page

However, I could not find any release notes which highlighted breaking changes or config updates that need to be made when upgrading.

I believe it’s this section of the config:

#-# The OpenID Connect client identifier used by the authenticator.
#-#
#-# The default is the automatically generated unique id of the XWiki instance.
# oidc.idtokenclaims=xwiki_instance_id

Where the value of oidc.idtokenclaims= is the key for the value that gets passed as id_token with the request to the Google endpoint.

I can see this in the browser request which seems to confirm that:

/o/oauth2/v2/auth?scope=openid+email&claims={"id_token":{"xwiki_instance_id":null}, [...]

I don’t know if this is a value that the plugin should transparently pick up, or if it’s something that I need to configure myself.

@tmortagne is my understanding correct? Is there anything obvious that I’ve missed?

If you are talking about the null value, there is nothing wrong with that AFAIK. The point here is just to tell the provided that we would like to receive the " xwiki_instance_id" value as part of the returned id token. It’s also nothing new AFAIK.

Interesting. When jumping between 1.29.1 and 1.31, something must change in the required config that I’m missing, however I see nothing highlighted as needing to be changed. Do you have any reccomendations?

Super basic config section
#-# The OpenId Connect base URL of the XWiki instance to use as provider.
#-# See following endpoints properties if the provider is not an XWiki instance.
#-# If not indicated, it will be asked to the user.
# oidc.xwikiprovider=https://xwikiorg-node1.xwikisas.com/xwiki/oidc

#-# The generic OpenId Connect endpoints to use to communicate with the provider.
#-# Not needed in case of XWiki based provider.
# oidc.endpoint.authorization=https://xwikiorg-node1.xwikisas.com/xwiki/oidc/authorization
# oidc.endpoint.token=https://xwikiorg-node1.xwikisas.com/xwiki/oidc/token
# oidc.endpoint.userinfo=https://xwikiorg-node1.xwikisas.com/xwiki/oidc/userinfo
# oidc.endpoint.logout=https://xwikiorg-node1.xwikisas.com/xwiki/oidc/logout

# Google endpoinds
oidc.endpoint.authorization=https://accounts.google.com/o/oauth2/v2/auth
oidc.endpoint.token=https://oauth2.googleapis.com/token
oidc.endpoint.userinfo=https://openidconnect.googleapis.com/v1/userinfo
oidc.endpoint.logout=https://oauth2.googleapis.com/revoke

#-# It's possible to add custom HTTP headers to the endpoint (generally only needed for bad or non-oidc providers)
#-# by adding the suffix ".headers" to the endpoint property key and listing the custom headers using key:value format.
#-# Note that it's not taken into account for the oidc.endpoint.authorization endpoint because it's used as a redirect.
#-# Here is an example to send "Accept: application/json" and "SomeOtherHeader: header" HTTP headers with the userinfo request.
# oidc.endpoint.userinfo.headers=Accept:application/json
# oidc.endpoint.userinfo.headers=SomeOtherHeader:header value

#-# The scopes to use when redirecting to the provider
#-# The standard OpenID Connection scopes are:
#-# * openid: Informs the authorisation server that the client is making an OpenID Connect request (REQUIRED).
#-# * profile: Requests that access to the end-user's default profile claims at the UserInfo endpoint be granted by the issued access token.
#-# * email: Requests that access to the email and email_verified claims at the UserInfo endpoint be granted by the issued access token.
#-# * address: Requests that access to address claim at the UserInfo endpoint be granted by the issued access token.
#-# * phone: Requests that access to the {phone_number and phone_number_verified claims at the UserInfo endpoint be granted by the issued access token.
#-# * offline_access: Requests that an OAuth 2.0 refresh token be issued that can be used to obtain an access token that grants access the end-user's UserInfo endpoint even when the user is not present (not logged in).
#-# 
#-# But depending on the provider more can be listed.
#-# 
#-# The default is:
oidc.scope=openid,email

#-# The method used to access the userinfo endpoint.
#-# 
#-# Supported values are:
#-# * GET: use GET HTTP method
#-# * POST: use POST HTTP method
#-# 
#-# The default is:
# oidc.endpoint.userinfo.method=GET

#-# The pattern to use to generate the XWiki user name.
#-# 
#-# The following variables are available:
#-# oidc.user.subject: the unique id of the user in the provider
#-# oidc.user.mail: the mail of the user
#-# oidc.user.familyName : the last name of the user
#-# oidc.user.givenName: the first name of the user
#-# oidc.user.preferredUsername: the recommended string to use as id for the user
#-# oidc.provider: the URL of the XWiki provider (only when a XWiki provider is used)
#-# oidc.provider.host: the host of the provider URL
#-# oidc.provider.path: the path of the provider URL
#-# oidc.provider.protocol: the protocol (usually https) of the provider URL
#-# oidc.provider.port: the port of the provider URL
#-# oidc.issuer: the issuer URI
#-# oidc.issuer.host: the host of the issuer URI
#-# oidc.issuer.path: the path of the issuer URI
#-# oidc.issuer.scheme: the scheme (usually https) of the issuer URI
#-# oidc.issuer.port: the port of the issuer URI
#-# 
#-# The entire userinfo JSON received from the provider is also available using prefix "oidc.user.".
#-# For example if the provider send the following JSON for the user info:
#-# {
#-#   "sub"                : "248289761001",
#-#   "name"               : "Jane Doe",
#-#   "given_name"         : "Jane",
#-#   "family_name"        : "Doe",
#-#   "preferred_username" : "j.doe",
#-#   "email"              : "janedoe@example.com",
#-#   "picture"            : "http://example.com/janedoe/me.jpg"
#-#   "customoject"        :
#-#   {
#-#     "customproperty"   :  "customvalue"
#-#   }
#-# }
#-# you can use the variable ${oidc.user.customoject.customproperty}.
#-#
#-# The following suffixes can be added:
#-# * "._lowerCase": the lower case version of the string
#-# * "._upperCase": the upper case version of the string 
#-# * "._clean": a version of the string stripped from ".", ":", ",", "@", "^" characters and "\s" (all forms of white spaces).
#-#             It can itself be suffixed with "._lowerCase" and "._uperCase".
#-#
#-# The variable syntax also have other features (fallback value, etc.) detailed on https://commons.apache.org/proper/commons-text/apidocs/org/apache/commons/text/StringSubstitutor.html.
#-# 
#-# The default is: 
# oidc.user.nameFormater=${oidc.issuer.host._clean}-${oidc.user.preferredUsername._clean}
#oidc.user.nameFormater=${oidc.user.preferredUsername._clean._lowerCase}-${oidc.user.mail._clean._lowerCase}

#-# The pattern to use to generate the unique identifier of the user in the OpenId Connect provider.
#-# It is used to avoid collisions with user have similar name.
#-# 
#-# The syntax is the same than the one described for oidc.user.nameFormater property.
#-# 
#-# The default is: 
# oidc.user.subjectFormater=${oidc.user.subject}

#-# It's possible to associate non standard properties coming from the OpenID Connect provider with the XWiki user.
#-# It's a map with the name of the XWiki user property and a format similar to the one defined in oidc.user.nameFormater for the OpenID Connect side.
#-# 
# oidc.user.mapping=myxproperty1=${oidc.user.subject}
# oidc.user.mapping=myxproperty2=myprefix-${oidc.user.subject}

#-# The OpenID Connect client identifier used by the authenticator.
#-#
#-# The default is the automatically generated unique id of the XWiki instance.
# oidc.idtokenclaims=xwiki_instance_id

#-# The name of the claim used to get the list of groups the user belong to.
#-# This claim also need to be listed in oidc.userinfoclaims which control if group membership synchronization is enabled or not.
#-# 
#-# It's also possible to use a custom property from the userinfo JSON.
#-# For example if the provider send the following JSON for the user info:
#-# {
#-#   "sub"                : "248289761001",
#-#   "name"               : "Jane Doe",
#-#   "given_name"         : "Jane",
#-#   "family_name"        : "Doe",
#-#   "preferred_username" : "j.doe",
#-#   "email"              : "janedoe@example.com",
#-#   "picture"            : "http://example.com/janedoe/me.jpg"
#-#   "customoject"        :
#-#   {
#-#     "customgroups"   :  ["group1", "group2"]
#-#   }
#-# }
#-# you can use:
# oidc.groups.claim=customoject.customgroups
#-# 
#-# The default is:
# oidc.groups.claim=xwiki_groups

#-# Receiving a groups list is enough to enable group synchronization but you might need to configure XWiki groups names different from the remote groups names.
#-# It's also required to indicate what's the field containing the list of groups (that's not an OpenID Connect standard) using oidc.groups.claim property.
#-# 
# oidc.groups.mapping=MyXWikiGroup=my-oidc-group
# oidc.groups.mapping=MyXWikiGroup2=my-oidc-group2
# oidc.groups.mapping=MyXWikiGroup2=my-oidc-group3

#-# The groups the user need to belong to be allowed to authenticate.
#-# Not taken into account if not set or empty.
#-# 
# oidc.groups.allowed=

#-# If the user belong to one of these groups it won't be allowed to authenticate
#-# Not taken into account if not set or empty.
#-# 
# oidc.groups.forbidden=

#-# If set, only group names with this prefix will be provisioned
#-# Not taken into account if not set or empty.
#-# 
# oidc.groups.prefix=

#-# If the identity provider returns group memberships as a single value attribute delimited with a char, for example:
#-# {
#-#   "sub"                : "248289761001",
#-#   "name"               : "Jane Doe",
#-#   "given_name"         : "Jane",
#-#   "family_name"        : "Doe",
#-#   "preferred_username" : "j.doe",
#-#   "email"              : "janedoe@example.com",
#-#   "picture"            : "http://example.com/janedoe/me.jpg",
#-#   "groups"             : "group1,group2"
#-# }
#-# you can set here the separator char to get the list of groups the user belong to. 
#-# If not set, group memberships are evaluated as a multi valued attribute.
#-# 
# oidc.groups.separator=

#-# The custom claims to request to the provider for the UserInfo
#-# 
#-# The available custom claims are:
#-# xwiki_groups (or whatever you indicated in oidc.groups.claim): the groups a user belong to in the provider (see "Group synchronization" section for more details)
#-# xwiki_user_<fieldname>: the suffix to use to request any field in the user profile document (generally when the provider is XWiki) 
#-# The default is:
# oidc.userinfoclaims=xwiki_user_accessibility,xwiki_user_company,xwiki_user_displayHiddenDocuments,xwiki_user_editor,xwiki_user_usertype

#-# The time after which the user information should be refreshed (in milliseconds)
#-# 
#-# The default is:
# oidc.userinforefreshrate=600000

#-# The client identifier used by the authentication.
#-# The default is the identifier of the XWiki instance.
oidc.clientid=[redacted]

#-# The client secret (optionally) registered on the provider.
#-# By default nothing is sent to the provider.
oidc.secret=[redacted]

#-# How to send the client id and secret.
#-# 
#-# Supported values are:
#-# * client_secret_basic: the id and the secret are sent using BASIC auth header
#-# * client_secret_post: the id and the secret are sent in the the request body 
#-# 
#-# The default is:
# oidc.endpoint.token.auth_method=client_secret_basic

#-# Configure the in-wiki OIDC configuration
#-# 
#-# Define the name of the default wiki OIDC configuration to be used for client authentication.
#-# If no configuration with such name is found, the authenticator will rely only on the configuration keys declared in
#-# this file.
#-#
#-# The default is:
#-# oidc.defaultClientConfiguration=default
#-#
#-# When using in-wiki OIDC configuration, it is possible to define multiple configurations that can be selected by
#-# the end user through a cookie indicating the name of the configuration to be used. You can control the name of
#-# this cookie with the following configuration.
#-#
#-# oidc.clientConfigurationCookie=oidcProvider

#-# Configure the logout mechanism
#-#
#-# The OIDC authenticator provides different logout strategies, that need to be selected based on the OpenID Provider
#-# used for authenticating the users. It is also possible to define extra logout mechanisms specifically for
#-# some OpenID Providers by implementing org.xwiki.contrib.oidc.auth.OIDCLogoutMechanism.
#-#
#-# The authenticator provides the following mechanisms by default :
#-# * rpInitiated : will redirect the user to the logout page of the OpenID provider.
#-#   Specifications : https://openid.net/specs/openid-connect-rpinitiated-1_0.html.
#-# * backChannel : XWiki will send a request for logout to the OpenID provider, without redirecting the user.
#-#   Specifications : https://openid.net/specs/openid-connect-backchannel-1_0.html.
#-#
#-# The default is:
#-# oidc.logoutMechanism=backChannel

#-# Disable the OpenId Connect authenticator
#-# 
#-# The default is:
# oidc.skipped=false

So it seems that the different is [OIDC-120] OIDCClientConfiguration#getClaimsRequest() won't return configured claims - XWiki.org JIRA : in 1.26 a regression was introduced which caused the request to not contain any custom claim and this was fixed in 1.30.

Now it looks like a mistake on Google side to refuse custom claims (according to the specification it’s supposed to simply ignore claims it does not know, Final: OpenID Connect Core 1.0 incorporating errata set 1), but I guess you could try to set an empty oidc.idtokenclaims and see how it goes.

I tried setting oidc.idtokenclaims= to empty but that doesn’t solve the problem. What it sent now is this:
{"id_token":{"":null},"userinfo":{"":null}}.

My apologies for resurrecting this thread, if I shouldn’t. But I’m wondering if this ever got solved or if anyone figured out a workaround etc? I’m having the same problem and I’m not sure what can be done to resolve it.

Any guidance would be helpful. I experience the same thing as @dzegarra mentioned. Setting oidc.idtokenclaims to ANY value will send the following:

{"id_token":{"ANY_VALUE":null},"userinfo" : [...]}

for instance, if you were to set oidc.idtokenclaims=a_test_value

{"id_token":{"a_test_value":null},"userinfo" : [...] }

Hi @kados if not already installed, you should try the recent new version 1.34 of the OpenID extension. We were experiencing the same problem but after installing that one, it worked.

These are our settings from the xwiki.properties (I omit clientid and secret):

oidc.endpoint.authorization=https://accounts.google.com/o/oauth2/v2/auth
...
oidc.groups.claim=
oidc.idtokenclaims=
oidc.endpoint.logout=https://oauth2.googleapis.com/revoke
oidc.scope=openid,profile,email
oidc.endpoint.token=https://oauth2.googleapis.com/token
oidc.userinfoclaims=
oidc.endpoint.userinfo=https://openidconnect.googleapis.com/v1/userinfo
oidc.user.mapping=
oidc.user.nameFormater=${oidc.user.email}
oidc.user.subjectFormater=${oidc.user.email}

See also: Page load performance / Page Cache relevant? (which starts around another topic - page cache - but later in the thread there’s a lot about the OIDC extension).

1 Like