Spring Keycloak 适配器权限策略执行器。如何设置
Spring Keycloak adapter Permissions Policy Enforcer. How to set it up
首先我用的是
- keycloak-authz-client-3.3.0.Final
- spring 引导 1.5.8.RELEASE
- spring-boot-starter-security
我一直在使用 Keycloak spring 适配器探索示例,因为我们想将它应用到我们的项目中。
我能够使用本教程轻松地为角色 运行 制作它:
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-enforcer-config.enforcement-mode=宽容
我启用它的那一刻我每次都会得到这个异常
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}
包括 header 授权:不记名 ${accessToken}
响应是 {"rpt": ${jwt token}} 实际上包含权限
所以知道这是有效的,一定是 Spring 适配器出了问题。进一步调查 Keycloak 异常,我发现该错误是在适配器获取所有资源时发生的。为此,它使用了以下 url:
http://localhost:28080/auth/realms/license/authz/protection/resource_set
在 headers 中使用不同的标记(我在调试时复制的)
因此,当我在邮递员中尝试时,我也遇到了 403 错误,但是 json body:
{
"error": "invalid_scope",
"error_description": "Requires uma_protection scope."
}
我已经在 keycloak 中启用和禁用了所有 uma 配置,但我无法让它工作。请有人指出我正确的方向吗?
更新
我现在已将 Keycloak 适配器更新到 3.4。0.final 我在 UI 中收到以下错误:
11 月 20 日星期一 10:09:21 格林威治标准时间 2017
出现意外错误(类型=内部服务器错误,状态=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 始终为空。
我已经通过将 uma_protection 角色添加到 Keycloak 客户端配置中的 服务帐户角色选项卡来使其正常工作
解决方案的第二部分:
设置安全限制是强制性的,即使它们对您来说意义不大。示例:
keycloak.securityConstraints[0].authRoles[0] = ROLE1
keycloak.securityConstraints[0].securityCollections[0].name = protected
keycloak.securityConstraints[0].securityCollections[0].patterns[0] = /*
这段代码对我有用:
HttpServletRequest request = ...; // obtain javax.servlet.http.HttpServletRequest
Principal userPrincipal = request.getUserPrincipal();
KeycloakPrincipal < KeycloakSecurityContext > keycloakPrincipal =
(KeycloakPrincipal < KeycloakSecurityContext > ) userPrincipal;
KeycloakSecurityContext securityContext =
keycloakPrincipal.getKeycloakSecurityContext();
如果您遇到“java.lang.RuntimeException: 找不到资源”错误并且您正在使用 Keycloak docker 容器,则可能是因为这个错误。我没有关于 docker 的足够信息。因此,我将 keycloak 下载为 zip 文件并 运行 它。它工作正常。
首先我用的是
- keycloak-authz-client-3.3.0.Final
- spring 引导 1.5.8.RELEASE
- spring-boot-starter-security
我一直在使用 Keycloak spring 适配器探索示例,因为我们想将它应用到我们的项目中。
我能够使用本教程轻松地为角色 运行 制作它: 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-enforcer-config.enforcement-mode=宽容
我启用它的那一刻我每次都会得到这个异常
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} 包括 header 授权:不记名 ${accessToken} 响应是 {"rpt": ${jwt token}} 实际上包含权限
所以知道这是有效的,一定是 Spring 适配器出了问题。进一步调查 Keycloak 异常,我发现该错误是在适配器获取所有资源时发生的。为此,它使用了以下 url: http://localhost:28080/auth/realms/license/authz/protection/resource_set 在 headers 中使用不同的标记(我在调试时复制的) 因此,当我在邮递员中尝试时,我也遇到了 403 错误,但是 json body:
{ "error": "invalid_scope", "error_description": "Requires uma_protection scope." }
我已经在 keycloak 中启用和禁用了所有 uma 配置,但我无法让它工作。请有人指出我正确的方向吗?
更新
我现在已将 Keycloak 适配器更新到 3.4。0.final 我在 UI 中收到以下错误:
11 月 20 日星期一 10:09:21 格林威治标准时间 2017 出现意外错误(类型=内部服务器错误,状态=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 始终为空。
我已经通过将 uma_protection 角色添加到 Keycloak 客户端配置中的 服务帐户角色选项卡来使其正常工作
解决方案的第二部分:
设置安全限制是强制性的,即使它们对您来说意义不大。示例:
keycloak.securityConstraints[0].authRoles[0] = ROLE1
keycloak.securityConstraints[0].securityCollections[0].name = protected
keycloak.securityConstraints[0].securityCollections[0].patterns[0] = /*
这段代码对我有用:
HttpServletRequest request = ...; // obtain javax.servlet.http.HttpServletRequest
Principal userPrincipal = request.getUserPrincipal();
KeycloakPrincipal < KeycloakSecurityContext > keycloakPrincipal =
(KeycloakPrincipal < KeycloakSecurityContext > ) userPrincipal;
KeycloakSecurityContext securityContext =
keycloakPrincipal.getKeycloakSecurityContext();
如果您遇到“java.lang.RuntimeException: 找不到资源”错误并且您正在使用 Keycloak docker 容器,则可能是因为这个错误。我没有关于 docker 的足够信息。因此,我将 keycloak 下载为 zip 文件并 运行 它。它工作正常。