jenkinsci / azure-ad-plugin

Authentication and Authorization with Azure AD
https://plugins.jenkins.io/azure-ad/
MIT License
29 stars 57 forks source link

NullPointerException when using azure-ad with role-based-access-control #145

Closed Pistahh closed 3 years ago

Pistahh commented 3 years ago

Version report

Jenkins and plugins versions report:

Jenkins: 2.298
OS: Linux - 5.4.0-1049-azure
---
blueocean-events:1.24.7
blueocean-github-pipeline:1.24.7
basic-branch-build-strategies:1.3.2
github-branch-source:2.11.1
pipeline-model-api:1.8.5
pipeline-model-declarative-agent:1.1.1
pipeline-utility-steps:2.6.1
antisamy-markup-formatter:2.1
pipeline-stage-step:2.5
htmlpublisher:1.25
jira:3.3
cloudbees-bitbucket-branch-source:2.9.9
jobConfigHistory:2.27
ivy:2.1
sshd:3.0.3
jenkins-design-language:1.24.7
token-macro:2.15
workflow-job:2.41
docker-java-api:3.1.5.2
handy-uri-templates-2-api:2.1.8-1.0
maven-plugin:3.12
echarts-api:5.1.2-2
blueocean-jira:1.24.7
jdk-tool:1.5
workflow-multibranch:2.24
mercurial:2.15
blueocean-rest-impl:1.24.7
git-client:3.7.2
structs:1.23
checks-api:1.7.0
run-condition:1.5
slack:2.48
favorite:2.3.3
change-assembly-version-plugin:1.10
bootstrap5-api:5.0.1-2
bitbucket:1.1.29
blueocean-autofavorite:1.2.4
pipeline-graph-analysis:1.11
hashicorp-vault-plugin:3.8.0
pipeline-model-extensions:1.8.5
azure-sdk:20.vd701043901ab
apache-httpcomponents-client-4-api:4.5.13-1.0
role-strategy:3.1.1
blueocean-git-pipeline:1.24.7
font-awesome-api:5.15.3-3
blueocean-pipeline-api-impl:1.24.7
configuration-as-code:1.51
handlebars:3.0.8
pipeline-rest-api:2.19
workflow-scm-step:2.13
docker-plugin:1.2.2
credentials-binding:1.25
authorize-project:1.4.0
google-oauth-plugin:1.0.6
pipeline-stage-view:2.19
pipeline-build-step:2.13
azure-commons:1.1.3
timestamper:1.13
popper2-api:2.5.4-2
blueocean-display-url:2.4.1
logstash:2.4.0
kubernetes-credentials:0.9.0
jquery:1.12.4-1
pipeline-milestone-step:1.3.2
extended-choice-parameter:0.82
blueocean:1.24.7
artifactory:3.11.4
ssh-agent:1.23
file-operations:1.11
pipeline-input-step:2.12
snakeyaml-api:1.29.1
kubernetes:1.30.0
azure-ad:168.ve6e7e368dbf6
blueocean-core-js:1.24.7
momentjs:1.1.1
windows-slaves:1.8
external-monitor-job:1.7
workflow-api:2.45
gradle:1.36
workflow-aggregator:2.6
durable-task:1.37
plugin-util-api:2.3.0
github-api:1.123
kubernetes-pipeline-devops-steps:1.6
pubsub-light:1.16
subversion:2.14.4
command-launcher:1.6
pipeline-model-definition:1.8.5
blueocean-jwt:1.24.7
trilead-api:1.0.13
workflow-basic-steps:2.23
bouncycastle-api:2.20
ace-editor:1.1
blueocean-personalization:1.24.7
kubernetes-client-api:5.4.1
blueocean-pipeline-editor:1.24.7
splunk-devops:1.9.6
bootstrap4-api:4.6.0-3
kubernetes-pipeline-aggregator:1.6
docker-workflow:1.26
lockable-resources:2.11
jquery3-api:3.6.0-1
sonar:2.13.1
powershell:1.5
variant:1.4
workflow-cps-global-lib:2.19
pipeline-stage-tags-metadata:1.8.5
workflow-cps:2.92
credentials:2.5
matrix-project:1.19
pam-auth:1.6
git-server:1.9
jsch:0.1.55.2
blueocean-pipeline-scm-api:1.24.7
http_request:1.9.0
github:1.33.1
workflow-step-api:2.23
workflow-durable-task-step:2.39
caffeine-api:2.9.1-23.v51c4e2c879c8
metrics:4.0.2.8
blueocean-executor-info:1.24.7
javadoc:1.6
mailer:1.34
popper-api:1.16.1-2
jjwt-api:0.11.2-9.c8b45b8bb173
blueocean-commons:1.24.7
ssh-slaves:1.32.0
blueocean-i18n:1.24.7
audit-trail:3.8
kubernetes-pipeline-arquillian-steps:1.6
blueocean-rest:1.24.7
junit:1.50
git:4.7.2
cloudbees-folder:6.15
workflow-support:3.8
ldap:2.7
sse-gateway:1.24
plain-credentials:1.7
jquery-detached:1.2.1
script-security:1.77
oauth-credentials:0.4
okhttp-api:3.14.9
display-url-api:2.3.5
blueocean-bitbucket-pipeline:1.24.7
authentication-tokens:1.4
docker-commons:1.17
custom-tools-plugin:0.8
mapdb-api:1.0.9.0
job-dsl:1.77
extended-read-permission:3.2
config-file-provider:3.8.0
kubernetes-pipeline-steps:1.6
jackson2-api:2.12.3
branch-api:2.6.4
scm-api:2.6.4
jquery-ui:1.0.2
matrix-auth:2.6.7
ant:1.11
ssh-credentials:1.19
splunk-devops-extend:1.9.6
azure-credentials:182.v3ccd4a755864
blueocean-config:1.24.7
blueocean-web:1.24.7
blueocean-dashboard:1.24.7
See above

