Spring Security: несколько HTTP-конфигураций не работают

#spring-security

#java #spring #Безопасность #spring-mvc #spring-безопасность

Вопрос:

Я пытаюсь использовать Spring Security, и у меня есть вариант использования, когда я хочу, чтобы были защищены разные страницы входа и другой набор URL-адресов.

Вот моя конфигурация:

 @Configuration
@Order(1)
public static class ProviderSecurity extends WebSecurityConfigurerAdapter{
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/", "/home").permitAll()
                .antMatchers("/admin/login").permitAll()
                .antMatchers("/admin/**").access("hasRole('BASE_USER')")
                .and()
            .formLogin()
                .loginPage("/admin/login").permitAll()
                .defaultSuccessUrl("/admin/home")
                .failureUrl("/admin/login?error=true").permitAll()
                .usernameParameter("username")
                .passwordParameter("password")
                .and()
            .csrf()                    
                .and()
            .exceptionHandling().accessDeniedPage("/Access_Denied");            
    }
}


@Configuration
@Order(2)
public static class ConsumerSecurity extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/consumer/login").permitAll()
                .antMatchers("/consumer/**").access("hasRole('BASE_USER')")
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/consumer/login").permitAll()
                .defaultSuccessUrl("/consumer/home")
                .failureUrl("/consumer/login?error=true").permitAll()
                .usernameParameter("username")
                .passwordParameter("password")
                .and().csrf()                
                .and()
            .exceptionHandling().accessDeniedPage("/Access_Denied");
    }
}
  

Эти классы являются внутренними классами другого класса, MultipleHttpSecurityConfig который имеет аннотацию @EnableWebSecurity .

Защита для admin/** работает нормально, но ни одна из consumer/** страниц не защищена, перенаправление страницы входа не происходит. Я искал другие ответы, но ни один из них не сработал.

Ответ №1:

Посмотрите на Spring Security Reference:

 @EnableWebSecurity
public class MultiHttpSecurityConfig {
  @Autowired
  public void configureGlobal(AuthenticationManagerBuilder auth) { 1
      auth
          .inMemoryAuthentication()
              .withUser("user").password("password").roles("USER").and()
              .withUser("admin").password("password").roles("USER", "ADMIN");
  }

  @Configuration
  @Order(1)                                                        2
  public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
      protected void configure(HttpSecurity http) throws Exception {
          http
              .antMatcher("/api/**")                               3
              .authorizeRequests()
                  .anyRequest().hasRole("ADMIN")
                  .and()
              .httpBasic();
      }
  }    

  @Configuration                                                   4
  public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

      @Override
      protected void configure(HttpSecurity http) throws Exception {
          http
              .authorizeRequests()
                  .anyRequest().authenticated()
                  .and()
              .formLogin();
      }
  }
}
  

1 Настройте аутентификацию как обычно

2 Создайте экземпляр, WebSecurityConfigurerAdapter который содержит @Order , чтобы указать, что WebSecurityConfigurerAdapter следует рассматривать в первую очередь.

3 http.antMatcher Указано, что это HttpSecurity будет применимо только к URL-адресам, начинающимся с /api/

4 Создайте другой экземпляр WebSecurityConfigurerAdapter . Если URL-адрес не начинается с /api/ , будет использоваться эта конфигурация. Эта конфигурация рассматривается после, ApiWebSecurityConfigurationAdapter поскольку она имеет @Order значение после 1 (значение по @Order умолчанию не является последним).

Ваша вторая конфигурация не используется, потому что ваша первая конфигурация соответствует /** (не antMatcher настроена). И ваша первая конфигурация ограничивает только /admin/** , все остальные URL-адреса разрешены по умолчанию.

Комментарии:

1.Другими словами, вы можете указать несколько WebSecurityConfigurerAdapter ов, которые рассматриваются в порядке приоритета, указанного в @Order аннотации. Используется первая, которая соответствует .requestMatchers().antMatchers("/matcher/**") , а другие отбрасываются. ie, WebSecurityConfigurerAdapter s не складываются.

Ответ №2:

Ваш первый WebSecurityConfigurerAdapter

 http
            .authorizeRequests()
  

соответствует всем URL-адресам, ограничьте его только URL-адресами, начинающимися с /admin с помощью antMatcher :

 @Configuration
@Order(1)
public static class ProviderSecurity extends WebSecurityConfigurerAdapter{
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .antMatcher("/admin/**")
                .authorizeRequests()
                .antMatchers("/admin/login").permitAll()
                .antMatchers("/admin/**").access("hasRole('BASE_USER')")
                .and()

                ...