OIDC - Allowed Groups / Prefix

Hi,
I hope you can help me - I’d like to switch our authentication to OIDC over entra. Working fine for “standard”-users incl. group-mapping.
But now in the last configs, I don’t come further.

At first, I’d like to limit the logins to a certain group, but this is ignored. (our group-Names look like “XWiki-xxx”)

I’ve added to xwiki.properties (with x on end to disable “all” logins):

oidc.groups.allowed=XWiki-Wissensportalx

And all I get in the logs is:

 DEBUG o.x.c.o.a.i.OIDCUserManager    - Updating XWiki claims
 DEBUG o.x.c.o.a.i.OIDCUserManager    - Getting groups sent by the provider associated with claim [groups]
 DEBUG o.x.c.o.a.i.OIDCUserManager    - Groups claim not found in userInfo token. Trying idToken
 DEBUG o.x.c.o.a.i.OIDCUserManager    - The provider sent the following groups: ["XWiki-BAZ","XWiki-HR","XWiki-BW","XWiki-Ideenbox","XWiki-Technik","XWiki-DWH","XWiki-BCM","XWiki-ZBSMBT","XWiki-Lehrlingsausbilder","XWiki-Wissensportal","XWiki-Finance_Controlling","XWiki-BW-LVS","XWiki-Wissensportal-EDVA","XWiki-PM","XWiki-HR-Laender","XWiki-Projekte-FinCo"]
 DEBUG o.x.c.o.a.i.OIDCUserManager    - Updating group membership for the user [XWiki.gerd\.schnoetzinger@xxxxxxx\.com]
 DEBUG o.x.c.o.a.i.OIDCUserManager    - The user belongs to following XWiki groups: [XWiki.XWiki-Wissensportal-EDVA, XWiki.XWikiAllGroup, XWiki.XWiki-HR-Laender, XWiki.XWiki-Wissensportal, XWiki.XWiki-HR, XWiki.XWiki-Ideenbox, XWiki.XWiki-PM, XWiki.XWiki-Projekte-FinCo, XWiki.XWiki-Technik, XWiki.XWiki-BCM, XWiki.XWiki-BW-LVS, XWiki.XWiki-DWH, XWiki.XWiki-BW, XWiki.XWiki-Finance_Controlling, XWiki.XWiki-BAZ, XWiki.XWiki-ZBSMBT, XWiki.XWiki-Lehrlingsausbilder]

It’s just ignored - no error that the user isn’t in this group.

And second, I’d like to limit the groups we’ve got, because all of them were created automatically which I didn’t like. So I’ve set:

oidc.groups.prefix=XWiki

but now, I’ll get this error:

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:764)
	org.xwiki.container.servlet.filters.internal.SetHTTPHeaderFilter.doFilter(SetHTTPHeaderFilter.java:63)
	org.xwiki.resource.servlet.RoutingFilter.doFilter(RoutingFilter.java:145)
	org.xwiki.container.servlet.filters.internal.SavedRequestRestorerFilter.doFilter(SavedRequestRestorerFilter.java:208)
	org.xwiki.container.servlet.filters.internal.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:117)

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:764)
	org.xwiki.container.servlet.filters.internal.SetHTTPHeaderFilter.doFilter(SetHTTPHeaderFilter.java:63)
	org.xwiki.resource.servlet.RoutingFilter.doFilter(RoutingFilter.java:145)
	org.xwiki.container.servlet.filters.internal.SavedRequestRestorerFilter.doFilter(SavedRequestRestorerFilter.java:208)
	org.xwiki.container.servlet.filters.internal.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:117)

Root Cause

