Spring Security将过滤器添加到所有Endpoint EXCEPT之一

时间:2018-08-27 12:28:03

标签: spring spring-boot spring-security

我对此进行了研究,并在SO上找到了这个Answer

但是我对此有补充问题:

我有一组过滤器,除了特殊情况(例如:除/ mgmt / **和/ error / **以外的所有路径),我希望将其应用于所有请求。

无法使用链接答案中介绍的相同方法来完成此操作,因为我会将过滤器添加到默认的http-security对象,然后将其也应用于特殊情况。

是否有类似“负匹配器”的内容,允许我做类似的事情:

http.negativeAntMatchers("/mgmt/**).addFilter(...)

为/ mgmt / **以外的所有内容添加过滤器?

我的代码:

这是“ / mgmt”的配置,将ManagementBasicAuthFilter放置在链中-这可行,因为除“ / mgmt / **”外没有其他端点要求基本身份验证。

@Order(1)
@Configuration
@RequiredArgsConstructor
public static class ManagementSecurityConfig extends WebSecurityConfigurerAdapter {

    private final AuthenticationManager authenticationManager;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
            http.antMatcher("mgmt/**")
                .csrf().disable()
                .headers().frameOptions().sameOrigin()
                .cacheControl().disable()
                .and()
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                    .addFilterBefore(new ManagementBasicAuthenticationFilter(authenticationManager,
                        getAuthenticationEntryPoint(), "/mgmt"), BasicAuthenticationFilter.class)
                    .authorizeRequests()
                    .anyRequest()
                    .permitAll();
    }

    private BasicAuthenticationEntryPoint getAuthenticationEntryPoint() {
        BasicAuthenticationEntryPoint entryPoint = new BasicAuthenticationEntryPoint();
        entryPoint.setRealmName("myApp");
        return entryPoint;
    }
}

这是所有入口点的配置,除了mgmt-此文件中的所有过滤器都不应应用于/ mgmt / **

@Order(2)
@Configuration
@RequiredArgsConstructor
@Import({ ResourceServerTokenServicesConfiguration.class })
@EnableOAuth2Client
public static class OAuthSecurityConfig extends WebSecurityConfigurerAdapter {

    private final OAuth2ClientContextFilter clientContextFilter;
    private final OAuth2ClientAuthenticationProcessingFilter ssoFilter;
    private final StatePropagatingLoginRedirectFilter statePropagatingLoginRedirectFilter;


    @Override
    public void configure(WebSecurity web) {
      web.ignoring().antMatchers("/mgmt/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .headers().frameOptions().sameOrigin()
                .cacheControl().disable()
                .and()
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                    .exceptionHandling()
                        .defaultAuthenticationEntryPointFor(
                            new LoginUrlAuthenticationEntryPoint("/login"),
                            request -> true)
                .and()
                .addFilterAfter(statePropagatingLoginRedirectFilter, AbstractPreAuthenticatedProcessingFilter.class)
                .addFilterAfter(ssoFilter, statePropagatingLoginRedirectFilter.getClass())
                .addFilterAfter(clientContextFilter, ssoFilter.getClass())
                .authorizeRequests()
                .anyRequest()
                .authenticated();
    }
}

当我请求例如:“ / mgmt / health”时,系统会提示我进行基本身份验证,但是登录后,(statePropagating,sso,clientContext)中的过滤器仍然适用-为什么会这样?

4 个答案:

答案 0 :(得分:2)

如果我对您的问题理解正确,那么您不希望将过滤器应用于/mgmt,那么您可以使用

    @Configuration
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {

       @Override
       public void configure(WebSecurity web) {
          // Overridden to exclude some url's 
          web.ignoring().antMatchers("/mgmt");
       }


       @Override
       protected void configure(HttpSecurity http) throws Exception {
        // configure the other url's as required
       }

    }

答案 1 :(得分:1)

您可以使用web.ignoring将spring安全性配置为忽略某些url模式 就您而言

web.ignoring().antMatchers("/mgmt/**");

答案 2 :(得分:1)

感谢kimhom和他的answer与Nicholas和eg78的结合,我弄清楚了-web.ignoring无法正常工作,原因是我想稍后进行调查-我忘了那个春天会自动将以Bean形式出现的所有过滤器添加到所有过滤器链。为防止这种情况,可以

  1. 不将过滤器注册为bean并在以下位置手动实例化它们 它们是必需的
  2. 为其中的过滤器添加FilterRegistrationBean     询问并为他们禁用注册,如下所示:

    @Bean
    public FilterRegistrationBean disableMyFilterBean(MyFilterBean filter) {
        FilterRegistrationBean registration = new FilterRegistrationBean(filter);
        registration.setEnabled(false);
        return registration;
    }
    

然后我的过滤器仅应用于我希望它们使用的位置-我什至不需要提供WebSecurity.ignoring匹配器

答案 3 :(得分:0)

您需要允许“ / mgmt / **”中的所有请求,并对其他请求进行身份验证,然后尝试类似的操作。

    http    
        .authorizeRequests()
                .antMatchers("**").hasAnyAuthority("ANY_AUTHORITY")
                .antMatchers("/mgmt/**").permitAll()
                .anyRequest().authenticated()