【发布时间】:2018-04-22 07:02:27
【问题描述】:
首先我正在使用
- keycloak-authz-client-3.3.0.Final
- spring boot 1.5.8.RELEASE
- spring-boot-starter-security
我一直在使用 Keycloak 弹簧适配器探索示例,因为我们想将它应用到我们的项目中。
使用本教程,我能够轻松地为角色运行它: https://dzone.com/articles/easily-secure-your-spring-boot-applications-with-k
在那之后,我转移到了权限,这就是它变得更加棘手的时候(这也是我们的主要目标)。
我想实现此处 (9.1.2) 中描述的内容: http://www.keycloak.org/docs/2.4/authorization_services_guide/topics/enforcer/authorization-context.html#
要获得权限,您需要在 Keycloak 授权、凭据中进行设置,然后创建资源或范围和策略才能创建权限(我花了一段时间,但我得到了它的工作)。在 Evaluator 中测试一切似乎都很好。
下一步是在 Spring 端获取用户权限。为此,我必须启用: keycloak.policy-enforcer-config.enforcement-mode=permissive
当我启用它的那一刻,我每次都会得到这个异常
java.lang.RuntimeException: Could not find resource.
at org.keycloak.authorization.client.resource.ProtectedResource.findAll(ProtectedResource.java:88)
at org.keycloak.adapters.authorization.PolicyEnforcer.configureAllPathsForResourceServer...
...
Caused by: org.keycloak.authorization.client.util.HttpResponseException:
Unexpected response from server: 403 / Forbidden
无论我在服务器中点击什么地址。
于是我开始调查问题的根源。查看一些示例如何手动获取权限,我实际上通过以下请求在邮递员中获得了权限: http://localhost:8080/auth/realms/${myKeycloakRealm}/authz/entitlement/${MyKeycloakClient} 包括标题授权:承载 ${accessToken} 响应是实际包含权限的 {"rpt": ${jwt token}}
所以知道这是正常工作,肯定是 Spring 适配器有问题。进一步调查 Keycloak 异常,我发现在适配器获取所有资源时发生了该错误。为此,它使用了以下网址: http://localhost:28080/auth/realms/license/authz/protection/resource_set 标头中有不同的标记(我在调试时复制) 因此,当我在邮递员中尝试时,我也遇到了 403 错误,但带有 json 正文:
{ “错误”:“无效范围”, "error_description": "需要 uma_protection 范围。" }
我已启用和禁用 keycloak 中的所有 uma 配置,但我无法使其工作。请有人指出我正确的方向吗?
更新
我现在已将 Keycloak 适配器更新为 3.4.0.final,我在 UI 中收到以下错误:
2017 年 11 月 20 日星期一 10:09:21 GMT 出现意外错误(类型=内部服务器错误,状态=500)。 找不到资源。服务器消息:{"error":"invalid_scope","error_description":"Requires uma_protection scope."}
(和我在邮递员请求中得到的差不多)
我还打印了所有用户角色,以确保 uma_protection 角色存在,确实存在。
我做的另一件事是禁用 spring 安全角色前缀以确保它不是角色不匹配。
更新 2
能够解决 403 问题(您可以在下面的回复中看到它)。 从 HttpServletRequest 获取 KeycloakSecurityContext 仍然遇到问题
更新 3
能够像这样获得 KeycloakSecurityContext:
Principal principal = servletRequest.getUserPrincipal();
KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) principal;
OidcKeycloakAccount auth = token.getAccount();
KeycloakSecurityContext keycloakSecurityContext = auth.getKeycloakSecurityContext();
AuthorizationContext authzContext = keycloakSecurityContext.getAuthorizationContext();
现在的问题是 AuthorizationContext 始终为空。
【问题讨论】:
-
嗨@Luis Perdigao,我也在尝试获得具有权限的spring boot,但就我而言,我也没有获得localhost:8080/auth/realms/${myKeycloakRealm}/authz/entitlement/${MyKeycloakClient 中的权限} 称呼。我创建了一个资源和一个基于 js 的策略并添加了权限。该策略在用户中寻找一个属性,如果这是真的,那么它就被授予了。在 rpt 令牌中,我没有看到属性或权限,你知道我们如何才能做到这一点
-
如果权限设置给该用户,您应该可以在那里看到它。转到 keycloak 授权选项卡 -> 评估并测试您应该在其中拥有的权限。如果这没有帮助,请尝试添加更多通用权限并查看它们是否出现在请求中
-
我能够使用 ABAC 运行快速入门 REST Spring 启动应用程序之一。我想知道您是否能够使其与策略执行器一起使用或不使用它。我的问题基本上是总是需要策略执行器,因为如果我们有,它总是调用 Keycloak 服务器来验证我们希望尽可能避免每次调用
-
没有。如果您想要由应用程序(即授权)处理的角色或特权,您只需要策略执行器。并非每次调用都调用 Keycloak。如果我没记错的话,只要您设置访问令牌的有效性,它将避免另一个调用。
-
谢谢。它不会在每个请求上调用 keycloak 服务器
标签: spring-boot spring-security authorization privileges keycloak