Selon Spring Security Reference section 5.7 , il devrait être possible de définir plusieurs adaptateurs de sécurité.
J'essaie de faire de même mais sans succès. Après un redémarrage du serveur, les x premières fois que l'API fonctionne correctement avec l'authentification de base, mais après quelques fois, je suis redirigé vers la page de connexion (formulaire), cela ne devrait se produire que pour notre application Web, pas pour les appels d'API.
Mon code:
@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;
}
}
}
Une idée?
J'utilise Spring Boot version 1.4.1-RELEASE et Spring Security version 4.1.3-RELEASE.
Vous utilisez le même AuthenticationManager
pour les deux configurations, car vous autowire le même AuthenticationManagerBuilder
.
Voir 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"); } }
Cet exemple concerne une application Web, mais l'utilisation de
AuthenticationManagerBuilder
est plus largement applicable (voir ci-dessous pour plus de détails sur la façon dont la sécurité des applications Web est implémentée). Notez queAuthenticationManagerBuilder
est@Autowired
dans une méthode dans un@Bean
- c'est ce qui fait qu'il construit le gestionnaire d'authentification global (parent). En revanche, si nous l'avions fait de cette façon:@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"); } }
(en utilisant un
@Override
d'une méthode dans le configurateur) alors leAuthenticationManagerBuilder
n'est utilisé que pour construire un "local"AuthenticationManager
, qui est un enfant du global.