java.lang.NullPointerException: Cannot invoke "java.util.List.stream()" because "providerGroups" is null
	org.xwiki.contrib.oidc.auth.internal.OIDCUserManager.checkAllowedGroups(OIDCUserManager.java:228)
	org.xwiki.contrib.oidc.auth.internal.OIDCUserManager.updateUser(OIDCUserManager.java:299)
	org.xwiki.contrib.oidc.auth.internal.OIDCUserManager.updateUserInfo(OIDCUserManager.java:213)
	org.xwiki.contrib.oidc.auth.internal.OIDCUserManager.updateUserInfo(OIDCUserManager.java:181)
	org.xwiki.contrib.oidc.auth.internal.endpoint.CallbackOIDCEndpoint.handle(CallbackOIDCEndpoint.java:248)
	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:764)
	org.xwiki.container.servlet.filters.internal.SetHTTPHeaderFilter.doFilter(SetHTTPHeaderFilter.java:63)
	org.xwiki.resource.servlet.RoutingFilter.doFilter(RoutingFilter.java:145)
	org.xwiki.container.servlet.filters.internal.SavedRequestRestorerFilter.doFilter(SavedRequestRestorerFilter.java:208)
	org.xwiki.container.servlet.filters.internal.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:117)

in catalina.out, i see the sucessfule OIDC user info response, and after this, this error shows (on favicon.ico??)


[2024-04-11 13:14:01] [info] 2024-04-11 13:14:01,698 [https-openssl-apr-8443-exec-8 - https://xwiki-dev.xxxxxx.com:8443/favicon.ico] ERROR .o.i.DefaultObservationManager - Failed to send event [class org.xwiki.bridge.event.ActionExecutedEvent (view)] to listener [com.xpn.xwiki.stats.impl.XWikiStatsServiceImpl@6282f455]
[2024-04-11 13:14:01] [info] java.lang.IllegalStateException: Cannot create a session after the response has been committed
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.connector.Request.doGetSession(Request.java:3060)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.connector.Request.getSession(Request.java:2492)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:908)
[2024-04-11 13:14:01] [info] #011at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:244)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:585)
[2024-04-11 13:14:01] [info] #011at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:244)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:585)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:529)
[2024-04-11 13:14:01] [info] #011at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:253)
[2024-04-11 13:14:01] [info] #011at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:253)
[2024-04-11 13:14:01] [info] #011at com.xpn.xwiki.stats.impl.StatsUtil.getRecentActionFromSessions(StatsUtil.java:281)
[2024-04-11 13:14:01] [info] #011at com.xpn.xwiki.stats.impl.XWikiStatsServiceImpl.onEvent(XWikiStatsServiceImpl.java:160)
[2024-04-11 13:14:01] [info] #011at org.xwiki.observation.internal.DefaultObservationManager.notify(DefaultObservationManager.java:338)
[2024-04-11 13:14:01] [info] #011at org.xwiki.observation.internal.DefaultObservationManager.notify(DefaultObservationManager.java:303)
[2024-04-11 13:14:01] [info] #011at com.xpn.xwiki.web.XWikiAction.execute(XWikiAction.java:747)
[2024-04-11 13:14:01] [info] #011at com.xpn.xwiki.web.XWikiAction.execute(XWikiAction.java:339)
[2024-04-11 13:14:01] [info] #011at com.xpn.xwiki.web.LegacyActionServlet.service(LegacyActionServlet.java:108)
[2024-04-11 13:14:01] [info] #011at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
[2024-04-11 13:14:01] [info] #011at org.xwiki.container.servlet.filters.internal.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:117)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:711)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:461)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:385)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:313)
[2024-04-11 13:14:01] [info] #011at com.xpn.xwiki.web.XWikiAction.redirectSpaceURLs(XWikiAction.java:1171)
[2024-04-11 13:14:01] [info] #011at com.xpn.xwiki.web.XWikiAction.execute(XWikiAction.java:509)
[2024-04-11 13:14:01] [info] #011at com.xpn.xwiki.web.XWikiAction.execute(XWikiAction.java:339)
[2024-04-11 13:14:01] [info] #011at com.xpn.xwiki.web.LegacyActionServlet.service(LegacyActionServlet.java:108)
[2024-04-11 13:14:01] [info] #011at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
[2024-04-11 13:14:01] [info] #011at org.xwiki.container.servlet.filters.internal.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:117)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:711)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:461)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:385)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:313)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:403)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:249)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
[2024-04-11 13:14:01] [info] #011at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:359)
[2024-04-11 13:14:01] [info] #011at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
[2024-04-11 13:14:01] [info] #011at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
[2024-04-11 13:14:01] [info] #011at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889)
[2024-04-11 13:14:01] [info] #011at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2128)
[2024-04-11 13:14:01] [info] #011at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
[2024-04-11 13:14:01] [info] #011at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
[2024-04-11 13:14:01] [info] #011at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
[2024-04-11 13:14:01] [info] #011at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
[2024-04-11 13:14:01] [info] #011at java.base/java.lang.Thread.run(Thread.java:840)

Can you please help here, what I’m doing wrong? If you need more information, please let me know.

Thanks,
Gerd

Just checked the code and while I don’t see anything wrong with it, it’s indeed missing some debug log that would help understand exactly what happen.

I just released a 2.5.2 with some more debug log in this area.

Thanks! I’ve updated the plugin, but the result is still the same, so it looks like this part of code isn’t even entered.



DEBUG i.OIDCResourceReferenceHandler - OIDC: Reference: [path = authenticator/callback, endpoint = authenticator, pathSegments = [callback]]
DEBUG c.o.a.i.e.CallbackOIDCEndpoint - OIDC callback: starting with request [https://172.25.23.14:8443/oidc/authenticator/callback?<...deleted...> 
DEBUG c.o.a.i.e.CallbackOIDCEndpoint - OIDC callback: adding secret <...deleted...> 
DEBUG c.o.a.i.e.CallbackOIDCEndpoint - OIDC Token request <...deleted...> 
DEBUG c.o.a.i.e.CallbackOIDCEndpoint - OIDC Token response <...deleted...> 

DEBUG o.x.c.o.a.i.OIDCUserManager    - OIDC user info request (org.xwiki.contrib.oidc.auth.internal.Endpoint@<...deleted...> )
DEBUG o.x.c.o.a.i.OIDCUserManager    - OIDC user info request (https://graph.microsoft.com/oidc/userinfo?https://graph.microsoft.com/oidc/userinfo,{Authorization=[Bearer <...deleted...> 
DEBUG o.x.c.o.a.i.OIDCUserManager    - OIDC user info response ({"sub":<...deleted...>

WARN  o.x.c.o.a.i.OIDCUserManager    - Failed to get user avatar from URL [https://graph.microsoft.com/v1.0/me/photo/$value]: IOException: Server returned HTTP response code: 403 for URL: https://graph.microsoft.com/v1.0/me/photo/$value
DEBUG o.x.c.o.a.i.OIDCUserManager    - Updating XWiki claims
DEBUG o.x.c.o.a.i.OIDCUserManager    - Getting groups sent by the provider associated with claim [groups]
DEBUG o.x.c.o.a.i.OIDCUserManager    - Groups claim not found in userInfo token. Trying idToken
DEBUG o.x.c.o.a.i.OIDCUserManager    - The provider sent the following groups: ["XWiki-BAZ","XWiki-HR","XWiki-BW","XWiki-Ideenbox","XWiki-Technik","XWiki-DWH","XWiki-BCM","XWiki-ZBSMBT","XWiki-Lehrlingsausbilder","XWiki-Wissensportal","XWiki-Finance_Controlling","XWiki-BW-LVS","XWiki-Wissensportal-EDVA","XWiki-PM","XWiki-HR-Laender","XWiki-Projekte-FinCo"]
DEBUG o.x.c.o.a.i.OIDCUserManager    - Updating group membership for the user [XWiki.gerd\.schnoetzinger@xxxxx\.com]
DEBUG o.x.c.o.a.i.OIDCUserManager    - The user belongs to following XWiki groups: [XWiki.XWiki-Ideenbox, XWiki.XWiki-Wissensportal-EDVA, XWiki.XWikiAllGroup, XWiki.XWiki-Technik, XWiki.XWiki-Projekte-FinCo, XWiki.XWiki-Lehrlingsausbilder, XWiki.XWiki-BW, XWiki.XWiki-HR-Laender, XWiki.XWiki-Finance_Controlling, XWiki.XWiki-Wissensportal, XWiki.XWiki-BCM, XWiki.XWiki-PM, XWiki.XWiki-ZBSMBT, XWiki.XWiki-BAZ, XWiki.XWiki-DWH, XWiki.XWiki-HR, XWiki.XWiki-BW-LVS]
DEBUG c.o.a.i.e.CallbackOIDCEndpoint - OIDC callback: principal=[SimplePrincipal[name = 'xwiki:XWiki.gerd\.schnoetzinger@xxxxx\.com']]
DEBUG c.o.a.i.e.CallbackOIDCEndpoint - OIDC callback: redirect=[https://xwiki-dev.xxxxx.com:8443/bin/login/XWiki/XWikiLogin?xredirect=%2Fbin%2Fview%2FMain%2F&loginLink=1&srid=jmVcQbyQ]


after that from several Requests:
DEBUG o.x.c.o.a.i.OIDCUserManager    - No user info refresh is needed

and also - when i add the “oidc.groups.prefix=XWiki” in the config, i get the same error again directly after the “OIDC user info response”:

Cannot invoke "java.util.List.stream()" because "providerGroups" is null

I’ve also tried to add some group-mappings, to get any difference:

oidc.groups.mapping=XWiki-Wissensportal2=XWiki-Wissensportal

# this results in 2 new lines after "The user belongs to following XWiki groups"
DEBUG o.x.c.o.a.i.OIDCUserManager    - Adding user [XWiki.gerd\.schnoetzinger@xxxxx\.com] to xwiki group [XWiki.XWiki-Wissensportal2]
DEBUG o.x.c.o.a.i.OIDCUserManager    - Finished adding user [XWiki.gerd\.schnoetzinger@xxxxx\.com] to xwiki group [XWiki.XWiki-Wissensportal2]

And this new group XWiki-Wissensportal2 was not existing before and has been automatically created! Is this the intended behaviour with new groups? With LDAP i had to create the groups before on my own.

Edit: Right version is used, in the user info request, this user-agent is sent (sorry - deleted it before):

, User-Agent=[OpenID Connect Authenticator/2.5.2]})

Actually, I think this is the root cause of all your problems (this seems to fail right before it checks the allowed groups). I just released a 2.5.3 with a bit of bulletproofing and some more log to hopefully understand better what is the problem (if it’s not fixed by the bulletproofing).

Hi,

thanks - it seems to work now, now i’m getting the “right” error:

org.xwiki.contrib.oidc.provider.internal.OIDCException: The user is not allowed to authenticate because it's not a member of the following groups: [XWiki-Wissensportalx]

But one thing i don’t understand. I set the prefix, so only groups beginning with this are considered in the mapping: (i added the -W to see it better)

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

But then i get the “not allowed”-error again, because the prefix is removed from the group-names:

DEBUG o.x.c.o.a.i.OIDCUserManager    - The provider sent the following groups: [issensportal, issensportal-EDVA]

I can solve this using the group-mapping, but should it be like this? I would prefer mapping the whole group name to a xwiki-group.

Thanks,
gerd

I’m not the author of that feature, so not 100% sure what was the initial intent. But it does not feel like the kind of behavior you have by mistake, and if people are using this, they now rely on this cutting (it would be quite a breakage to change that). I guess it would require some other property to control if the prefix should be removed or not.

Ok, i will do this using the group-mappings. - Thanks a lot !!

Could you please check one thing:
It looks like the “allowed group” is only working, when at least one group is sent (based on the prefix, if set).

I’ve invited a guest user in our tenant, but this user has no xwiki-relevant group. And this user can login and doesn’t get the error “it’s not a member of the following group”.
Maybe the “lookup” on the empty group-set doesn’t work for allowed-groups.

This is the part of the logs:

DEBUG o.x.c.o.a.i.OIDCUserManager    - Getting groups sent by the provider associated with claim [groups]
DEBUG o.x.c.o.a.i.OIDCUserManager    - Groups claim not found in userInfo token. Trying idToken
DEBUG o.x.c.o.a.i.OIDCUserManager    - The provider did not sent any group
DEBUG o.x.c.o.a.i.OIDCUserManager    - Checking allowed groups
WARN  o.x.c.o.a.i.OIDCUserManager    - Failed to get user avatar from URL [https://graph.microsoft.com/v1.0/me/photo/$value]: IOException: Server returned HTTP response code: 401 for URL: https://graph.microsoft.com/v1.0/me/photo/$value
DEBUG o.x.c.o.a.i.OIDCUserManager    - Updating XWiki claims

Only “checking allowed groups” and that’s it.

Thanks,
Gerd

I’ve created Loading... for this, I hope this is the right place for this.

Thanks,
Gerd