应该将 JWT 中不存在的角色添加到 Authentication 对象的啥位置?

Posted

技术标签:

【中文标题】应该将 JWT 中不存在的角色添加到 Authentication 对象的啥位置?【英文标题】:Where should roles not existing in a JWT be added to an Authentication object?应该将 JWT 中不存在的角色添加到 Authentication 对象的什么位置? 【发布时间】:2021-05-19 12:46:51 【问题描述】:

我们有一个 Spring Boot 服务器,它使用 JWT 令牌对用户进行身份验证。应根据用户的身份为用户分配角色。

授予令牌的服务器不知道用户在每个系统中应该拥有什么角色,因此每个系统应该根据用户的身份授予角色。

类似:

    验证用户。 (用户已通过身份验证)查找用户拥有的角色并添加到安全上下文中的身份验证。 检查角色。例如,@PreAuthorize(hasRole('some_role'))

我的问题是:

我应该怎么做?或者,我不应该这样做并以其他方式处理这种情况吗?

【问题讨论】:

你正朝着正确的方向前进。每次对每个请求检查令牌时,始终从 db 获取用户角色数据。令牌提供用于获取用户数据的用户标识,然后创建会话用户对象,这反过来有助于创建安全上下文。是的,只要每个用户 ID 都有一个角色,您的 API 就会进行 @PreAuthorize(hasRole('role')) 检查。 现在关于如何在代码中完成所有这些,你将不得不学习更多关于 Spring Security 的知识 好吧,看来值得进一步研究这条赛道。现在我正在考虑提供 JwtAuthenticationProvider 的自定义版本。谢谢@BeshambherChaukhwan 【参考方案1】:

如前所述,JwtAuthenticationConverter 是预期的配置点。

Spring Security 会将其作为@Bean

@Bean
JwtAuthenticationConverter jwtAuthenticationConverter() 
    JwtAuthenticationConverter converter =
        new JwtAuthenticationConverter();
    converter.setJwtGrantedAuthoritiesConverter(...);
    return converter;

正如在另一个答案中已经指出的那样,您也可以在 DSL 上设置一个。

您可以在参考中阅读更多内容:https://docs.spring.io/spring-security/site/docs/5.4.4/reference/html5/#oauth2resourceserver-jwt-authorization-extraction

【讨论】:

【参考方案2】:

我找到了一种使用自定义jwtAuthenticationConverter 的方法。

  http
            ...
            ?.oauth2ResourceServer()
            ?.jwt()
            ?.jwtAuthenticationConverter(customConverter)
@Component
class CustomConverter(
    private val jwtGrantedAuthoritiesConverter: JwtGrantedAuthoritiesConverter
) : Converter<Jwt, AbstractAuthenticationToken> 

    override fun convert(jwt: Jwt): AbstractAuthenticationToken 
      // Custom logic that adds roles
    

【讨论】:

以上是关于应该将 JWT 中不存在的角色添加到 Authentication 对象的啥位置?的主要内容,如果未能解决你的问题,请参考以下文章

如果标头中不存在 JWT 令牌,如何执行一些逻辑?

Symfony 的分析器中不存在 lexik_jwt_authentication.on_jwt_created

Spring过滤器将角色添加到来自令牌的请求

无法检索用户角色

向从外部提供者检索到的 JWT 添加其他声明(例如角色)

数据库JWT中不存在用户?