为什么 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 次。

登录时,ProviderManager.authenticate() 被调用两次。

为什么?我如何更正此问题,以便我可以在某些情况下将凭据定向到 SAML,在所有其他情况下定向到 OAuth,或者允许任何在 SAML 中不起作用的凭据溢出到 OAuth?

new ProviderManager() 创建了一个跳过构建器进程的 AuthenticationManager,这就是它在调试时不显示的原因 performBuild()

authenticationManager() bean 方法旨在 return 现有的全局 AuthenticationManager,但问题使用它的方式 return 是一个新的和不同的 AuthenticationManager,覆盖构建器 return秒。这就是为什么在调试 authenticate() 时它 确实 出现,而​​构建的 AuthenticationManager 却没有。

解决方案是将现有的 AuthenticationManager 传递给 SAMLProcessingFilter.setAuthenticationManager(),而不是传递一个新的。我这样做的方法是将所有代码从 SAMLConfig.java 移动到 WebSecurityConfig.java,这样更直接,但这不是唯一的方法。