如何使 Spring Boot 适配器中的 Keycloak 策略执行器与 vaadin 一起使用

Posted

技术标签:

【中文标题】如何使 Spring Boot 适配器中的 Keycloak 策略执行器与 vaadin 一起使用【英文标题】:How to make Keycloak policy enforcer in spring boot adapter work with vaadin 【发布时间】:2021-08-10 22:09:20 【问题描述】:

所以我有一个使用 vaadin (14) 和 keycloak 弹簧靴适配器 (11) 的应用程序。 我在此处查看了名为“app-authz-springboot”的spring boot的keycloaks授权示例:https://github.com/keycloak/keycloak-quickstarts/tree/latest/app-authz-springboot 当我执行该示例时,一切正常,但是当我将我的 vaadin 应用程序连接到示例中的 keycloak 实例并从同一示例的 spring 部分复制 application.properties 文件时,它无法设置策略执行配置。 它给了我错误信息:

Could not lazy load resource with path[/VAADIN/build/webcomponentsjs/webcomponents-loader.js] from server

使用堆栈跟踪:

    java.lang.RuntimeException: Could not find resource
    at org.keycloak.authorization.client.util.Throwables.retryAndWrapExceptionIfNecessary(Throwables.java:91) ~[keycloak-authz-client-11.0.2.jar:11.0.2]
    at org.keycloak.authorization.client.resource.ProtectedResource.find(ProtectedResource.java:232) ~[keycloak-authz-client-11.0.2.jar:11.0.2]
    at org.keycloak.authorization.client.resource.ProtectedResource.findByMatchingUri(ProtectedResource.java:291) ~[keycloak-authz-client-11.0.2.jar:11.0.2]
    at org.keycloak.adapters.authorization.PolicyEnforcer$PathConfigMatcher.matches(PolicyEnforcer.java:268) ~[keycloak-adapter-core-11.0.2.jar:11.0.2]
    at org.keycloak.adapters.authorization.AbstractPolicyEnforcer.getPathConfig(AbstractPolicyEnforcer.java:351) ~[keycloak-adapter-core-11.0.2.jar:11.0.2]
    at org.keycloak.adapters.authorization.AbstractPolicyEnforcer.authorize(AbstractPolicyEnforcer.java:72) ~[keycloak-adapter-core-11.0.2.jar:11.0.2]
    at org.keycloak.adapters.authorization.PolicyEnforcer.enforce(PolicyEnforcer.java:95) ~[keycloak-adapter-core-11.0.2.jar:11.0.2]
    at org.keycloak.adapters.AuthenticatedActionsHandler.isAuthorized(AuthenticatedActionsHandler.java:158) ~[keycloak-adapter-core-11.0.2.jar:11.0.2]
    at org.keycloak.adapters.AuthenticatedActionsHandler.handledRequest(AuthenticatedActionsHandler.java:60) ~[keycloak-adapter-core-11.0.2.jar:11.0.2]
    at org.keycloak.adapters.tomcat.AbstractAuthenticatedActionsValve.invoke(AbstractAuthenticatedActionsValve.java:62) ~[spring-boot-container-bundle-11.0.2.jar:11.0.2]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:667) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
    at org.keycloak.adapters.tomcat.AbstractKeycloakAuthenticatorValve.invoke(AbstractKeycloakAuthenticatorValve.java:181) ~[spring-boot-container-bundle-11.0.2.jar:11.0.2]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:888) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
    at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
Caused by: java.lang.RuntimeException: org.keycloak.jose.jws.JWSInputException: java.lang.NullPointerException
    at org.keycloak.authorization.client.util.TokenCallable.call(TokenCallable.java:75) ~[keycloak-authz-client-11.0.2.jar:11.0.2]
    at org.keycloak.authorization.client.resource.ProtectedResource.createFindRequest(ProtectedResource.java:296) ~[keycloak-authz-client-11.0.2.jar:11.0.2]
    at org.keycloak.authorization.client.resource.ProtectedResource.access$300(ProtectedResource.java:38) ~[keycloak-authz-client-11.0.2.jar:11.0.2]
    at org.keycloak.authorization.client.resource.ProtectedResource$5.call(ProtectedResource.java:225) ~[keycloak-authz-client-11.0.2.jar:11.0.2]
    at org.keycloak.authorization.client.resource.ProtectedResource$5.call(ProtectedResource.java:222) ~[keycloak-authz-client-11.0.2.jar:11.0.2]
    at org.keycloak.authorization.client.resource.ProtectedResource.find(ProtectedResource.java:230) ~[keycloak-authz-client-11.0.2.jar:11.0.2]
    ... 23 common frames omitted
