gpt4 book ai didi

spring - 在 Spring Security 3.2.5 中,是什么导致 AuthenticationManager 实现内部出现无限循环?

转载 作者:行者123 更新时间:2023-12-02 00:35:11 24 4
gpt4 key购买 nike

不久前我遇到了一个有趣的情况,它导致了 Spring Security 的 AuthenticationManager 中的无限循环(并最终导致堆栈溢出)。几个月来,一切都按预期进行,但后来我决定将 XML 配置转移到纯代码配置。这是我在 Java 配置中的基本设置:

@Configuration
@EnableWebMvcSecurity
@ComponentScan(basePackages = { "com.my.company" })
public class SecurityConfig extends WebSecurityConfigurerAdapter {

// Disable default configuration
public SecurityConfig() {
super(true);
}

@Autowired
AuthenticationProviderImpl authenticationProvider;

@Autowired
MyAuthenticationEntryPoint customAuthenticationEntryPoint;

@Autowired
AuthenticationTokenProcessingFilter authenticationTokenProcessingFilter;

@Bean(name = "authenticationManager")
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}

@Override
public void configure(WebSecurity web) throws Exception {

// Ignore requests of resources in security
web.ignoring().antMatchers("/resources/**")
// Ignore requests to authentication
.and().ignoring().antMatchers("/auth/**");
}

@Override
protected void configure(HttpSecurity http) throws Exception {

// Define main authentication filter
http.addFilterBefore(authenticationTokenProcessingFilter,
UsernamePasswordAuthenticationFilter.class)

// Request path authorization
.authorizeRequests()
.antMatchers("/api/**")
.access("isAuthenticated()")

// Authentication provider
.and()
.authenticationProvider(authenticationProvider)

// Security failure exception handling
.exceptionHandling()
.authenticationEntryPoint(customAuthenticationEntryPoint)

// Session Management
.and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)

// Default security HTTP headers
.and().headers().xssProtection().frameOptions()
.cacheControl().contentTypeOptions();
}
}

但是,我很快发现此配置会导致我的 AuthenticationProviderImpl (实现 Spring Security AuthenticationProvider 接口(interface))出现问题。当实现的重写 authenticate 方法抛出 BadCredentialsException 时,会再次调用该类中完全相同的方法,直到堆栈溢出。好消息是,我通过简单地覆盖 SecurityConfig 中的 configure(AuthenticationManagerBuilder builder) 并在那里声明我的 AuthenticationProvider 实现来修复我的配置在 configure(HttpSecurity http) 中。这是修复后的版本:

@Configuration
@EnableWebMvcSecurity
@ComponentScan(basePackages = { "com.my.company" })
public class SecurityConfig extends WebSecurityConfigurerAdapter {

// Disable default configuration
public SecurityConfig() {
super(true);
}

@Autowired
AuthenticationProviderImpl authenticationProvider;

@Autowired
MyAuthenticationEntryPoint customAuthenticationEntryPoint;

@Autowired
AuthenticationTokenProcessingFilter authenticationTokenProcessingFilter;

@Bean(name = "authenticationManager")
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}

@Override
public void configure(AuthenticationManagerBuilder builder) {
// Configure the authentication manager WITH the authentication
// provider. Not overriding this method causes very bad things to
// happen.
builder.authenticationProvider(authenticationProvider);
}

@Override
public void configure(WebSecurity web) throws Exception {

// Ignore requests of resources in security
web.ignoring().antMatchers("/resources/**")
// Ignore requests to authentication
.and().ignoring().antMatchers("/auth/**");
}

@Override
protected void configure(HttpSecurity http) throws Exception {

// Define main authentication filter
http.addFilterBefore(authenticationTokenProcessingFilter,
UsernamePasswordAuthenticationFilter.class)

// Request path authorization
.authorizeRequests()
.antMatchers("/api/**")
.access("isAuthenticated()")
.and()

// Security failure exception handling
.exceptionHandling()
.authenticationEntryPoint(customAuthenticationEntryPoint)

// Session Management
.and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)

// Default security HTTP headers
.and().headers().xssProtection().frameOptions()
.cacheControl().contentTypeOptions();
}
}

虽然我相信我的问题已通过固定配置解决,但我仍然不知道为什么当我的 AuthenticationProvider< 实现抛出异常时,应用程序会无限调用 authenticate()/?我尝试逐步检查并检查 Spring Security 类,但没有找到合乎逻辑的答案。在此先感谢您的专业知识!

最佳答案

几周前我也重现了这种行为,see this thread on stackoverflow

处理这个问题时,我发现当 AuthenticationManager 内部迭代其关联的 AuthenticationProviders 列表时会发生循环,然后找到自定义提供程序并尝试进行身份验证使用已找到的提供程序。如果提供者通过调用 authenticate() 将身份验证委托(delegate)回 AuthenticationManager,那么您就处于循环之中。我猜你的 AuthenticationProviderImpl 做了类似的事情?

AuthenticationManagerjava.util.List 内的提供程序的顺序很重要。该顺序由您的配置给出,例如通过做你最初尝试过的事情:

// Authentication provider
.and()
.authenticationProvider(authenticationProvider)

通过更改您的配置,您影响了附加到您的管理器的内部管理的提供程序列表,这最终将解决您的代码。

关于spring - 在 Spring Security 3.2.5 中,是什么导致 AuthenticationManager 实现内部出现无限循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28686745/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com