Because “sub” not exists in JSON response in Graph userinfo:
https://graph.microsoft.com/v1.0/me
Below fields are in standard response:
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity",
"businessPhones": [
"+1 412 555 0109"
],
"displayName": "Megan Bowen",
"givenName": "Megan",
"jobTitle": "Auditor",
"mail": "MeganB@M365x214355.onmicrosoft.com",
"mobilePhone": null,
"officeLocation": "12/1110",
"preferredLanguage": "en-US",
"surname": "Bowen",
"userPrincipalName": "MeganB@M365x214355.onmicrosoft.com",
"id": "48d31887-5fad-4d73-a9f5-3c356e68a038"
}
And because “sub” is mandatory:
Caused by: com.nimbusds.oauth2.sdk.ParseException: Couldn't parse UserInfo claims: Missing or invalid "sub" claim
at com.nimbusds.openid.connect.sdk.UserInfoSuccessResponse.parse(UserInfoSuccessResponse.java:248)
at com.nimbusds.openid.connect.sdk.UserInfoResponse.parse(UserInfoResponse.java:73)
or if I set it to empty string:
Caused by: java.lang.IllegalArgumentException: The value must not be null or empty string
at com.nimbusds.oauth2.sdk.id.Identifier.<init>(Identifier.java:92)
at com.nimbusds.oauth2.sdk.id.Subject.<init>(Subject.java:39)
So there must be a value assigned to “sub”.
So I verify all my changes and I finally modify everything only in two files of
oauth-2.0-sdk-with-openid-connect-extensions
BTW (try to implement changes in lastest version of this ext but it is not compatibile with xwiki, so I use the same that is already on xwiki: v6.23)
I modified two files:
.
.
.
FIRST
\oauth-2.0-sdk-with-openid-connect-extensions\src\main\java\com\nimbusds\openid\connect\sdk\UserInfoSuccessResponse.java
line: 238
from:
if (ct.match(CommonContentTypes.APPLICATION_JSON)) {
UserInfo claimsSet;
try {
claimsSet = new UserInfo(httpResponse.getContentAsJSONObject());
} catch (Exception e) {
throw new ParseException("Couldn't parse UserInfo claims: " +
e.getMessage(), e);
}
response = new UserInfoSuccessResponse(claimsSet);
}
to:
if (ct.match(CommonContentTypes.APPLICATION_JSON)) {
UserInfo claimsSet;
try {
JSONObject j = httpResponse.getContentAsJSONObject();
if (!j.containsKey("sub") && j.containsKey("id")) {
j.put("sub", j.get("id").toString());
}
claimsSet = new UserInfo(j);
} catch (Exception e) {
throw new ParseException("Couldn't parse UserInfo claims: " +
e.getMessage(), e);
}
response = new UserInfoSuccessResponse(claimsSet);
}
I decided to assign “sub” from “id” because “id” is mostly uses in newer verson of openid userinfo (instead of “sub”).
.
.
.
SECOND
oauth-2.0-sdk-with-openid-connect-extensions\src\main\java\com\nimbusds\oauth2\sdk\http\HTTPRequest.java
line: 800
by adding new line:
conn.addRequestProperty("Accept", "application/json");
so it looks now:
conn.addRequestProperty("Accept", "application/json");
conn.setRequestMethod(method.name());
conn.setConnectTimeout(connectTimeout);
conn.setReadTimeout(readTimeout);
conn.setInstanceFollowRedirects(followRedirects);
I have tested header set like abowe and all each below methods worked:
oidc.endpoint.provider=https://login.microsoftonline.com/{tenant}/oauth2
oidc.endpoint.authorization=https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize
oidc.endpoint.token=https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token
oidc.endpoint.userinfo=https://graph.microsoft.com/v1.0/me
.
oidc.xwikiprovider=https://login.microsoftonline.com/{tenant}/oauth2
oidc.endpoint.authorization=https://login.microsoftonline.com/{tenant}/oauth2/authorize
oidc.endpoint.token=https://login.microsoftonline.com/{tenant}/oauth2/token
oidc.endpoint.userinfo=https://login.microsoftonline.com/{tenant}/openid/userinfo
.
oidc.xwikiprovider=https://login.microsoftonline.com/{tenant}/oauth2
oidc.endpoint.authorization=https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize
oidc.endpoint.token=https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token
oidc.endpoint.userinfo=https://graph.microsoft.com/oidc/userinfo