Spring Security OAuth2:如何添加多个ResourceServerConfigurer类型的安全过滤器链?

aku*_*ma8 4 spring-security spring-boot spring-security-oauth2

我使用 Spring Security OAuth2 设置了一个 Spring Boot 多模块(5 个模块)应用程序。一切都运行良好,但随着应用程序的增长,我想将每个模块中的安全部分分开。主模块启用一切:

@SpringBootApplication
@EnableResourceServer
@EnableAuthorizationServer
@EnableWebSecurity(debug = true)
public class Application {  
  ...
}
Run Code Online (Sandbox Code Playgroud)

现在在每个模块中我定义了一个类型的beanResourceServerConfigurer

@Configuration
@Order(2)
public class Module1SecurityFilterChain extends ResourceServerConfigurerAdapter {

   @Override
   public void configure( HttpSecurity http ) throws Exception {
      http.sessionManagement().sessionCreationPolicy( STATELESS );
      http.antMatcher( "/module1/**")
            .authorizeRequests()
            .antMatchers( "/module1/resource").authenticated()
            .antMatchers( "/module1/test" ).authenticated()
            .anyRequest().access( "#oauth2.hasScope('webclient')" );
   }
}
Run Code Online (Sandbox Code Playgroud)

与 module2 相同:

@Configuration
@Order(1)
public class Module2SecurityFilterChain extends ResourceServerConfigurerAdapter {

   @Override
   public void configure( HttpSecurity http ) throws Exception {
      http.sessionManagement().sessionCreationPolicy( STATELESS );
      http.antMatcher( "/module2/**")
            .authorizeRequests()
            .antMatchers( "/module2/resource").authenticated()
            .antMatchers( "/module2/test" ).authenticated()
            .anyRequest().access( "#oauth2.hasScope('webclient')" );
   }
}
Run Code Online (Sandbox Code Playgroud)

等等...

问题是只有一个 FilterChain 被注册,即带有@Order(2). 我看了一下文档ResourceServerConfigurer它指出了这一点:

...如果多个配置相同的预操作,则最后一个获胜。配置器在应用之前按顺序排序

我怎样才能绕过这个限制?多谢。

编辑

这样做(扩展WebSecurityConfigurerAdapter而不是ResourceServerConfigurerAdapter):

@Configuration
@Order(1)
public class Module2SecurityFilterChain extends WebSecurityConfigurerAdapter {...}
Run Code Online (Sandbox Code Playgroud)

似乎注册了过滤器链,但还有另一个问题,当我验证用户身份(获取令牌/oauth/token)时,我无法访问受该链保护的资源,我得到了一个403 Forbidden. 这个黑匣子是如何工作的?

jzh*_*aux 5

您可以使用跨多个 bean 来配置多个匹配器,requestMatchers().antMatchers(String...)如下所示:

@Configuration
public class Module2SecurityFilterChain extends ResourceServerConfigurerAdapter {

   @Override
   public void configure(HttpSecurity http) throws Exception {
       http
           .requestMatchers()
               .antMatchers("/module2/**")
           .authorizeRequests()
               .antMatchers("/module2/resource").authenticated()
               .antMatchers("/module2/test").authenticated()
               .anyRequest().access("#oauth2.hasScope('webclient')");
   }
}
Run Code Online (Sandbox Code Playgroud)

这有点令人困惑,但是当您调用 时http.antMatcher(String),这表明您只想与该一个端点进行匹配。因此,调用它两次(一次在 中Module1SecurityFilterChain,然后再次在 中Module2SecurityFilterChain),第二次调用将覆盖第一次。

但是,usinghttp.requestMatchers().antMatchers(String)表示应该将给定String添加到已匹配的现有端点列表中。你可以把它想象antMatcher成有点像“ setMatcher”和antMatchers“像appendMatcher”。