在spring boot中使用多个WebSecurityConfigurerAdapter

Jan*_*yka 27 spring-security spring-boot

我有2个课程延伸WebSecurityConfigurerAdapter.并不能让他们一起工作.

这个想法如下:

  1. 有一个WebSecurityConfigurerAdapter只添加自定义过滤器到安全链.过滤器执行一些自定义身份验证并保存AuthenticationSecurityContext.这通常很好.配置如下(导入省略):
 @Order(1)
 @Configuration
 @EnableWebMvcSecurity
 public class BestSecurityConfig extends WebSecurityConfigurerAdapter {

     @Autowired
     private BestPreAuthenticationFilter ssoAuthenticationFilter;

     @Bean
     protected FilterRegistrationBean getSSOAuthenticationFilter() {
         FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(ssoAuthenticationFilter);

         // Avoid include to the default chain
         filterRegistrationBean.setEnabled(false);

         return filterRegistrationBean;
     }

     @Override
     protected void configure(HttpSecurity http) throws Exception {
         http
            .addFilterAfter(ssoAuthenticationFilter, SecurityContextPersistenceFilter.class);

     }

     @Configuration
     protected static class AuthenticationConfiguration extends
             GlobalAuthenticationConfigurerAdapter {

         @Autowired
         private BestAuthenticationProvider authenticationProvider;

         @Override
         public void configure(AuthenticationManagerBuilder auth) throws Exception {
             auth.authenticationProvider(authenticationProvider);
         }
     }
 }
Run Code Online (Sandbox Code Playgroud)
  1. 我希望以上是一种任何人都可以包含的库类,@ComponentScan并将自定义身份验证排序.显然,他们希望提供自定义HttpSecurity安全的edpoints.尝试类似的东西:
 @Configuration
 @EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
 @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
 public class SecurityConfig extends WebSecurityConfigurerAdapter {

     @Override
     protected void configure(HttpSecurity http) throws Exception {
         http
             .csrf().disable()
             .authorizeRequests()
             .antMatchers("/testUrl").hasRole("NON_EXISTING")
             .anyRequest().authenticated();
     }
 }
Run Code Online (Sandbox Code Playgroud)

显然,由于我的用户不是角色成员,因此不应该访问测试URL NON_EXISTING.不幸的是,她是.

如果我将安全性authorizeRequests()部分移动到配置类窗体1.在添加安全性过滤器之后,它会按预期阻止访问.但在我的情况下,它似乎忽略了第二个配置.

我也调试了这些configure()方法,并注意到它HttpSecurity不是同一个闻起来有点的对象.

任何提示我如何使这项工作非常受欢迎.

总结目标:

  • 有一个WebSecurityConfigurerAdapter添加过滤器并且对的用户隐藏
  • 让用户定义自己的自定义端点安全性

Spring boot 1.1.6-RELEASE

Jan*_*yka 14

所以我刚发现的一个选择是:

  1. @Configuration从第一个bean中删除注释

并将2.更改为:

 @Configuration
 @EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
 @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
 public class SecurityConfig extends BestSecurityConfig { //Note the changed extend !

     @Override
     protected void configure(HttpSecurity http) throws Exception {

         super.configure(http); // Merge of the 2 HTTP configurations

         http
             .csrf().disable()
             .authorizeRequests()
             .antMatchers("/testUrl").hasRole("NON_EXISTING")
             .anyRequest().authenticated();
     }
 }
Run Code Online (Sandbox Code Playgroud)

关于这是对还是错的任何评论都非常赞赏

编辑:几年后我仍然没有找到其他方式,但我越来越喜欢这种方式.即使在默认情况下,您扩展了抽象WebSecurityConfigurerAdapter,也没有理由为什么其他抽象层不能提供另一个提供有意义默认值的抽象扩展.

  • 是的,这就是我应该如何完成这样的任务吗?或者我应该以不同的方式使用它吗? (2认同)

Jul*_*ane 8

我(在我看来)创建了一种更简洁的方法来构建一些默认配置,并通过使用自定义DSL简化了在新项目中的集成.

我正在使用它来配置JWT身份验证过滤器,但我认为CORS过滤器更简单,更具说服力:

public class CustomCorsFilterDsl extends AbstractHttpConfigurer<CustomCorsFilterDsl, HttpSecurity> {

    @Override
    public void init(HttpSecurity http) throws Exception {
        //your init code here, no needed in this case
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        CorsFilter corsFilter = corsFilter(corsProperties);
        http.addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class);
    }

    private CorsFilter corsFilter(CorsProperties corsProperties) {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://localhost:9000");
        config.addAllowedHeader("*");
        config.addAllowedMethod("GET, POST, PUT, PATCH, DELETE");
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }

    public static CustomCorsFilterDsl dsl() {
        return new CustomCorsFilterDsl();
    }
}
Run Code Online (Sandbox Code Playgroud)

在您的WebSecurityConfig中,您可以像这样使用它:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .exceptionHandling()
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers("/foo/**").permitAll()
                //... your configurations
                .antMatchers("/**").authenticated()
                .and()
                .apply(CustomCorsFilterDsl.dsl());
    }
}
Run Code Online (Sandbox Code Playgroud)

并且您以更清晰的方式完成了使库具有独立于项目代码的默认配置的目标,因为您可以在项目的WebSecurityConfig中可视化自定义CORS条目.


eis*_*eis 8

定义一个特殊的接口

public interface ServiceWebSecurityConfigurer {
    void configure(HttpSecurity http) throws Exception;
}
Run Code Online (Sandbox Code Playgroud)

然后只有一个ConfigurerAdapter:

public class MyConfigurerAdapter extends WebSecurityConfigurerAdapter {

    @Autowired(required = false)
    ServiceWebSecurityConfigurer serviceSecConfig;

    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests(). // whatever

        if (serviceSecConfig != null) serviceSecConfig.configure(http);

        http.authorizeRequests(). // whatever
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在需要时在其他地方实现ServiceWebSecurityConfigurer。也可以有多种实现,只需将它们自动连接为列表,然后迭代并在主配置中使用它们即可。

  • 经过多年的尝试/错误/忘记这一点并再次找到它,我相信这是最好的答案。 (2认同)