Spring Circular Dependency with HttpSecurityConfiguration



我有一个循环依赖错误的问题。当我在我的securityConfig类中定义UserDetailsService bean时抛出,但是如果我在我的authenticationConfig类中定义相同的bean,错误就会消失,我不知道为什么。这是代码

@Configuration
public class SecurityConfig {
@Autowired
private JwtAuthenticationFilter jwtAuthenticationFilter;
@Autowired
private InitialAuthenticationFilter initialAuthenticationFilter;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {    
return http.csrf().disable()
.httpBasic().and()
.addFilterBefore(initialAuthenticationFilter, BasicAuthenticationFilter.class)
.addFilterAfter(jwtAuthenticationFilter,BasicAuthenticationFilter.class)
.authorizeHttpRequests().requestMatchers("/actuator/**").permitAll().and()
.authorizeHttpRequests().anyRequest().authenticated()
.and()
.build();
}
@Bean
public UserDetailsService userDetailsService(){    
UserDetails user = User.builder()
.username("user")
.password("123")
.roles("USER")
.build();
UserDetails admin = User.builder()
.username("admin")
.password("123")
.roles("USER", "ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);        
}
}
@Configuration
public class AuthenticationConfig {
@Autowired
private OtpAuthenticationProvider otpAuthenticationProvider;
@Autowired
private UsernamePasswordAuthenticationProvider usernamePasswordAuthenticationProvider;
@Bean
public AuthenticationManager authManager(HttpSecurity http) throws Exception {
AuthenticationManagerBuilder authenticationManagerBuilder =
http.getSharedObject(AuthenticationManagerBuilder.class);
authenticationManagerBuilder.authenticationProvider(usernamePasswordAuthenticationProvider).authenticationProvider(otpAuthenticationProvider);
return authenticationManagerBuilder.build();
}
}
@Component
public class InitialAuthenticationFilter extends OncePerRequestFilter {
@Autowired
private AuthenticationManager manager;
@Value("${jwt.signing.key}")
private String signingKey;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException { // do filtering
}
}
// and then i have some providers like this one
@Component
public class UsernamePasswordAuthenticationProvider implements AuthenticationProvider{

@Autowired
private AuthenticationServerProxy proxy;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String password = String.valueOf(authentication.getCredentials());
proxy.sendAuth(username, password);
return new UsernamePasswordAuthenticationToken(username, password);
}
@Override
public boolean supports(Class<?> authentication) {
// TODO Auto-generated method stub
return UsernamePasswordAuthentication.class.isAssignableFrom(authentication);
}
}

这是日志:

Exception: org.springframework.beans.factory.UnsatisfiedDependencyException. 
Message: Error creating bean with name 'securityConfig': Unsatisfied dependency expressed through field 'initialAuthenticationFilter': 
Error creating bean with name 'initialAuthenticationFilter': Unsatisfied dependency expressed through field 'manager': 
Error creating bean with name 'authManager' defined in class path resource [root/AuthenticationConfig.class]: 
Unsatisfied dependency expressed through method 'authManager' parameter 0: 
Error creating bean with name 'org.springframework.security.config.annotation.web.configuration.HttpSecurityConfiguration.httpSecurity' 
defined in class path resource [org/springframework/security/config/annotation/web/configuration/HttpSecurityConfiguration.class]: 
Failed to instantiate [org.springframework.security.config.annotation.web.builders.HttpSecurity]: 
Factory method 'httpSecurity' threw exception with message: Error creating bean with name 'securityConfig': 
Requested bean is currently in creation: Is there an unresolvable circular reference?

然后是这个图:

The dependencies of some of the beans in the application context form a cycle:
┌─────┐
|  securityConfig (field private root.filters.InitialAuthenticationFilter root.SecurityConfig.initialAuthenticationFilter)
↑     ↓
|  initialAuthenticationFilter (field private org.springframework.security.authentication.AuthenticationManager root.filters.InitialAuthenticationFilter.manager)
↑     ↓
|  authManager defined in class path resource [root/AuthenticationConfig.class]
↑     ↓
|  org.springframework.security.config.annotation.web.configuration.HttpSecurityConfiguration.httpSecurity defined in class path resource [org/springframework/security/config/annotation/web/configuration/HttpSecurityConfiguration.class]
└─────┘

如果我移动UserDetailsService bean到另一个类,一切工作完美,但我试图了解在哪里是循环依赖来自。日志说authManager依赖于HttpSecurity,这是正确的,但是HttpSecurity依赖于securityConfig,我试着用调试器检查HttpSecurity bean,但找不到任何依赖

检查UserDetailsServiceHttpSecurity没有任何直接关系。但是您必须使用UserDetailsService来将角色定义为HttpSecurity。您可以在Spring API HttpSecurity中找到相关信息。

循环依赖应该与AuthenticationManagerHttpSecurity相关。在旧版spring中,创建覆盖WebSecurityConfigurerAdapterAuthenticationManager。代码类似于:

@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}

但是在最后的版本中,您可以使用filterChain(在您的示例中是securityFilerChange)来实例化AuthenticationManager。bean可以是这样的:

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {    
AuthenticationManagerBuilder authenticationManagerBuilder = http.getSharedObject(AuthenticationManagerBuilder.class);
authenticationManagerBuilder.authenticationProvider(usernamePasswordAuthenticationProvider).authenticationProvider(otpAuthenticationProvider);
AuthenticationManager authenticationManager = authenticationManagerBuilder.build();
return http.csrf().disable()
.httpBasic().and().{...}
.anyRequest().authenticated()
.and()
.authenticationManager(authenticationManager).{...}
.build();
}

在这个实现中,你只有一个站点,你正在使用HttpSecurity和循环依赖错误应该消失。

关于如何升级WebSecurityConfigurerAdapter,您可以在此链接中查看有关如何使用该AuthenticationManager的更多信息。

相关内容

  • 没有找到相关文章

最新更新