J'étais assez accro au problème que l'application ne pouvait pas démarrer en raison de ʻAlreadyBuiltException` dans Spring Security + Spring Boot, donc le mémo de la solution à ce moment-là.
Bien que j'aie omis diverses choses, j'ai créé la configuration Java suivante.
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> auds;
@Bean
public PreAuthenticatedAuthenticationProvider preAuthenticationProvider() {
PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider();
provider.setPreAuthenticatedUserDetailsService(auds);
return provider;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(preAuthenticationProvider()).build();
}
}
Si vous démarrez l'application avec ces paramètres, l'erreur suivante se produit.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is org.springframework.security.config.annotation.AlreadyBuiltException: This object has already been built
J'ai eu une erreur disant que springSecurityFilterChain
est déjà construit, mais il m'a fallu un certain temps pour déterminer la cause.
C'était parce que j'exécutais build avec la méthode configure de la classe SecurityConfig
.
Il semble que lorsque la construction est exécutée, ʻAuthenticationManager est généré, mais en fait, il est exécuté par la classe parente
WebSecurityConfigurerAdapter`.
Il semble qu'un tel problème se soit produit car il a été exécuté deux fois cette fois.
Vous pouvez faire ce qui suit.
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> auds;
@Bean
public PreAuthenticatedAuthenticationProvider preAuthenticationProvider() {
PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider();
provider.setPreAuthenticatedUserDetailsService(auds);
return provider;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(preAuthenticationProvider());
}
}
En fait, même si vous consultez la documentation, etc., vous ne l'avez pas construite avec JavaConfig. Mais c'est une classe Builder, et si la méthode de construction vient en complément, vous voudrez la construire!
Vous devez lire le document correctement. J'ai perdu beaucoup de temps.