8

В соответствии с Spring Security Reference section 5.7 должно быть возможно определить более одного адаптера безопасности.Использование нескольких WebSecurityConfigurerAdapter с различными AuthenticationProviders (базовый auth для API и LDAP для веб-приложения)

Я стараюсь делать то же самое, но безуспешно. После перезагрузки сервера первый раз x API отлично работает с базовым auth, но через пару раз я перенаправлен на страницу входа (формы), это должно произойти только для нашего веб-приложения, а не для вызовов API.

Мой код:

@EnableWebSecurity 
public class MultiHttpSecurityConfig { 

    @Configuration 
    @Order(1) 
    public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { 

     @Autowired 
     private Environment env; 

     @Autowired 
     public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
      auth.inMemoryAuthentication(). 
       withUser("admin").password("pw_test").roles(API_ROLE); 
     } 

     protected void configure(HttpSecurity http) throws Exception { 
      http 
       .antMatcher("/services/**") 
       .authorizeRequests() 
       .anyRequest().hasRole(API_ROLE) 
       .and() 
       .httpBasic() 
       .and() 
       .csrf() 
       .disable(); 
     } 
    } 

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

     @Autowired 
     private Environment env; 

     @Autowired 
     public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
      auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider()); 
      auth.eraseCredentials(false); 
     } 

     @Override 
     protected void configure(HttpSecurity http) throws Exception { 
      // LDAP FORM AUTHENTICATION 
      http.authorizeRequests() 
       .antMatchers("/login.html").permitAll() 
       .antMatchers("/css/**").permitAll() 
       .antMatchers("/js/**").permitAll() 
       .antMatchers("/images/**").permitAll() 
       .anyRequest().authenticated() 
      .and().formLogin() 
       .failureUrl("/login.html?error=1") 
       .loginPage("/login.html") 
       .loginProcessingUrl("/j_spring_security_check") 
       .defaultSuccessUrl("/success.html") 
       .usernameParameter("j_username") 
       .passwordParameter("j_password") 
       .permitAll(); 

      http.csrf().disable(); 

      // iFRAMES SETTINGS 
      http 
       .headers() 
       .frameOptions().sameOrigin() 
       .httpStrictTransportSecurity().disable(); 

      // HTTPS 
      http 
       .requiresChannel() 
       .anyRequest() 
       .requiresSecure(); 

      //MAP 8080 to HTTPS PORT 
      http.portMapper().http(8080).mapsTo(443); 
     } 

     @Bean 
     public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() { 
      CustomLdapAuthenticationProvider provider = new CustomLdapAuthenticationProvider(env.getProperty("ldap.domain"), env.getProperty("ldap.url"), env.getProperty("ldap.base")); 
      provider.setConvertSubErrorCodesToExceptions(true); 
      provider.setUseAuthenticationRequestCredentials(true); 
      return provider; 
     } 
    } 
} 

Любая идея?

Я использую версию Spring Boot 1.4.1-RELEASE и версию Spring Security 4.1.3-RELEASE.

+0

это ниже ответ работа? – theLearner

+0

Да, он отлично работает! – Dimi

ответ

2

Вы используете то же самое AuthenticationManager для обеих конфигураций, потому что вы автоматически устанавливаете то же самое AuthenticationManagerBuilder.

См Spring Security Architecture:

@Configuration 
public class ApplicationSecurity extends WebSecurityConfigurerAdapter { 

    ... // web stuff here 

    @Autowired 
    public initialize(AuthenticationManagerBuilder builder, DataSource dataSource) { 
     auth.jdbcAuthentication().dataSource(dataSource).withUser("dave") 
      .password("secret").roles("USER"); 
    } 

} 

Этот пример относится к веб-приложения, но использование AuthenticationManagerBuilder является более широкое применение (см ниже более подробно о том, как осуществляется безопасность веб-приложений). Обратите внимание, что AuthenticationManagerBuilder является @Autowired в метод в @Bean - вот почему он создает глобальный (родительский) AuthenticationManager. В отличии, если бы мы сделали это таким образом:

@Configuration 
public class ApplicationSecurity extends WebSecurityConfigurerAdapter { 

    @Autowired 
    DataSource dataSource; 

    ... // web stuff here 

    @Override 
    public configure(AuthenticationManagerBuilder builder) { 
     auth.jdbcAuthentication().dataSource(dataSource).withUser("dave") 
      .password("secret").roles("USER"); 
    } 

} 

(с использованием @Override метода в configurer), то AuthenticationManagerBuilder только используется для создания «локального» AuthenticationManager, который является потомком глобального ,