Issues with OpenID / Office365

Hi

I’m enabling OpenID Connect Authenticator to use Office365/AzureAD login.
So far, I can pass the Office365 login but when calling back the Wiki using its callback (/xwiki/oidc/authenticator/callback?..):

Type Exception Report

Message Failed to handle Resource Reference [path = authenticator/callback, endpoint = authenticator, pathSegments = [callback]]

Description The server encountered an unexpected condition that prevented it from fulfilling the request.

Exception

javax.servlet.ServletException: Failed to handle Resource Reference [path = authenticator/callback, endpoint = authenticator, pathSegments = [callback]]
org.xwiki.resource.servlet.ResourceReferenceHandlerServlet.handleResourceReference(ResourceReferenceHandlerServlet.java:161)
org.xwiki.resource.servlet.ResourceReferenceHandlerServlet.service(ResourceReferenceHandlerServlet.java:87)
javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
org.xwiki.container.servlet.filters.internal.SetHTTPHeaderFilter.doFilter(SetHTTPHeaderFilter.java:63)
org.xwiki.resource.servlet.RoutingFilter.doFilter(RoutingFilter.java:147)
Root Cause

org.xwiki.resource.ResourceReferenceHandlerException: Failed to handle http servlet request
org.xwiki.contrib.oidc.provider.internal.OIDCResourceReferenceHandler.handle(OIDCResourceReferenceHandler.java:110)
org.xwiki.resource.internal.DefaultResourceReferenceHandlerChain.handleNext(DefaultResourceReferenceHandlerChain.java:79)
org.xwiki.resource.internal.AbstractResourceReferenceHandlerManager.handle(AbstractResourceReferenceHandlerManager.java:82)
org.xwiki.resource.servlet.ResourceReferenceHandlerServlet.handleResourceReference(ResourceReferenceHandlerServlet.java:159)
org.xwiki.resource.servlet.ResourceReferenceHandlerServlet.service(ResourceReferenceHandlerServlet.java:87)
javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
org.xwiki.container.servlet.filters.internal.SetHTTPHeaderFilter.doFilter(SetHTTPHeaderFilter.java:63)
org.xwiki.resource.servlet.RoutingFilter.doFilter(RoutingFilter.java:147)
Root Cause

org.xwiki.contrib.oidc.provider.internal.OIDCException: Failed to get access token:invalid_client
org.xwiki.contrib.oidc.auth.internal.endpoint.CallbackOIDCEndpoint.handle(CallbackOIDCEndpoint.java:134)
org.xwiki.contrib.oidc.provider.internal.OIDCResourceReferenceHandler.handle(OIDCResourceReferenceHandler.java:134)
org.xwiki.contrib.oidc.provider.internal.OIDCResourceReferenceHandler.handle(OIDCResourceReferenceHandler.java:108)
org.xwiki.resource.internal.DefaultResourceReferenceHandlerChain.handleNext(DefaultResourceReferenceHandlerChain.java:79)
org.xwiki.resource.internal.AbstractResourceReferenceHandlerManager.handle(AbstractResourceReferenceHandlerManager.java:82)
org.xwiki.resource.servlet.ResourceReferenceHandlerServlet.handleResourceReference(ResourceReferenceHandlerServlet.java:159)
org.xwiki.resource.servlet.ResourceReferenceHandlerServlet.service(ResourceReferenceHandlerServlet.java:87)
javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
org.xwiki.container.servlet.filters.internal.SetHTTPHeaderFilter.doFilter(SetHTTPHeaderFilter.java:63)
org.xwiki.resource.servlet.RoutingFilter.doFilter(RoutingFilter.java:147)
Note The full stack trace of the root cause is available in the server logs.

Any idea ?

Yes that’s https://jira.xwiki.org/browse/OIDC-46. It means the provider you are using only allows clients you explicitly registered on it to authenticate, unfortunately this OpenID Connect extension is not implemented yet in the authenticator.

Now you might want to try https://extensions.xwiki.org/xwiki/bin/view/Extension/Office365%20Application/ which among other things provide an Office 365 specific authenticator.

Hi

That’s sad. As you marked the change as easy and as it’s been opened since 2017, and as you have several threads here about this matter, idea plan to fix this ?

Unfortunately this have a hard time getting at the top of my TODO list. But pull requests are welcome :wink:

Also, I’d love testing this but I struggle accessing the License menu whatever admin or superadmin I use
And both assigned groups/users have programming permissions enabled :confused:

“Only the administrators with programming rights are allowed to manage the licenses.”

Ok a former admin wasn’t existing any more. recreating one with the same login solved this

Now, Office365 Pro app is enabled and setup. How can I enable the authenticator now ?

Hello @faichelbaum. You should know that you’re on xwiki.org and this forum is the community support for all free extensions from extensions.xwiki.org. You seem to be referring to a “Pro” extension, which I think means an paying extension provided by XWiki SAS on store.xwiki.com. XWiki SAS is providing some professional support for what it sells. Please contact them or check store.xwiki.com.

Thanks!

I think I mixed with another extension since this one does not seems to provide an authenticator actually. I was thinking about https://extensions.xwiki.org/xwiki/bin/view/Extension/XWiki%20Application%20-%20Google%20Apps actually, sorry. So indeed the quickest would be to find someone to add support for client validation in the OpenID Connect authenticator.

Any success in this case?

