8

Zgodnie z Spring Security Reference section 5.7 powinno być możliwe zdefiniowanie więcej niż jednego adaptera bezpieczeństwa.Korzystanie z wielu WebSecurityConfigurerAdapter z różnymi dostawcami uwierzytelniania (podstawowe uwierzytelnienie dla API i LDAP dla aplikacji internetowej)

Próbuję zrobić to samo, ale bez powodzenia. Po ponownym uruchomieniu serwera, pierwszy xx działa poprawnie z podstawowym uwierzytelnieniem, ale po kilkukrotnym przekierowaniu na stronę logowania (formularza), to powinno się zdarzyć tylko dla naszej aplikacji internetowej, a nie dla wywołań API.

Mój kod:

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

Każdy pomysł?

Używam Spring Boot wersji 1.4.1-RELEASE i Spring Security wersji 4.1.3-RELEASE.

+0

czy poniżej odpowiedź zadziałała? – theLearner

+0

tak, działa poprawnie! – Dimi

Odpowiedz

2

W obu konfiguracjach używasz tego samego AuthenticationManager, ponieważ nadajesz taką samą nazwę AuthenticationManagerBuilder.

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

} 

Ten przykład odnosi się do aplikacji internetowej, ale korzystanie z AuthenticationManagerBuilder jest bardziej powszechnie stosowane (patrz poniżej, aby uzyskać więcej szczegółów na temat sposobu zabezpieczenia aplikacji internetowych jest realizowany). Zauważ, że AuthenticationManagerBuilder jest @Autowired na metodę w @Bean - to właśnie sprawia, że ​​buduje globalny (nadrzędny) AuthenticationManager. W przeciwieństwie do tego, gdybyśmy zrobili to w ten sposób:

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

} 

(używając @Override sposobu w Configurer) wtedy AuthenticationManagerBuilder służy wyłącznie do budowania „lokalny” AuthenticationManager, który jest dzieckiem globalnej .

Powiązane problemy