我正在将 Apache Zeppelin 版本 0.11.1 与 Keycloak 集成以进行身份验证和授权。为了支持这种集成,我使用了额外的库(pac4j 和 buji pac4j),因为 Zeppelin 使用 Shiro 进行身份验证,而 Shiro 本身不支持 OIDC。
我已完成所有配置,并且可以通过 Keycloak 成功登录 Zeppelin。但是,登录后,每当我单击 Interpreter 或 Notebook Repo 等任何部分时,我都会遇到来自 pac4j-core 的空指针异常,并出现以下错误:
HTTP ERROR 500 javax.servlet.ServletException: org.pac4j.core.exception.TechnicalException: Bad token response, error=invalid_grant, description=PKCE verification failed
URI: /api/callback
STATUS: 500
MESSAGE: javax.servlet.ServletException: org.pac4j.core.exception.TechnicalException: Bad token response, error=invalid_grant, description=PKCE verification failed
SERVLET: rest
CAUSED BY: javax.servlet.ServletException: org.pac4j.core.exception.TechnicalException: Bad token response, error=invalid_grant, description=PKCE verification failed
CAUSED BY: org.pac4j.core.exception.TechnicalException: Bad token response, error=invalid_grant, description=PKCE verification failed
Caused by:
javax.servlet.ServletException: org.pac4j.core.exception.TechnicalException: Bad token response, error=invalid_grant, description=PKCE verification failed
at org.apache.shiro.web.servlet.AdviceFilter.cleanup(AdviceFilter.java:196)
at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:148)
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 org.apache.zeppelin.server.CorsFilter.doFilter(CorsFilter.java:64)
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.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:600)
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: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.ContextHandlerCollection.handle(ContextHandlerCollection.java:234)
at io.micrometer.core.instrument.binder.jetty.TimedHandler.handle(TimedHandler.java:120)
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.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:834)
Caused by: org.pac4j.core.exception.TechnicalException: Bad token response, error=invalid_grant, description=PKCE verification failed
at org.pac4j.oidc.credentials.authenticator.OidcAuthenticator.executeTokenRequest(OidcAuthenticator.java:206)
at org.pac4j.oidc.credentials.authenticator.OidcAuthenticator.validate(OidcAuthenticator.java:165)
at org.pac4j.core.client.BaseClient.lambda$retrieveCredentials$0(BaseClient.java:75)
at java.base/java.util.Optional.ifPresent(Optional.java:183)
at org.pac4j.core.client.BaseClient.retrieveCredentials(BaseClient.java:72)
at org.pac4j.core.client.IndirectClient.getCredentials(IndirectClient.java:145)
at org.pac4j.core.engine.DefaultCallbackLogic.perform(DefaultCallbackLogic.java:75)
at io.buji.pac4j.filter.CallbackFilter.doFilter(CallbackFilter.java:72)
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)
... 42 more
Powered by Jetty:// 9.4.52.v20230823
尝试访问 Interpreter 等页面时会发生此错误,该页面应通过调用某些 API 来检索解释器设置(在下面的日志中)。这些API也受到我的shiro.ini中的oidcSecurityFilter的保护,导致了上面提到的错误。
这是我访问 Interpreter 页面时 Zeppelin 的日志:
**....
**
INFO [2024-08-08 00:10:31,281] ({main} ZeppelinServer.java[main]:271) - Done, zeppelin server started
INFO [2024-08-08 00:10:37,513] ({qtp2142565033-27} AbstractValidatingSessionManager.java[enableSessionValidation]:233) - Enabling session validation scheduler...
WARN [2024-08-08 00:10:45,122] ({qtp2142565033-46} TokenValidator.java[<init>]:50) - Preferred JWS algorithm: null not available. Using all metadata algorithms: [PS384, ES384, RS384, HS256, HS512, ES256, RS256, HS384, ES512, PS256, PS512, RS512]
INFO [2024-08-08 00:10:45,765] ({qtp2142565033-35} ShiroAuthenticationService.java[<init>]:75) - ShiroAuthenticationService is initialized
WARN [2024-08-08 00:10:45,779] ({qtp2142565033-35} SecurityRestApi.java[ticket]:82) - {"status":"OK","message":"","body":{"principal":"admin","ticket":"63f3addc-7784-414b-a4ab-c8b47837d998","roles":"[\"admin\"]"}}
INFO [2024-08-08 00:10:46,173] ({qtp2142565033-27} NotebookServer.java[onOpen]:256) - Open connection to /127.0.0.1:2283 with Session: WebSocketSession[websocket=JsrAnnotatedEventDriver[websocket=org.apache.zeppelin.socket.NotebookServer@5a4bef8],behavior=SERVER,connection=WebSocketServerConnection@37f1a299::SocketChannelEndPoint@397c5385{l=/127.0.0.1:8080,r=/127.0.0.1:2283,OPEN,fill=-,flush=-,to=5/300000}{io=0/0,kio=0,kro=1}->WebSocketServerConnection@37f1a299[s=ConnectionState@9eec231[OPENING],f=Flusher@70a8628f[IDLE][queueSize=0,aggregateSize=-1,terminated=null],g=Generator[SERVER,validating,+rsv1],p=Parser@6ac0de89[ExtensionStack,s=START,c=0,len=0,f=null]],remote=WebSocketRemoteEndpoint@4a714423[batching=true],incoming=JsrAnnotatedEventDriver[websocket=org.apache.zeppelin.socket.NotebookServer@5a4bef8],outgoing=ExtensionStack[queueSize=0,extensions=[permessage-deflate],incoming=org.eclipse.jetty.websocket.common.extensions.compress.PerMessageDeflateExtension,outgoing=org.eclipse.jetty.websocket.common.extensions.compress.PerMessageDeflateExtension]], config: [Origin, javax.websocket.endpoint.localAddress, javax.websocket.upgrade.locales, javax.websocket.endpoint.remoteAddress, X-Watcher-Key]
INFO [2024-08-08 00:10:54,591] ({qtp2142565033-46} AbstractValidatingSessionManager.java[enableSessionValidation]:233) - Enabling session validation scheduler...
WARN [2024-08-08 00:10:54,595] ({qtp2142565033-32} HttpChannel.java[handleException]:776) - /next/api/interpreter
javax.servlet.ServletException: java.lang.NullPointerException
at org.apache.shiro.web.servlet.AdviceFilter.cleanup(AdviceFilter.java:196)
at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:148)
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 org.apache.zeppelin.server.CorsFilter.doFilter(CorsFilter.java:64)
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.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:600)
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: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.ContextHandlerCollection.handle(ContextHandlerCollection.java:234)
at io.micrometer.core.instrument.binder.jetty.TimedHandler.handle(TimedHandler.java:120)
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:834)
Caused by: java.lang.NullPointerException
at org.pac4j.core.http.ajax.DefaultAjaxRequestResolver.buildAjaxResponse(DefaultAjaxRequestResolver.java:42)
at org.pac4j.core.client.IndirectClient.getRedirectionAction(IndirectClient.java:97)
at org.pac4j.core.engine.DefaultSecurityLogic.redirectToIdentityProvider(DefaultSecurityLogic.java:237)
at org.pac4j.core.engine.DefaultSecurityLogic.perform(DefaultSecurityLogic.java:150)
at io.buji.pac4j.filter.SecurityFilter.doFilter(SecurityFilter.java:77)
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)
... 47 more
** ...
**
WARN [2024-08-08 00:10:54,595] ({qtp2142565033-67} HttpChannel.java[handleException]:776) - /next/api/interpreter/repository
javax.servlet.ServletException: java.lang.NullPointerException
at org.apache.shiro.web.servlet.AdviceFilter.cleanup(AdviceFilter.java:196)
at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:148)
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 org.apache.zeppelin.server.CorsFilter.doFilter(CorsFilter.java:64)
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.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:600)
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: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.ContextHandlerCollection.handle(ContextHandlerCollection.java:234)
at io.micrometer.core.instrument.binder.jetty.TimedHandler.handle(TimedHandler.java:120)
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.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:834)
Caused by: java.lang.NullPointerException
at org.pac4j.core.http.ajax.DefaultAjaxRequestResolver.buildAjaxResponse(DefaultAjaxRequestResolver.java:42)
at org.pac4j.core.client.IndirectClient.getRedirectionAction(IndirectClient.java:97)
at org.pac4j.core.engine.DefaultSecurityLogic.redirectToIdentityProvider(DefaultSecurityLogic.java:237)
at org.pac4j.core.engine.DefaultSecurityLogic.perform(DefaultSecurityLogic.java:150)
at io.buji.pac4j.filter.SecurityFilter.doFilter(SecurityFilter.java:77)
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)
... 42 more
WARN [2024-08-08 00:10:55,032] ({qtp2142565033-74} HttpChannel.java[handleException]:776) - /api/callback
javax.servlet.ServletException: org.pac4j.core.exception.TechnicalException: Bad token response, error=invalid_grant, description=PKCE verification failed
at org.apache.shiro.web.servlet.AdviceFilter.cleanup(AdviceFilter.java:196)
at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:148)
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 org.apache.zeppelin.server.CorsFilter.doFilter(CorsFilter.java:64)
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.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:600)
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: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.ContextHandlerCollection.handle(ContextHandlerCollection.java:234)
at io.micrometer.core.instrument.binder.jetty.TimedHandler.handle(TimedHandler.java:120)
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.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:834)
Caused by: org.pac4j.core.exception.TechnicalException: Bad token response, error=invalid_grant, description=PKCE verification failed
at org.pac4j.oidc.credentials.authenticator.OidcAuthenticator.executeTokenRequest(OidcAuthenticator.java:206)
at org.pac4j.oidc.credentials.authenticator.OidcAuthenticator.validate(OidcAuthenticator.java:165)
at org.pac4j.core.client.BaseClient.lambda$retrieveCredentials$0(BaseClient.java:75)
at java.base/java.util.Optional.ifPresent(Optional.java:183)
at org.pac4j.core.client.BaseClient.retrieveCredentials(BaseClient.java:72)
at org.pac4j.core.client.IndirectClient.getCredentials(IndirectClient.java:145)
at org.pac4j.core.engine.DefaultCallbackLogic.perform(DefaultCallbackLogic.java:75)
at io.buji.pac4j.filter.CallbackFilter.doFilter(CallbackFilter.java:72)
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)
... 42 more
这是我的shiro.ini:
[main]
roleAdminAuthGenerator = org.pac4j.core.authorization.generator.FromAttributesAuthorizationGenerator
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
securityManager.sessionManager = $sessionManager
securityManager.sessionManager.globalSessionTimeout = 86400000
oidcConfig = org.pac4j.oidc.config.OidcConfiguration
oidcConfig.discoveryURI = http://localhost:9889/realms/zeppelin/.well-known/openid-configuration
oidcConfig.clientId = zeppelin-client
oidcConfig.secret = Y44RsXalwm7ulAx5bNRukV2uEoRyPF7p
oidcConfig.clientAuthenticationMethodAsString = client_secret_basic
oidcClient = org.pac4j.oidc.client.OidcClient
oidcClient.configuration = $oidcConfig
oidcConfig.logoutUrl = http://localhost:9889/realms/zeppelin/protocol/openid-connect/logout
oidcConfig.withState = false
keycloakOidcClient = org.pac4j.oidc.client.KeycloakOidcClient
keycloakOidcClient.configuration = $oidcConfig
keycloakOidcClient.name = keycloakOidcClient
keycloakOidcClient.authorizationGenerator = $roleAdminAuthGenerator
clients = org.pac4j.core.client.Clients
clients.callbackUrl = http://localhost:8080/api/callback
clients.clients = $keycloakOidcClient
requireRoleAdmin = org.pac4j.core.authorization.authorizer.RequireAnyRoleAuthorizer
requireRoleAdmin.elements = admin_role
requireRoleUser = org.pac4j.core.authorization.authorizer.RequireAnyRoleAuthorizer
requireRoleUser.elements = admin_role, user_role
requireRoleAdmin = org.pac4j.core.authorization.authorizer.RequireAnyRoleAuthorizer
usernameAuthorizer = com.custom.pac4j.UsernameAuthorizer
config = org.pac4j.core.config.Config
config.clients = $clients
config.authorizers = username:$usernameAuthorizer
pac4jRealm = io.buji.pac4j.realm.Pac4jRealm
pac4jSubjectFactory = io.buji.pac4j.subject.Pac4jSubjectFactory
securityManager.subjectFactory = $pac4jSubjectFactory
pac4jRealm.principalNameAttribute = preferred_username
oidcSecurityFilter = io.buji.pac4j.filter.SecurityFilter
oidcSecurityFilter.config = $config
oidcSecurityFilter.clients = keycloakOidcClient
customCallbackLogic = com.custom.pac4j.ForceDefaultURLCallbackLogic
callbackFilter = io.buji.pac4j.filter.CallbackFilter
callbackFilter.defaultUrl = http://localhost:8080
callbackFilter.config = $config
callbackFilter.callbackLogic = $customCallbackLogic
logoutFilter = io.buji.pac4j.filter.LogoutFilter
logoutFilter.localLogout = true
logoutFilter.centralLogout = true
logoutFilter.config = $config
logoutFilter.defaultUrl = http://localhost:9889/realms/zeppelin/protocol/openid-connect/logout
ajaxRequestResolver = org.pac4j.core.http.ajax.DefaultAjaxRequestResolver
ajaxRequestResolver.addRedirectionUrlAsHeader = true
keycloakOidcClient.ajaxRequestResolver = $ajaxRequestResolver
[urls]
/api/version = anon
/api/callback = callbackFilter
/api/login/logout = logoutFilter
/** = oidcSecurityFilter
如您所见,所有API请求都需要经过我配置中的oidcSecurityFilter。
正在使用的图书馆:
我希望 AJAX 请求能够准确无误地检索必要的数据,但它们却返回 null。这表明配置或通过 oidcSecurityFilter 处理 AJAX 请求的方式可能存在问题。
这是一个很奇怪的事情。看起来
redirectionActionBuilder
是 null
组件的 buildAjaxResponse
调用中的 DefaultAjaxRequestResolver
。不过,它应该在第一次使用时正确初始化。
错误发生前的
org.pac4j
DEBUG 日志是什么?