java Spring Security:多个 HTTP 配置不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33603156/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 21:54:09  来源:igfitidea点击:

Spring Security : Multiple HTTP Config not working

javaspringsecurityspring-mvcspring-security

提问by Mohan Singh

I am trying to use Spring Security and I have a use case where I want different login pages and different set of URLs to be secured.

我正在尝试使用 Spring Security,我有一个用例,我希望保护不同的登录页面和不同的 URL 集。

Here is my configuration:

这是我的配置:

@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");
    }
}

These classes are inner classes of another class MultipleHttpSecurityConfigthat has annotation @EnableWebSecurity.

这些类是另一个MultipleHttpSecurityConfig具有注解的类的内部类@EnableWebSecurity

The security for admin/**is working fine, but none of the consumer/**pages are secured, no redirection is happening for login page. I've searched for other answers but none worked.

的安全性admin/**工作正常,但没有任何consumer/**页面受到保护,登录页面没有发生重定向。我已经搜索了其他答案,但都没有奏效。

回答by dur

Look at the Spring Security Reference:

查看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 WebSecurityConfigurerAdapterthat contains @Orderto specify which WebSecurityConfigurerAdaptershould be considered first.

3 The http.antMatcherstates that this HttpSecuritywill 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 ApiWebSecurityConfigurationAdaptersince it has an @Ordervalue after 1(no @Orderdefaults to last).

@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应该首先考虑哪个。

3http.antMatcher声明这HttpSecurity仅适用于以/api/

4 创建 的另一个实例WebSecurityConfigurerAdapter。如果 URL 不是/api/以此配置开头,则将使用此配置。考虑此配置之后,ApiWebSecurityConfigurationAdapter因为它有一个@Order之后的值1(没有@Order默认为最后一个)。

Your second configuration is not used, because your first configuration matches /**(no antMatcherconfigured). And your first configuration restricts only /admin/**, all other URLs are permitted by default.

未使用您的第二个配置,因为您的第一个配置匹配/**(未antMatcher配置)。并且您的第一个配置仅限制/admin/**,默认情况下允许所有其他 URL。

回答by DiveInto

Your first WebSecurityConfigurerAdapter's

你的第一个WebSecurityConfigurerAdapter

http
            .authorizeRequests()

matches all the URLs, limit it to only URLs start with /adminby using antMatcher:

匹配所有的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()

                ...