Spring Security добавить фильтр на все конечные точки, кроме одного - PullRequest
0 голосов
/ 27 августа 2018

Я исследовал это и нашел этот Ответ на 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;
    }
}

Это конфигурация для всех точек входа, КРОМЕ мгмт - все фильтры в этом файле НЕ должны применяться к / мгмт / **

@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 голосов
/ 28 августа 2018

благодаря Кимхому и его ответу в сочетании с Николасом и eg78 я понял - web.ignoring не работает, по причинам, которые я хочу исследовать позже - я забыл о том, что весна будетавтоматически добавлять все фильтры, представленные в виде Beans, во все цепочки фильтров.Чтобы предотвратить это, можно либо

  1. не регистрировать фильтры в виде bean-компонентов и создавать их вручную, где они необходимы
  2. добавить FilterRegistrationBean для рассматриваемых фильтров и отключить регистрацию дляони вот так:

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

Тогда мои фильтры применяются только там, где я хочу - мне даже не нужно предоставлять WebSecurity.ignoring совпадений

0 голосов
/ 27 августа 2018

Если я правильно понимаю ваш вопрос, вы не хотите, чтобы фильтр применялся к /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
       }

    }
0 голосов
/ 27 августа 2018

Вы можете настроить Spring Security, чтобы игнорировать некоторые шаблоны URL, используя web.ignoring. В вашем случае

web.ignoring().antMatchers("/mgmt/**");
0 голосов
/ 27 августа 2018

Вам нужно будет разрешить все запросы в "/ mgmt / **" и сделать другие запросы аутентифицированными, попробуйте что-нибудь подобное.

    http    
        .authorizeRequests()
                .antMatchers("**").hasAnyAuthority("ANY_AUTHORITY")
                .antMatchers("/mgmt/**").permitAll()
                .anyRequest().authenticated()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...