I may have hit a bug with SonarQube. Tried with 9.9.4 LTS, 9.9.5 LTA, and also upgraded the instance to 10.5.1 in hope that this had been fixed before me.
We use SonarQube Developer Edition, hosted on Windows from ZIP file, and I have recently configured SAML authentication with MS Entra ID there.
This is where the issue manifested.
We decorate our BitBucket pull requests with SonarQube, and the links that SonarQube provides in the pull request have the form of
https://sonarqube.domain.com/dashboard?id=project&pullRequest=PRID
The project is configured to be private, so when people click it, they are supposed to authenticate.
So if I try to open this link unauthenticated, SonarQube redirects me to
https://sonarqube.domain.com/sessions/new?return_to=%2Fdashboard%3Fid%3Dproject%26pullRequest%3DPRID&authorizationError=true)
Which is expected, of course, but then I click Log in with SAML there, authenticate successfully, and, suddenly, get
You’re not authorized to access this page. Please contact the administrator.
Well, I’m the administrator, and I have the following stack trace in web.log
:
2024.05.29 16:14:33 WARN web[aef5b0ff-b1c7-49ef-838c-4daa49dbe5f9][o.s.s.a.AuthenticationError] Fail to initialize authentication with provider 'saml'
java.nio.file.InvalidPathException: Illegal char <?> at index 10: /dashboard?id=**project**&pullRequest=**PRID**
at java.base/sun.nio.fs.WindowsPathParser.normalize(WindowsPathParser.java:182)
at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:153)
at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:77)
at java.base/sun.nio.fs.WindowsPath.parse(WindowsPath.java:92)
at java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:232)
at java.base/java.nio.file.Path.of(Path.java:147)
at org.sonar.server.authentication.OAuth2AuthenticationParametersImpl.escapePathTraversalChars(OAuth2AuthenticationParametersImpl.java:139)
at org.sonar.server.authentication.OAuth2AuthenticationParametersImpl.sanitizeRedirectUrl(OAuth2AuthenticationParametersImpl.java:134)
at org.sonar.server.authentication.OAuth2AuthenticationParametersImpl.init(OAuth2AuthenticationParametersImpl.java:63)
at org.sonar.server.authentication.InitFilter.handleProvider(InitFilter.java:74)
at org.sonar.server.authentication.InitFilter.doFilter(InitFilter.java:65)
at org.sonar.server.platform.web.MasterServletFilter$JavaxFilterAdapter.doFilter(MasterServletFilter.java:227)
at org.sonar.server.platform.web.MasterServletFilter$GodFilterChain.doFilter(MasterServletFilter.java:198)
at org.sonar.server.platform.web.MasterServletFilter$HttpFilterChainAdapter.doFilter(MasterServletFilter.java:241)
at org.sonar.server.authentication.DefaultAdminCredentialsVerifierFilter.doFilter(DefaultAdminCredentialsVerifierFilter.java:83)
at org.sonar.server.platform.web.MasterServletFilter$JavaxFilterAdapter.doFilter(MasterServletFilter.java:227)
at org.sonar.server.platform.web.MasterServletFilter$GodFilterChain.doFilter(MasterServletFilter.java:198)
at org.sonar.server.platform.web.MasterServletFilter.doFilter(MasterServletFilter.java:146)
at jdk.internal.reflect.GeneratedMethodAccessor20.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.apache.catalina.security.SecurityUtil.lambda$execute$0(SecurityUtil.java:222)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.base/javax.security.auth.Subject.doAsPrivileged(Subject.java:584)
at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:250)
at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:202)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:177)
at org.apache.catalina.core.ApplicationFilterChain.lambda$doFilter$0(ApplicationFilterChain.java:138)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:137)
at org.sonar.server.platform.web.UserSessionFilter.doFilter(UserSessionFilter.java:83)
at org.sonar.server.platform.web.UserSessionFilter.doFilter(UserSessionFilter.java:70)
at jdk.internal.reflect.GeneratedMethodAccessor20.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.apache.catalina.security.SecurityUtil.lambda$execute$0(SecurityUtil.java:222)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.base/javax.security.auth.Subject.doAsPrivileged(Subject.java:584)
at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:250)
at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:202)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:177)
at org.apache.catalina.core.ApplicationFilterChain.lambda$doFilter$0(ApplicationFilterChain.java:138)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:137)
at org.sonar.server.platform.web.CrossOriginFilter.doFilter(CrossOriginFilter.java:51)
at jdk.internal.reflect.GeneratedMethodAccessor20.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.apache.catalina.security.SecurityUtil.lambda$execute$0(SecurityUtil.java:222)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.base/javax.security.auth.Subject.doAsPrivileged(Subject.java:584)
at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:250)
at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:202)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:177)
at org.apache.catalina.core.ApplicationFilterChain.lambda$doFilter$0(ApplicationFilterChain.java:138)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:137)
at org.sonar.server.platform.web.CspFilter.doFilter(CspFilter.java:63)
at jdk.internal.reflect.GeneratedMethodAccessor20.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.apache.catalina.security.SecurityUtil.lambda$execute$0(SecurityUtil.java:222)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.base/javax.security.auth.Subject.doAsPrivileged(Subject.java:584)
at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:250)
at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:202)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:177)
at org.apache.catalina.core.ApplicationFilterChain.lambda$doFilter$0(ApplicationFilterChain.java:138)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:137)
at org.sonar.server.platform.web.CacheControlFilter.doFilter(CacheControlFilter.java:76)
at jdk.internal.reflect.GeneratedMethodAccessor20.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.apache.catalina.security.SecurityUtil.lambda$execute$0(SecurityUtil.java:222)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.base/javax.security.auth.Subject.doAsPrivileged(Subject.java:584)
at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:250)
at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:202)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:177)
at org.apache.catalina.core.ApplicationFilterChain.lambda$doFilter$0(ApplicationFilterChain.java:138)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:137)
at org.sonar.server.platform.web.SecurityServletFilter.doHttpFilter(SecurityServletFilter.java:60)
at org.sonar.server.platform.web.SecurityServletFilter.doFilter(SecurityServletFilter.java:47)
at jdk.internal.reflect.GeneratedMethodAccessor20.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.apache.catalina.security.SecurityUtil.lambda$execute$0(SecurityUtil.java:222)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.base/javax.security.auth.Subject.doAsPrivileged(Subject.java:584)
at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:250)
at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:202)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:177)
at org.apache.catalina.core.ApplicationFilterChain.lambda$doFilter$0(ApplicationFilterChain.java:138)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:137)
at org.sonar.server.platform.web.RedirectFilter.doFilter(RedirectFilter.java:56)
at jdk.internal.reflect.GeneratedMethodAccessor20.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.apache.catalina.security.SecurityUtil.lambda$execute$0(SecurityUtil.java:222)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.base/javax.security.auth.Subject.doAsPrivileged(Subject.java:584)
at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:250)
at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:202)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:177)
at org.apache.catalina.core.ApplicationFilterChain.lambda$doFilter$0(ApplicationFilterChain.java:138)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:137)
at org.sonar.server.platform.web.EndpointPathFilter.doFilter(EndpointPathFilter.java:47)
at jdk.internal.reflect.GeneratedMethodAccessor20.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.apache.catalina.security.SecurityUtil.lambda$execute$0(SecurityUtil.java:222)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.base/javax.security.auth.Subject.doAsPrivileged(Subject.java:584)
at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:250)
at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:202)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:177)
at org.apache.catalina.core.ApplicationFilterChain.lambda$doFilter$0(ApplicationFilterChain.java:138)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:137)
at org.sonar.server.platform.web.RequestIdFilter.doFilter(RequestIdFilter.java:66)
at jdk.internal.reflect.GeneratedMethodAccessor20.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.apache.catalina.security.SecurityUtil.lambda$execute$0(SecurityUtil.java:222)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.base/javax.security.auth.Subject.doAsPrivileged(Subject.java:584)
at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:250)
at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:202)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:177)
at org.apache.catalina.core.ApplicationFilterChain.lambda$doFilter$0(ApplicationFilterChain.java:138)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:137)
at org.sonar.server.platform.web.RootFilter.doFilter(RootFilter.java:65)
at jdk.internal.reflect.GeneratedMethodAccessor20.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.apache.catalina.security.SecurityUtil.lambda$execute$0(SecurityUtil.java:222)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.base/javax.security.auth.Subject.doAsPrivileged(Subject.java:584)
at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:250)
at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:202)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:177)
at org.apache.catalina.core.ApplicationFilterChain.lambda$doFilter$0(ApplicationFilterChain.java:138)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:137)
at org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:115)
at jdk.internal.reflect.GeneratedMethodAccessor20.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.apache.catalina.security.SecurityUtil.lambda$execute$0(SecurityUtil.java:222)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.base/javax.security.auth.Subject.doAsPrivileged(Subject.java:584)
at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:250)
at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:202)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:177)
at org.apache.catalina.core.ApplicationFilterChain.lambda$doFilter$0(ApplicationFilterChain.java:138)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:137)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:168)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:481)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130)
at ch.qos.logback.access.tomcat.LogbackValve.invoke(LogbackValve.java:267)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:346)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:928)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1786)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
at java.base/java.lang.Thread.run(Thread.java:833)
I have a workaround for this situation - you just need to sign in to SonarQube at the main page, where URL does not have any question marks, and then you can re-click the link from the PR.
However, educating every developer experiencing this situation is not the outcome I’d want
This is certainly true for any page that has a query part and I try to access with SAML auth.
Any suggestions, guys?