Reproduction steps

When opening the role assignment page the groups have these error messages.

image

Detailed stack trace:

java.lang.NullPointerException
    at java.util.Objects.requireNonNull(Objects.java:203)
    at com.github.benmanes.caffeine.cache.BoundedLocalCache.computeIfAbsent(BoundedLocalCache.java:2364)
    at com.github.benmanes.caffeine.cache.LocalCache.computeIfAbsent(LocalCache.java:108)
    at com.github.benmanes.caffeine.cache.LocalManualCache.get(LocalManualCache.java:62)
    at com.microsoft.jenkins.azuread.AzureCachePool.getBelongingGroupsByOid(AzureCachePool.java:35)
    at com.microsoft.jenkins.azuread.AzureSecurityRealm.lambda$null$5(AzureSecurityRealm.java:494)
    at com.github.benmanes.caffeine.cache.BoundedLocalCache.lambda$doComputeIfAbsent$14(BoundedLocalCache.java:2405)
    at java.util.concurrent.ConcurrentHashMap.compute(ConcurrentHashMap.java:1853)
    at com.github.benmanes.caffeine.cache.BoundedLocalCache.doComputeIfAbsent(BoundedLocalCache.java:2403)
    at com.github.benmanes.caffeine.cache.BoundedLocalCache.computeIfAbsent(BoundedLocalCache.java:2386)
    at com.github.benmanes.caffeine.cache.LocalCache.computeIfAbsent(LocalCache.java:108)
    at com.github.benmanes.caffeine.cache.LocalManualCache.get(LocalManualCache.java:62)
    at com.microsoft.jenkins.azuread.AzureSecurityRealm.lambda$createSecurityComponents$6(AzureSecurityRealm.java:478)
    at hudson.security.SecurityRealm.loadUserByUsername2(SecurityRealm.java:411)
    at hudson.security.SecurityRealm.loadUserByUsername(SecurityRealm.java:421)
    at org.jenkinsci.plugins.matrixauth.AuthorizationContainerDescriptor.doCheckName_(AuthorizationContainerDescriptor.java:140)
    at hudson.security.GlobalMatrixAuthorizationStrategy$DescriptorImpl.doCheckName(GlobalMatrixAuthorizationStrategy.java:228)
    at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:627)
    at org.kohsuke.stapler.Function$MethodFunction.invoke(Function.java:393)
    at org.kohsuke.stapler.Function$InstanceFunction.invoke(Function.java:405)
    at org.kohsuke.stapler.Function.bindAndInvoke(Function.java:208)
    at org.kohsuke.stapler.Function.bindAndInvokeAndServeResponse(Function.java:141)
    at org.kohsuke.stapler.MetaClass$11.doDispatch(MetaClass.java:536)
    at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)
    at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:766)
    at org.kohsuke.stapler.Stapler.invoke(Stapler.java:898)
    at org.kohsuke.stapler.MetaClass$9.dispatch(MetaClass.java:457)
    at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:766)
    at org.kohsuke.stapler.Stapler.invoke(Stapler.java:898)
    at org.kohsuke.stapler.MetaClass$2.doDispatch(MetaClass.java:220)
    at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)
    at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:766)
    at org.kohsuke.stapler.Stapler.invoke(Stapler.java:898)
    at org.kohsuke.stapler.Stapler.invoke(Stapler.java:694)
    at org.kohsuke.stapler.Stapler.service(Stapler.java:240)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799)
    at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1626)
    at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:157)
    at com.splunk.splunkjenkins.WebPostAccessLogger.doFilter(WebPostAccessLogger.java:39)
    at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:154)
    at org.jenkinsci.plugins.ssegateway.Endpoint$SSEListenChannelFilter.doFilter(Endpoint.java:248)
    at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:154)
    at jenkins.telemetry.impl.UserLanguages$AcceptLanguageFilter.doFilter(UserLanguages.java:129)
    at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:154)
    at hudson.plugins.audit_trail.AuditTrailFilter.doFilter(AuditTrailFilter.java:111)
    at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:154)
    at jenkins.security.ResourceDomainFilter.doFilter(ResourceDomainFilter.java:81)
    at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:154)
    at io.jenkins.blueocean.ResourceCacheControl.doFilter(ResourceCacheControl.java:134)
    at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:154)
    at io.jenkins.blueocean.auth.jwt.impl.JwtAuthenticationFilter.doFilter(JwtAuthenticationFilter.java:60)
    at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:154)
    at jenkins.metrics.impl.MetricsFilter.doFilter(MetricsFilter.java:125)
    at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:154)
    at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:160)
    at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
    at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
    at hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:161)
    at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
    at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:93)
    at jenkins.security.AcegiSecurityExceptionFilter.doFilter(AcegiSecurityExceptionFilter.java:52)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:98)
    at hudson.security.UnwrapSecurityExceptionFilter.doFilter(UnwrapSecurityExceptionFilter.java:53)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:98)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:121)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:98)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:105)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:98)
    at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:101)
    at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:92)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:98)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:218)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:98)
    at jenkins.security.BasicHeaderProcessor.doFilter(BasicHeaderProcessor.java:96)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:98)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
    at hudson.security.HttpSessionContextIntegrationFilter2.doFilter(HttpSessionContextIntegrationFilter2.java:62)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:98)
    at hudson.security.ChainedServletFilter.doFilter(ChainedServletFilter.java:110)
    at hudson.security.HudsonFilter.doFilter(HudsonFilter.java:170)
    at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
    at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
    at org.kohsuke.stapler.compression.CompressionFilter.doFilter(CompressionFilter.java:51)
    at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
    at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
    at hudson.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:85)
    at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
    at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
    at org.kohsuke.stapler.DiagnosticThreadNameFilter.doFilter(DiagnosticThreadNameFilter.java:30)
    at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
    at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
    at jenkins.security.SuspiciousRequestFilter.doFilter(SuspiciousRequestFilter.java:36)
    at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
    at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:548)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:578)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)
    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:1435)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501)
    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:1350)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    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:388)
    at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:633)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:380)
    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:336)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:129)
    at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:383)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:882)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1036)
    at java.lang.Thread.run(Thread.java:748)

Results

Expected result:

No ugly stack traces :)

Actual result:

Stack traces :(

timja commented 3 years ago

Can you provide a bit more detail?

In the config.xml what's in the assignedSIDs section?

You can replace names, emails and IDs with pseudonyms, but I need the format that they are stored on disk.

I tried to reproduce this and I wasn't able to

Pistahh commented 3 years ago

In config.xml it literally contains the same names as seen in the matrix, i.e. something like

<assignedSIDs>
    <sid>#groupname1</sid>
    <sid>#groupname2</sid>
    <sid>user.name1@XXXXXXXX.com</sid>
    <sid>user.name2@XXXXXXXX.com</sid>
</assignedSIDs>

Also noticed (but not sure how relevant or related it is) that for any groups that has a name starting with # it doesn't result in any error (as if it were found) - but note the displayname = null.

This also happens for nonexistant groups too, it "accepts" everything starting with a #:

image

with using %23 instead of # I get the following:

image

timja commented 3 years ago

The object ID itself should work but thanks for getting back to me