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) по-прежнему применяются - почему это?

2
0
4 059
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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

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

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

    }

спасибо, я попробую это - до сих пор я использовал только HttpSecurity-config

billdoor 27.08.2018 14:58

хорошо, я вошел в систему, не осознавая, когда это сработало, поэтому я принял ответ, когда на самом деле проблема не была решена, я добавлю детали к вопросу

billdoor 28.08.2018 08:29

Вы не можете изменить вопрос сейчас, вам нужно будет задать другой.

Nicholas K 28.08.2018 08:31

это тот же вопрос, я только что добавил код, так как ваш ответ не решил проблему, и я подумал, что, скорее всего, требуется дополнительная информация

billdoor 28.08.2018 08:57

Я понял это, выполнив поиск случаев, когда ваш ответ не помогает - поэтому я хочу отдать должное там, где это необходимо, а не просто принять свой собственный ответ, как если бы я понял это сам

billdoor 28.08.2018 09:14

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

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

web - это элемент конфигурации WebSecurity. Во всяком случае, Николай К. написал лучший ответ.

e.g78 28.08.2018 15:02
Ответ принят как подходящий

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

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

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

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

Другие вопросы по теме