Issues with OpenID / Office365

version 4.12 (2015-03-14)
* HTTPRequest adds support for arbitrary headers.
* HTTPResponse adds support for arbitrary headers.

.
.

So can you create a custom jar or any other file with this small change (one line) for me that i can use in xwiki? I will ulopad it somewhere in wiki :slight_smile: Don’t know where yet. I installed it from Manager. I can Pay you for that, because I don’t know Java :frowning:

I asked my IT friends but they had a problem after import ext. from github and couldn’t compile :frowning:

Almost. I get an error now:

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:243)
	at com.nimbusds.openid.connect.sdk.UserInfoResponse.parse(UserInfoResponse.java:73)

I see there is a need to edit also oauth-2.0-sdk-with-openid-connect-extensions. Lot lot of changes :frowning:

There are more fields that not appear in JSON :frowning:
Maybe it is a good idea to create oauth-2.0 for MS Graph 1.0?

I don’t know how can I contact owner of this extension. Any ideas?

OK works like a charm :slight_smile:
(Sorry for my bad code but I don’t know JAVA)

To make it works with endpoint userinfo:
oidc.endpoint.userinfo=https://graph.microsoft.com/v1.0/me

we need 2 changes:

FIRST:
in file:

oidc-authenticator\src\main\java\org\xwiki\contrib\oidc\auth\internal\OIDCUserManager.java

line
line 177

userinfoHTTP.setHeader("User-Agent", this.getClass().getPackage().getImplementationTitle() + '/'
     + this.getClass().getPackage().getImplementationVersion());
// added line below
userinfoHTTP.setHeader("Accept", "application/json");

SECOND:
in below file (for sure version 2.63 - the newest version is not compatible with XWiki):

oauth-2.0-sdk-with-openid-connect-extensions\src\main\java\com\nimbusds\openid\connect\sdk\UserInfoSuccessResponse.java

import
import net.minidev.json.JSONObject;

line: 238
from:

try {
    claimsSet = new UserInfo(httpResponse.getContentAsJSONObject());			
} catch (Exception e) {

to:

try {
    JSONObject j = httpResponse.getContentAsJSONObject();
    j.put("sub", "abcdefgh");
    claimsSet = new UserInfo(j);
} catch (Exception e) {

Any idea idea why this is needed ? It does not seems to be doing anything else than adding a “sub” property to the received JSON.

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

It really seems you are trying hard to make an endpoint which have nothing to do with OpenID connect protocol fit in the standard code which does not make much sense.

A probably much better direction would be to use the extension mechanism provided by the authenticator (see https://extensions.xwiki.org/xwiki/bin/view/Extension/OpenID%20Connect/OpenID%20Connect%20Authenticator/#HListeners) and write a special component which request https://graph.microsoft.com/v1.0/me and update the user accordingly.

but was much more simpler to modify two files and everything works perfect :slight_smile:

Besides I know from official site that MS is working on adding “sub” to /me because many people requesting it. That will solve one problem with
oauth-2.0-sdk-with-openid-connect-extensions. So it will be only one problem with header Accept. Will be great if you could although add possibility to set header in xwiki.properties file. Can I count on you in that? :slight_smile:
Then all problems will be solved :slight_smile:

@tmortagne added a header modification functionality in the update 1.22. Thank you for that! :smiling_face_with_three_hearts:
@Rozpalacz123 So now we need to push microsoft to implement custom properties or the sub claim quickly! :grin:

Please everyone coming here, wanting microsoft to add the sub claim to Microsoft Graph /me endpoint please vote on this Uservoice idea: