Group assignment issues with EntraID (OD-1797)
Tobias opened 2 years ago

Hi Robin,

we are using EntraID as a link between two domains. We synchronize certain groups from each domain to EntraID. Reference onedev/server#1719 The group names used for the local AD login are the same as for EntraID since they are synchronized to EntraID.

The login via EntraID works, the group assignment only works if a specific dynamic EntraID group has been created in OneDev.

Are there any issues with local synchronized groups? How exactly do you query the groups in EntraID?

Is it possible to get more information about the request and authentication with external authentication in the server log, perhaps with a label in the Docker container?

  • Robin Shen commented 2 years ago

    OneDev get group ids via groups claim, then calls ms graph api to get associated group names. And OneDev account will be assigned to same OneDev group if it exists.

    The code to call ms graph api to get group names:

    https://code.onedev.io/onedev/server/~files/afbe48836d390633cc1fd87fa38e8ff4ca19a563/server-plugin/server-plugin-sso-openid/src/main/java/io/onedev/server/plugin/sso/openid/EntraIdConnector.java?position=source-111.1-151.3-1

  • Tobias commented 2 years ago

    The code helped to solve the problem, thank you very much. We have now used the single sign-on provider OpenID. Now all groups of the user who wants to log in to OneDev using EntraID are queried.

    We have entered the following data:

    • Configuration Discovery URL: https://login.microsoftonline.com/(Tenant ID)/v2.0/.well-known/openid-configuration
    • Client ID: Application Client ID
    • Client Secret: Value (Client Secret)
    • Request Scopes: openid email profile
    • Group Claim: groups

    The following settings are set for the groups claim:

    • ID: sAMAccountName
    • Access: Group ID
    • SAML: Group ID
  • Robin Shen commented 2 years ago

    So at your side, the id token will return group name directly instead of group uuid, and you don't need to call graph api to convert to group name?

  • Tobias commented 2 years ago

    In the setup with EntraID as the single sign-on provider, we would have had to convert the group ID to the group names. Here the ID in the group claim settings was set to "Group ID" and not all of the user's groups were returned.

    With the sAMAccountName ID setting, the group name is returned, eliminating the need for conversion.

  • Tobias commented 2 years ago

    Since switching to the sign-on provider OpenID, an error has been appearing in our server log. I could not find a connection with a login to the OneDev server.

    2024-03-19 07:06:26,374 WARN  [qtp1720013107-812] o.a.w.core.util.lang.WicketObjects Could not resolve class [io.onedev.server.plugin.sso.openid.openidconnector]
    java.lang.ClassNotFoundException: io.onedev.server.plugin.sso.openid.openidconnector
    	at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:476)
    	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:594)
    	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:527)
    	at java.base/java.lang.Class.forName0(Native Method)
    	at java.base/java.lang.Class.forName(Class.java:398)
    	at org.apache.wicket.application.AbstractClassResolver.resolveClass(AbstractClassResolver.java:111)
    	at org.apache.wicket.core.util.lang.WicketObjects.resolveClass(WicketObjects.java:71)
    	at org.apache.wicket.core.request.mapper.BasicResourceReferenceMapper.resolveClass(BasicResourceReferenceMapper.java:157)
    	at org.apache.wicket.core.request.mapper.BasicResourceReferenceMapper.mapRequest(BasicResourceReferenceMapper.java:133)
    	at org.apache.wicket.request.mapper.ParentPathReferenceRewriter.mapRequest(ParentPathReferenceRewriter.java:84)
    	at org.apache.wicket.request.mapper.CompoundRequestMapper.mapRequest(CompoundRequestMapper.java:147)
    	at org.apache.wicket.request.cycle.RequestCycle.resolveRequestHandler(RequestCycle.java:184)
    	at org.apache.wicket.request.cycle.RequestCycle.processRequest(RequestCycle.java:214)
    	at org.apache.wicket.request.cycle.RequestCycle.processRequestAndDetach(RequestCycle.java:288)
    	at org.apache.wicket.protocol.ws.AbstractUpgradeFilter.processRequestCycle(AbstractUpgradeFilter.java:70)
    	at org.apache.wicket.protocol.http.WicketFilter.processRequest(WicketFilter.java:203)
    	at org.apache.wicket.protocol.http.WicketServlet.doGet(WicketServlet.java:137)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    	at io.onedev.server.web.DefaultWicketServlet.lambda$service$0(DefaultWicketServlet.java:45)
    	at io.onedev.server.persistence.DefaultSessionManager.lambda$run$0(DefaultSessionManager.java:108)
    	at io.onedev.server.persistence.DefaultSessionManager.call(DefaultSessionManager.java:90)
    	at io.onedev.server.persistence.DefaultSessionManager.run(DefaultSessionManager.java:107)
    	at io.onedev.server.web.DefaultWicketServlet.service(DefaultWicketServlet.java:42)
    	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799)
    	at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1656)
    	at com.google.inject.servlet.DefaultFilterPipeline.dispatch(DefaultFilterPipeline.java:47)
    	at com.google.inject.servlet.GuiceFilter.doFilter(GuiceFilter.java:133)
    	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
    	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626)
    	at io.onedev.server.git.GoGetFilter.doFilter(GoGetFilter.java:87)
    	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
    	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626)
    	at io.onedev.server.git.GitLfsFilter.doFilter(GitLfsFilter.java:462)
    	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
    	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626)
    	at io.onedev.server.git.GitFilter.doFilter(GitFilter.java:369)
    	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
    	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626)
    	at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61)
    	at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
    	at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
    	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:154)
    	at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
    	at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
    	at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
    	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:154)
    	at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
    	at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
    	at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
    	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:154)
    	at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
    	at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:458)
    	at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:373)
    	at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
    	at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
    	at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:387)
    	at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:370)
    	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:154)
    	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
    	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626)
    	at io.onedev.server.security.CorsFilter.doFilter(CorsFilter.java:47)
    	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
    	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626)
    	at io.onedev.server.jetty.DisableTraceFilter.doFilter(DisableTraceFilter.java:28)
    	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
    	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626)
    	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:552)
    	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
    	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624)
    	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
    	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1440)
    	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
    	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:505)
    	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594)
    	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
    	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1355)
    	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    	at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:772)
    	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
    	at org.eclipse.jetty.server.Server.handle(Server.java:516)
    	at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:487)
    	at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:732)
    	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:479)
    	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)
    	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
    	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
    	at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
    	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338)
    	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315)
    	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173)
    	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131)
    	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:409)
    	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883)
    	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034)
    	at java.base/java.lang.Thread.run(Thread.java:829)
    
  • Robin Shen commented 2 years ago

    Is this affecting your login? Are you able to reproduce this?

  • Tobias commented 2 years ago

    I am still clarifying whether the error only occurs when a specific user logs in. The logins are not affected by the error for any user.

    We are currently running AD login (External Authenticator/AD) and EntraID login (SSO/OpenID) in parallel.

  • Robin Shen changed state to 'Closed' 2 years ago
    Previous Value Current Value
    Open
    Closed
  • Robin Shen commented 2 years ago

    Unable to reproduce. Reopen if there is more info.

issue 1/1
Type
Question
Priority
Normal
Assignee
Labels
No labels
Issue Votes (0)
Watchers (3)
Reference
OD-1797
Please wait...
Connection lost or session expired, reload to recover
Page is in error, reload to recover