【问题标题】:Spring Security OAuth2: how to add multiple Security Filter Chain of type ResourceServerConfigurer?Spring Security OAuth2:如何添加多个 ResourceServerConfigurer 类型的安全过滤器链?
【发布时间】:2019-05-28 16:52:02
【问题描述】:

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

@SpringBootApplication
@EnableResourceServer
@EnableAuthorizationServer
@EnableWebSecurity(debug = true)
public class Application {  
  ...
}

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

@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')" );
   }
}

与模块 2 相同:

@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')" );
   }
}

等等……

问题是只注册了一个FilterChain,即@Order(2)。我查看了ResourceServerConfigurerdoc 并指出:

...如果不止一个配置相同的preoperty,那么最后一个获胜。配置器在应用前按顺序排序

如何才能绕过此限制? 非常感谢。

编辑

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

@Configuration
@Order(1)
public class Module2SecurityFilterChain extends WebSecurityConfigurerAdapter {...}

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

【问题讨论】:

    标签: spring-boot spring-security spring-security-oauth2


    【解决方案1】:

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

    @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')");
       }
    }
    

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

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

    【讨论】:

    • 感谢回复,我想试试你的建议但是http.requestMatchers().antMatchers(String)之后没有authorizeRequests()的方法
    • 我接受响应(在编辑它以添加 and() 方法 ^^ 之后)即使它不完全是我想要的,但目标似乎是相同的。事实上,我想定义多个 FilterChain 但你回答,只有一个映射到所有模块的请求。就像每个模块的安全配置是分开的一样,它也是一个不错的选择。 Spring Security 一点也不容易理解,一个真正的黑匣子。再次感谢您的回答
    • 另一个问题,为什么WebSecurityConfigurerAdapter 没有这种行为?我的意思是,为什么它的 http.antMatcher(String) 创建了另一个 FilterChain 而没有覆盖其他的?
    • 我有另一个与此解决方案相关的问题,请参阅此处:stackoverflow.com/q/54030887/6643803
    猜你喜欢
    • 2016-04-20
    • 1970-01-01
    • 2020-02-08
    • 1970-01-01
    • 2019-04-13
    • 2022-01-14
    • 2016-05-07
    • 1970-01-01
    • 2015-12-04
    相关资源
    最近更新 更多