为什么 Spring SAML 阻止 Spring OAuth2 工作?
Why is Spring SAML preventing Spring OAuth2 from working?
我正在将 Spring SAML 添加到一些软件中,直到现在,这些软件仅使用 OAuth2。我需要确保 OAuth 仍然有效,因为 SAML 仅适用于我们的一些客户。
我 运行 遇到了一个问题,旧的 oAuth 似乎不再有效(尽管 SAML 基本上没问题)。似乎身份验证管理器正在以某种方式被覆盖,但不清楚如何或为什么。这是我的 WebSecurityConfig.java:
中的相关代码
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordService.getEncoder())
.and()
.authenticationProvider(samlAuthenticationProvider)
.authenticationProvider(oAuth2AuthenticationProvider());
}
和SAMLConfig.java:
@Bean
public SAMLProcessingFilter samlWebSSOProcessingFilter() throws Exception {
SAMLProcessingFilter samlWebSSOProcessingFilter = new SAMLProcessingFilter();
samlWebSSOProcessingFilter.setAuthenticationManager(authenticationManager());
samlWebSSOProcessingFilter.setAuthenticationSuccessHandler(successRedirectHandler());
samlWebSSOProcessingFilter.setAuthenticationFailureHandler(authenticationFailureHandler());
return samlWebSSOProcessingFilter;
}
@Bean
public AuthenticationManager authenticationManager() {
return new ProviderManager(Collections.singletonList(samlAuthenticationProvider()));
}
显然,这是错误的,但不清楚如何更正。
当我调试时,AuthenticationManagerBuilder.performBuild() 在启动时被调用了 3 次。
- 第一次使用 SAML、OAuth2 和 Dao AuthenticationProviders 构建一个。
- 第二次使用 AnonymousAuthenticationProvider 构建一个。
- 第三个用另一个 DaoAuthenticationProvider 构建一个。
登录时,ProviderManager.authenticate() 被调用两次。
- 第一次,它只有一个提供者,AnonymousAuthenticationProvider。这不验证。
- 第二次是父经理对第一次。它只有一个提供者,即 SAMLAuthenticationProvider。如果在 SAML 中找不到我要进行身份验证的用户,这仍然是要调用的最后一个提供者或管理器。
为什么?我如何更正此问题,以便我可以在某些情况下将凭据定向到 SAML,在所有其他情况下定向到 OAuth,或者允许任何在 SAML 中不起作用的凭据溢出到 OAuth?
new ProviderManager()
创建了一个跳过构建器进程的 AuthenticationManager,这就是它在调试时不显示的原因 performBuild()
。
authenticationManager()
bean 方法旨在 return 现有的全局 AuthenticationManager,但问题使用它的方式 return 是一个新的和不同的 AuthenticationManager,覆盖构建器 return秒。这就是为什么在调试 authenticate()
时它 确实 出现,而构建的 AuthenticationManager 却没有。
解决方案是将现有的 AuthenticationManager 传递给 SAMLProcessingFilter.setAuthenticationManager()
,而不是传递一个新的。我这样做的方法是将所有代码从 SAMLConfig.java 移动到 WebSecurityConfig.java,这样更直接,但这不是唯一的方法。
我正在将 Spring SAML 添加到一些软件中,直到现在,这些软件仅使用 OAuth2。我需要确保 OAuth 仍然有效,因为 SAML 仅适用于我们的一些客户。
我 运行 遇到了一个问题,旧的 oAuth 似乎不再有效(尽管 SAML 基本上没问题)。似乎身份验证管理器正在以某种方式被覆盖,但不清楚如何或为什么。这是我的 WebSecurityConfig.java:
中的相关代码@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordService.getEncoder())
.and()
.authenticationProvider(samlAuthenticationProvider)
.authenticationProvider(oAuth2AuthenticationProvider());
}
和SAMLConfig.java:
@Bean
public SAMLProcessingFilter samlWebSSOProcessingFilter() throws Exception {
SAMLProcessingFilter samlWebSSOProcessingFilter = new SAMLProcessingFilter();
samlWebSSOProcessingFilter.setAuthenticationManager(authenticationManager());
samlWebSSOProcessingFilter.setAuthenticationSuccessHandler(successRedirectHandler());
samlWebSSOProcessingFilter.setAuthenticationFailureHandler(authenticationFailureHandler());
return samlWebSSOProcessingFilter;
}
@Bean
public AuthenticationManager authenticationManager() {
return new ProviderManager(Collections.singletonList(samlAuthenticationProvider()));
}
显然,这是错误的,但不清楚如何更正。
当我调试时,AuthenticationManagerBuilder.performBuild() 在启动时被调用了 3 次。
- 第一次使用 SAML、OAuth2 和 Dao AuthenticationProviders 构建一个。
- 第二次使用 AnonymousAuthenticationProvider 构建一个。
- 第三个用另一个 DaoAuthenticationProvider 构建一个。
登录时,ProviderManager.authenticate() 被调用两次。
- 第一次,它只有一个提供者,AnonymousAuthenticationProvider。这不验证。
- 第二次是父经理对第一次。它只有一个提供者,即 SAMLAuthenticationProvider。如果在 SAML 中找不到我要进行身份验证的用户,这仍然是要调用的最后一个提供者或管理器。
为什么?我如何更正此问题,以便我可以在某些情况下将凭据定向到 SAML,在所有其他情况下定向到 OAuth,或者允许任何在 SAML 中不起作用的凭据溢出到 OAuth?
new ProviderManager()
创建了一个跳过构建器进程的 AuthenticationManager,这就是它在调试时不显示的原因 performBuild()
。
authenticationManager()
bean 方法旨在 return 现有的全局 AuthenticationManager,但问题使用它的方式 return 是一个新的和不同的 AuthenticationManager,覆盖构建器 return秒。这就是为什么在调试 authenticate()
时它 确实 出现,而构建的 AuthenticationManager 却没有。
解决方案是将现有的 AuthenticationManager 传递给 SAMLProcessingFilter.setAuthenticationManager()
,而不是传递一个新的。我这样做的方法是将所有代码从 SAMLConfig.java 移动到 WebSecurityConfig.java,这样更直接,但这不是唯一的方法。