@Rozpalacz123 if you are talking about “add support for client validation in the OpenID Connect authenticator” this has been done yes. See the new property “oidc.secret” in https://extensions.xwiki.org/xwiki/bin/view/Extension/OpenID%20Connect/OpenID%20Connect%20Authenticator/.

My wiki works with azure now :smiley:

But I have a question. When user login first time account is created but only with First Name and Last name filled. Is there any option to fill other data like email?
I have try with:

oidc.user.emailFormater=${oidc.user.unique_name}
oidc.user.mailFormater=${oidc.user.unique_name}
oidc.user.email=${oidc.user.unique_name}
oidc.user.mail=${oidc.user.unique_name}

but no lack.

This is my JSON response.

{
    "aio": "kjaldjsfhkjsadhflkdhsafkjadhsfa",
    "amr": "[\"pwd\"]",
    "family_name": "Picasso",
    "given_name": "Pablo",
    "ipaddr": "11.12.113.144",
    "name": "Pablo Picasso",
    "oid": "234234-2343-4343-43434-2342342",
    "onprem_sid": "234234234-23-423-4-234-2-34-234",
    "sub": "234233q45rtferfwverfwgw45grfg45g45",
    "tid": "sdfkjgasdhjfgasjdhfgashjdfgasdhjf",
    "unique_name": "pablo.picasso@company.com",
    "upn": "pablo.picasso@company.com",
    "uti": "kajshdfkljahsdfkjahsdkjfahsd",
    "ver": "1.0"
}

By default you get all the standard OIDC fields filled in the XWiki user. In your JSON you only have the first and last name. You can see https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims for the list of standard OIDC claims.

To fill custom properties you can use the configuration oidc.user.mapping in xwiki.properties file (since 1.18). See https://extensions.xwiki.org/xwiki/bin/view/Extension/OpenID%20Connect/OpenID%20Connect%20Authenticator/#Hxwiki.properties for more details.

below works for me with email :slight_smile:
oidc.user.mapping=email=${oidc.user.unique_name}

Is there any option to get Xwiki field name for mapping like ‘email’ above? For “Blog Feed”, “Company” (i guess for it will be ‘company’) :slight_smile:

In the admin of the wiki you have the configuration of the “User Profile” in which you can find the various fields.

Yes I know, but can I found mapping somewhere for example for field “Blog Feed”?
I it will be:
oidc.user.mapping=BlogFeed=${oidc.user.unique_name}

?

If you look at the User Profile administration as I suggested you will notice that there is a field named “blogfeed” so that’s what you should use. You also have a link to the user class where you can see all the existing fields id and display name and add new ones if needed.

OK, everything works great but when I try get info from graph v1.0 (because I need more info about user info like mailNickname

oidc.endpoint.userinfo=https://graph.microsoft.com/v1.0/me

i get error.

response ({
  "error": {
    "code": "BadRequest",
    "message": "The MIME type 'text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2' requires a '/' character between type and subtype, such as 'text/plain'.",
    "innerError": {
      "request-id": "b0aaaeb0-1aaa-4bc2-9aaa-511aaaaae4ae",
      "date": "2020-03-19T17:17:13"
    }
  }
}
)

This is because we send in request header:

Accept: text/html, image/gif, image/jpeg, *; q=.2, /; q=.2

Is there any option to send
Accept: application/json
?

In my opinion it makes more sense because we always get JSON.
Looks very very easy to fix in JAVA code :slight_smile:

See resolution in:
StackOverflow - Bad Request 400 when making API call to Microsoft Graph

I don’t know Java but i think header should be added here:

OIDCUserManager.java

line 177

UserInfoRequest userinfoRequest =
                new UserInfoRequest(userInfoEndpoint, this.configuration.getUserInfoEndPointMethod(), accessToken);
            HTTPRequest userinfoHTTP = userinfoRequest.toHTTPRequest();
            userinfoHTTP.setHeader("User-Agent", this.getClass().getPackage().getImplementationTitle() + '/'
                + this.getClass().getPackage().getImplementationVersion());

As far as I understand the request does not send any Accept right now so no idea where what you get is coming from. Also the authenticator is using oauth2-oidc-sdk library for this so this discussion should go there instead since it’s not the authenticator job to decide this IMO.

I get it from logs :slight_smile: I see JSON that is returned.

It is set as default for this method. If nothing is send then default Accepted is text… (info from stackoverflow)

So there is no option to add one line as below?

UserInfoRequest userinfoRequest =
                new UserInfoRequest(userInfoEndpoint, this.configuration.getUserInfoEndPointMethod(), accessToken);
            HTTPRequest userinfoHTTP = userinfoRequest.toHTTPRequest();
            userinfoHTTP.setHeader("User-Agent", this.getClass().getPackage().getImplementationTitle() + '/'
                + this.getClass().getPackage().getImplementationVersion());

// add line below
   userinfoHTTP.setHeader("Accept", "application/json");

This is my config which is checking header Accept on MS site:

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

With other config like below MS not verify header Accept - we can send everything there:

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

or

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

everything works because there header Accept is not verifying on MS site. But I can not get all info about user in this way :frowning:

What is indicated on stackoverflow is that POSTman set this Accept by default but that’s not what is used here. Maybe you have some proxy which does that or maybe a proxy in front of https://graph.microsoft.com/v1.0/me.

It’s not really the question, of course it’s easy to set a custom Accept but it would be more interresting to:

  • understand why you end up with that Accept
  • understand why it’s not set explicitly in oauth2-oidc-sdk, this suggest the OIDC specification does not indicate any Accept`