首页 > 解决方案 > Spring Security 向所有端点添加过滤器,除了一个

问题描述

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

但是,我确实对此有补充问题:

我有一组过滤器,我想将其应用于所有请求,除了特殊情况(例如:除 /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)中的过滤器仍然会被应用 - 为什么会这样?

标签: springspring-bootspring-security

解决方案


如果我正确理解您的问题,您不希望应用过滤器,/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
       }

    }

推荐阅读