2

Basically I want to implement a filter after the JWT token is parsed and before the method is called with the ability to modify the authentication object based on an http header

Context

In our application we have (among others) three entities related to authentication/authorization: Users, Permissions and Groups. Permissions can be directly assigned to an user or could be assigned to one of the groups a user belongs to.

Given this a JWT token looks like this:

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

The JWT flow is setup extending AuthorizationServerConfigurerAdapter and ResourceServerConfigurerAdapter, and the permissions are extracted from the map of JWT claims by extending DefaultUserAuthenticationConverter

By using @EnableGlobalMethodSecurity(prePostEnabled = true) in the configuration I am able to annotate methods with @PreAuthorize

For example:

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

This works with permissions directly assigned to the user.

However I want to receive an http header e.g: 'x-group' and add permissions from that group (if any) to the authentication object

Then, given the above 'jwt' with the http header set to swimmer I want to be able to invoke the following method:

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

1 回答 1

0

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

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

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

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);
    }
}

或者,如果您可以选择升级,那么从 Spring Security 5.1 开始提供新的支持,这会稍微简化一些事情。您现在使用的是一个名为 Spring Security OAuth 的遗留插件项目,但现在原生内置了支持。此外,这也是新功能的发展方向,如果您还没有在 Spring Security OAuth 道路上走得太远,那么从那里开始就很有价值。

在那种情况下,配置仍然非常相似:

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

        http.addFilterAfter(new XGroupFilter(), BearerTokenAuthenticationFilter.class);
    }
}
于 2019-02-21T19:31:12.507 回答