Spring Keycloak适配器权限策略强制实施器。如何设置

时间:2017-11-09 10:18:55

标签: spring-boot spring-security authorization privileges keycloak

首先我使用

  • keycloak-authz-client-3.3.0.Final
  • spring boot 1.5.8.RELEASE
  • 弹簧引导起动的安全性

我一直在玩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授权,凭据中设置权限,然后创建资源或范围和策略以便能够创建权限(我花了一段时间,但我得到了它的工作)。在Evaluater中测试一切似乎都很好。

  • 下一步是获取Spring方面的用户权限。为了做到这一点,我必须启用: keycloak.policy-实施者-config.enforcement模式=容许

我启用此功能的那一刻,我每次都会遇到此异常

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

无论我在服务器上找到什么地址。

  • 所以我开始调查问题的根源是什么。查看一些示例如何手动获取权限,我实际上在postman中使用以下请求获取它们: http://localhost:8080/auth/realms/ $ {myKeycloakRealm} / AuthZ的/授权/ $ {MyKeycloakClient} 包括标题授权:bearer $ {accessToken} 响应是{" rpt":$ {jwt token}}实际上包含权限

  • 因此,知道这是有效的,它必须是Spring适配器的错误。对Keycloak异常进行了进一步研究,我发现在适配器获取所有资源的那一刻就发生了错误。为此,它使用以下网址: http://localhost:28080/auth/realms/license/authz/protection/resource_set 在标题中使用不同的标记(我在调试时复制) 因此,当我在邮递员中尝试时,我也遇到了403错误,但是有一个json身体:

{     "错误":" invalid_scope",     " error_description":"需要uma_protection范围。" }

我已经启用并禁用了keycloak中的所有uma配置,但我无法使其正常工作。可以请某人指出我正确的方向吗?

更新

我现在已将Keycloak适配器更新到3.4.0.final,并且我在UI中收到以下错误:

Mon 11月20日10:09:21 GMT 2017 出现意外错误(type = Internal Server Error,status = 500)。 找不到资源。服务器消息:{"错误":" invalid_scope"," error_description":"需要uma_protection范围。"}

(我在邮递员的要求中几乎一样)

我还打印了所有用户角色,以确保uma_protection角色存在,并且确实存在。

我做的另一件事是禁用弹簧安全角色前缀,以确保它不会与角色不匹配。

更新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 始终为空。

2 个答案:

答案 0 :(得分:1)

我已成功通过将uma_protection角色添加到Keycloak客户端配置中的服务帐户角色标签

来使其正常运行

Here's the place where it is in Keycloak

有关它的更多信息: http://www.keycloak.org/docs/2.0/authorization_services_guide/topics/service/protection/whatis-obtain-pat.html

解决方案的第二部分:

即使它们对您没有多大意义,也必须具备安全约束。例如:

keycloak.securityConstraints[0].authRoles[0] = ROLE1
keycloak.securityConstraints[0].securityCollections[0].name = protected
keycloak.securityConstraints[0].securityCollections[0].patterns[0] = /*

有用的演示: https://github.com/keycloak/keycloak-quickstarts

答案 1 :(得分:0)

此代码对我有用:

HttpServletRequest request = ...; // obtain javax.servlet.http.HttpServletRequest
Principal userPrincipal = request.getUserPrincipal();
KeycloakPrincipal < KeycloakSecurityContext > keycloakPrincipal =
  (KeycloakPrincipal < KeycloakSecurityContext > ) userPrincipal;
KeycloakSecurityContext securityContext =
  keycloakPrincipal.getKeycloakSecurityContext();