Spring Security: 多个HTTP配置无法工作

26

我正在尝试使用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");
    }
}

这些类是另一个带有注释@EnableWebSecurity的类 MultipleHttpSecurityConfig 的内部类。

admin / **的安全性很好,但是consumer / **页面没有受到保护,没有重定向到登录页面。我已经搜索了其他答案,但都没有起作用。

2个回答

32
看一下 Spring Security 参考文档:
@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 Configure Authentication as normal

2 Create an instance of WebSecurityConfigurerAdapter that contains @Order to specify which WebSecurityConfigurerAdapter should be considered first.

3 The http.antMatcher states that this HttpSecurity will only be applicable to URLs that start with /api/

4 Create another instance of WebSecurityConfigurerAdapter. If the URL does not start with /api/ this configuration will be used. This configuration is considered after ApiWebSecurityConfigurationAdapter since it has an @Order value after 1 (no @Order defaults to last).

您的第二个配置未被使用,因为第一个配置匹配了 /** (没有配置 antMatcher)。而您的第一个配置仅限制了 /admin/**,所有其他URL默认允许访问。


1
换句话说,您可以指定多个WebSecurityConfigurerAdapter,这些适配器按照@Order注释中指定的优先级顺序进行考虑。 首先匹配 .requestMatchers().antMatchers("/matcher/**") 的适配器被使用,其他适配器被丢弃。也就是说,WebSecurityConfigurerAdapter不会堆叠。 - maricn

27

您的第一个WebSecurityConfigurerAdapter

http
            .authorizeRequests()

使用antMatcher,将匹配所有URL的限制为仅匹配以/admin开头的URL:

@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()

                ...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接