Caused by: org.keycloak.jose.jws.JWSInputException: java.lang.NullPointerException
    at org.keycloak.jose.jws.JWSInput.<init>(JWSInput.java:58) ~[keycloak-core-11.0.2.jar:11.0.2]
    at org.keycloak.authorization.client.util.TokenCallable.call(TokenCallable.java:64) ~[keycloak-authz-client-11.0.2.jar:11.0.2]
    ... 28 common frames omitted
Caused by: java.lang.NullPointerException: null
    at org.keycloak.jose.jws.JWSInput.<init>(JWSInput.java:44) ~[keycloak-core-11.0.2.jar:11.0.2]
    ... 29 common frames omitted
2021-05-21 18:44:18.843 DEBUG 7662 --- [nio-8080-exec-7] o.k.a.a.AbstractPolicyEnforcer           : Checking permissions for path [http://localhost:8080/VAADIN/build/webcomponentsjs/webcomponents-loader.js] with config [null].

keycloak 配置为所有路径 /* 提供通配符授权,因此 keycloak 端应该没问题。实际上在它设法创建配置并授予访问权限之后不久

2021-05-21 18:44:18.880 DEBUG 7662 --- [nio-8080-exec-4] o.k.a.a.AbstractPolicyEnforcer           : Checking permissions for path [http://localhost:8080/VAADIN/build/vaadin-bundle-57fa80d1d948b96b39df.cache.js] with config [PathConfigname='Default Resource', type='null', path='/*', scopes=[], id='c050c28d-091b-404c-b683-45ee88743439', enforcerMode='ENFORCING'].
2021-05-21 18:44:18.880 DEBUG 7662 --- [nio-8080-exec-4] o.k.a.a.AbstractPolicyEnforcer           : Authorization GRANTED for path [PathConfigname='Default Resource', type='null', path='/*', scopes=[], id='c050c28d-091b-404c-b683-45ee88743439', enforcerMode='ENFORCING']. Permissions [[Permission id=fb71929b-fe28-4a4c-8879-a77793a6c49b, name=VAADIN, scopes=[], Permission id=c45caaa3-cde6-4ac7-9224-33412368f006, name=Protected Resource, scopes=[], Permission id=c050c28d-091b-404c-b683-45ee88743439, name=Default Resource, scopes=[]]].

所以错误必须在策略执行器配置的创建中的某个地方。 你能帮我找出错误在哪里吗? 这是我的 application.properties

server.port=$PORT:8080
vaadin.productionMode=false

logging.level.org.springframework.security=DEBUG
logging.level.org.keycloak.adapters.authorization=DEBUG

keycloak.enabled = true
keycloak.realm=spring-boot-quickstart
keycloak.auth-server-url=http://localhost:8180/auth
keycloak.ssl-required=external
keycloak.resource=app-authz-springboot
keycloak.public-client=false
keycloak.credentials.secret=secret
keycloak.security-constraints[0].authRoles[0]=user
keycloak.securityConstraints[0].securityCollections[0].name = protected
keycloak.security-constraints[0].securityCollections[0].patterns[0]=/*
keycloak.policy-enforcer-config.lazy-load-paths=true
keycloak.policy-enforcer-config.on-deny-redirect-to=/accessDenied

【问题讨论】:

【参考方案1】:

原来我使用的是版本 11 中的 keycloakd 适配器,而不是导致错误的最新版本 13。

【讨论】:

请在您有时间的时候将您的答案标记为已接受 :)

以上是关于如何使 Spring Boot 适配器中的 Keycloak 策略执行器与 vaadin 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Spring boot keycloak 适配器 + spring security 强制更新 oAuth 令牌(访问令牌 + 刷新令牌)。?

spring boot 结合啥前端框架

spring-boot redis:如何使用户的所有会话无效?

如何在 spring-boot 应用程序中配置多个 Keycloak sso 客户端?

403 spring-boot-2-keycloak-适配器

Spring Boot 中集成 Redis 作为数据缓存