java - 如何根据http header过滤JWT认证权限

标签 java spring-boot spring-security jwt

基本上我想在 JWT token 被解析之后和方法被调用之前实现一个过滤器,能够根据 http header 修改身份验证对象

上下文

在我们的应用程序中,我们有(除其他外)三个与身份验证/授权相关的实体:用户、权限和组。权限可以直接分配给用户,也可以分配给用户所属的组之一。

鉴于此,JWT token 如下所示:

{
  "username": "duck",
  "groups": [
    {
      "name": "swimmer",
      "permissions": [
        "swim"
      ]
    },
    {
      "name": "walker",
      "permissions": [
        "walk"
      ]
    }
  ],
  "permissions": [
    "quack"
  ]
}

JWT 流程设置扩展 AuthorizationServerConfigurerAdapterResourceServerConfigurerAdapter ,并且通过扩展 DefaultUserAuthenticationConverter 从 JWT 声明映射中提取权限

通过使用 @EnableGlobalMethodSecurity(prePostEnabled = true)在配置中,我可以用 @PreAuthorize 注释方法

例如:

@PreAuthorize("hasPermission('quack')")
public void quack();

这适用于直接分配给用户的权限。

但是我想接收一个 http header ,例如:'x-group' 并将该组(如果有)的权限添加到身份验证对象

然后,给定上面的 'jwt' 并将 http header 设置为 swimmer我希望能够调用以下方法:

@PreAuthorize("hasPermission('swim')")
public void 

最佳答案

我知道您没有问过这个问题,但是从 header 建立额外的权限听起来有点冒险,除非您相信它的来源(例如,它是签名的或类似的)。这听起来很奇怪,因为使用 OAuth 的原因通常是只有授权服务器在颁发权限。

由于您已经在使用 DefaultUserAuthenticationConverter,我想知道您是否能够从后端获得那些相同的额外权限,比如通过 UserDetailsS​​ervice 的实例?

也就是说,要回答您的问题,您可以添加一个过滤器:

public class XGroupFilter extends OncePerRequestFilter {
    // ... look up current Authentication
    // ... look up and validate header
    // ... create new instance of Authentication, adding the new authorities
}

然后注册它:

@Configuration
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    @Override
    public void configure(HttpSecurity http) {
        // ...

        http.addFilterAfter(new XGroupFilter(), OAuth2AuthenticationProcessingFilter.class);
    }
}

或者,如果您可以选择升级,则有 new support as of Spring Security 5.1这简化了一些事情。您现在使用的是一个名为 Spring Security OAuth 的遗留插件项目,但现在支持 built in natively .此外,这也是新功能的发展方向,如果您还没有在 Spring Security OAuth 道路上走得太远,那么从那里开始很有值(value)。

那样的话,配置还是很相似的:

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) {
        // ...

        http.addFilterAfter(new XGroupFilter(), BearerTokenAuthenticationFilter.class);
    }
}

关于java - 如何根据http header过滤JWT认证权限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54811415/

相关文章:

java - 重置 PostgreSQL 中的序列

java - spring认证管理器不绑定(bind)@Service注解的用户服务

toString() 的 Java 值不打印

java - 可绘制动画结束时进入新 Activity

java - Struts2 如果标签不起作用

java - 无法构建具有从 jndi 查找数据源的 Spring Boot 项目

java - 如何修复 java.lang.UnsupportedClassVersionError?

java - 如何正确地将 2 列映射到同一实体

grails - Grails:从BootStrapDevelopment调用权限 protected Service方法

Grails 1.3.5 和 Spring Security Core