将Keycloak Realm角色Map到Spring权限不起作用

kxe2p93d  于 2023-03-23  发布在  Spring
关注(0)|答案(1)|浏览(263)

我在Kolin中使用spring-boot-starter-oauth2-resource-server创建了一个Sping Boot 应用程序(3.0.2)和spring-boot-starter-oauth2-client(3.0.2)包来使用OIDC验证我的用户。用于在Keycloak中Map我的用户的领域角色(21.0.1)我已经示例化了一个应该是setAuthoritiesClaimName("roles")JwtAuthenticationConverter。它在OAuth2ResourceServerConfigurer中正确加载,但是GrantedAuthorities仍然被设置为scopes,并且我的JwtAuthenticationConverter lambda没有被调用。
过滤器链的重要组成部分:

http.oauth2Login()
    ...
    .oauth2ResourceServer().jwt()
    .jwtAuthenticationConverter(jwtAuthenticationConverter()) // my fun

花了很多时间进行调试,我发现实际上调用了OidcAuthorizationCodeAuthenticationProviderauthoritiesMapper并处理权限的Map。然而,我不确定为什么在Baeldung中解释的方法对我不起作用。
你知道我哪里做错了吗?
先谢了!

pgky5nke

pgky5nke1#

OAuth2资源服务器的职责和安全需求与客户端的职责和安全需求差异太大,无法站在同一个安全过滤器链中。
Spring为这两个提供了不同的启动器,这是有原因的:

  • 资源服务器通常是无状态的(没有会话),当客户端安全性基于会话时,它们的安全性依赖于访问令牌(没有它,您甚至无法完成授权代码流)
  • 使用的Authentication实现是不一样的,安全上下文的构建/恢复方式也是完全不同的:一方面是访问令牌自检或JWT解码,另一方面是会话
  • 用于获取访问令牌的OAuth2流与资源服务器无关,它所关心的只是访问令牌是否有效,如何从中获取声明(内省或JWT解码),并根据这些声明做出访问决策
  • 客户端负责授权对资源服务器的请求:设置一个访问令牌作为Authorization头。为了获取这个令牌,它需要处理OAuth2流(包括授权代码和OAuth2登录)。

由于登录是客户端业务,通过在安全过滤器链中配置oauth2Login(),它成为客户端过滤器链,并且您在下面配置的关于JWT的内容基本上没有效果(查看浏览器调试工具,您会发现会话cookie但没有JWT访问令牌,即使在登录后)。
如果你的应用程序是一个REST API,它就是一个资源服务器。删除oauth2Login(),它在那里没有任何作用。使用像Postman这样的REST客户端,而不是你的浏览器,它开箱即用,不知道如何授权OAuth2请求和发送GET请求以外的任何东西。
如果应用程序在服务器上呈现UI模板(Thymeleaf、JSF等),则它是一个客户端,并通过会话进行保护。保留oauth2Login(),但删除oauth2ResourceServer(),并参考文档了解客户端权限Map
如果您的应用程序公开了REST API和服务器端呈现的UI来操作它,那么使用securityMatcher定义两个安全过滤器链bean来限制@Order中的第一个应用的路由。
所有这些都在我的教程中详细介绍:https://github.com/ch4mpy/spring-addons/tree/master/samples/tutorials

相关问题