在 Spring 安全 SAML2 中自定义 OpenSaml4AuthenticationProvider
Customizing OpenSaml4AuthenticationProvider in Spring Security SAML2
我需要使用带有 Spring 安全 SAML2 的遗留 UserDetailsService
,所以我正在关注 these instructions from Spring。但是,当我根据该文档尝试将 AuthenticationProvider
替换为所谓的“默认”时出现错误:
public class WigWebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
OpenSaml4AuthenticationProvider authenticationProvider = new OpenSaml4AuthenticationProvider();
// I've tried removing these 2 lines and I get the same error
authenticationProvider.setAssertionValidator(OpenSaml4AuthenticationProvider.createDefaultAssertionValidator());
authenticationProvider.setResponseAuthenticationConverter(OpenSaml4AuthenticationProvider.createDefaultResponseAuthenticationConverter());
httpSecurity.authorizeRequests(authz -> authz.anyRequest().authenticated())
.saml2Login(saml2 -> saml2.authenticationManager(new ProviderManager(authenticationProvider)));
}
}
当我这样做时,我在尝试验证时收到以下错误:
java.lang.NoSuchMethodError: org.opensaml.saml.saml2.assertion.SAML20AssertionValidator.<init>(Ljava/util/Collection;Ljava/util/Collection;Ljava/util/Collection;Lorg/opensaml/saml/saml2/assertion/AssertionValidator;Lorg/opensaml/xmlsec/signature/support/SignatureTrustEngine;Lorg/opensaml/xmlsec/signature/support/SignaturePrevalidator;)V
at org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider$SAML20AssertionValidators.<init>(OpenSaml4AuthenticationProvider.java:732)
at org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider$SAML20AssertionValidators.<clinit>(OpenSaml4AuthenticationProvider.java:731)
at org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider.lambda$createDefaultAssertionSignatureValidator(OpenSaml4AuthenticationProvider.java:572)
at org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider.lambda$createAssertionValidator(OpenSaml4AuthenticationProvider.java:654)
at org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider.process(OpenSaml4AuthenticationProvider.java:495)
at org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider.authenticate(OpenSaml4AuthenticationProvider.java:448)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182)
at org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationFilter.attemptAuthentication(Saml2WebSsoAuthenticationFilter.java:113)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:222)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
但是当我使用相同的代码而不设置 authenticationManager
时,SAML 身份验证工作正常。 (任何想要使用我的自定义 UserDetails
的页面当然会失败,因为它没有被填充,但是所有 SAML 身份验证步骤都工作正常。):
public class WigWebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests(authz -> authz.anyRequest().authenticated())
.saml2Login();
}
}
原来我用的是org.opensaml:opensaml-api 3.4.6,你要用4.x才能用class OpenSaml4AuthenticationProvider
.如果您使用的是 3.x,则需要使用已弃用的 class OpenSamlAuthenticationProvider
。我无法升级 opensaml 依赖项,因为我使用的是 Java 8,所以这是适合我的代码:
public class WigWebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
// This class is deprecated, but you have to use it if you're using OpenSAML < 4.0
OpenSamlAuthenticationProvider authenticationProvider = new OpenSamlAuthenticationProvider();
authenticationProvider.setAssertionValidator(OpenSamlAuthenticationProvider.createDefaultAssertionValidator());
authenticationProvider.setResponseAuthenticationConverter(OpenSamlAuthenticationProvider.createDefaultResponseAuthenticationConverter());
httpSecurity.authorizeRequests(authz -> authz.anyRequest().authenticated())
.saml2Login(saml2 -> saml2.authenticationManager(new ProviderManager(authenticationProvider)));
}
}
当我发现这就是 Saml2LoginConfigurer 内部所做的事情时,我终于找到了答案。
我需要使用带有 Spring 安全 SAML2 的遗留 UserDetailsService
,所以我正在关注 these instructions from Spring。但是,当我根据该文档尝试将 AuthenticationProvider
替换为所谓的“默认”时出现错误:
public class WigWebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
OpenSaml4AuthenticationProvider authenticationProvider = new OpenSaml4AuthenticationProvider();
// I've tried removing these 2 lines and I get the same error
authenticationProvider.setAssertionValidator(OpenSaml4AuthenticationProvider.createDefaultAssertionValidator());
authenticationProvider.setResponseAuthenticationConverter(OpenSaml4AuthenticationProvider.createDefaultResponseAuthenticationConverter());
httpSecurity.authorizeRequests(authz -> authz.anyRequest().authenticated())
.saml2Login(saml2 -> saml2.authenticationManager(new ProviderManager(authenticationProvider)));
}
}
当我这样做时,我在尝试验证时收到以下错误:
java.lang.NoSuchMethodError: org.opensaml.saml.saml2.assertion.SAML20AssertionValidator.<init>(Ljava/util/Collection;Ljava/util/Collection;Ljava/util/Collection;Lorg/opensaml/saml/saml2/assertion/AssertionValidator;Lorg/opensaml/xmlsec/signature/support/SignatureTrustEngine;Lorg/opensaml/xmlsec/signature/support/SignaturePrevalidator;)V
at org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider$SAML20AssertionValidators.<init>(OpenSaml4AuthenticationProvider.java:732)
at org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider$SAML20AssertionValidators.<clinit>(OpenSaml4AuthenticationProvider.java:731)
at org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider.lambda$createDefaultAssertionSignatureValidator(OpenSaml4AuthenticationProvider.java:572)
at org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider.lambda$createAssertionValidator(OpenSaml4AuthenticationProvider.java:654)
at org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider.process(OpenSaml4AuthenticationProvider.java:495)
at org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider.authenticate(OpenSaml4AuthenticationProvider.java:448)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182)
at org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationFilter.attemptAuthentication(Saml2WebSsoAuthenticationFilter.java:113)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:222)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
但是当我使用相同的代码而不设置 authenticationManager
时,SAML 身份验证工作正常。 (任何想要使用我的自定义 UserDetails
的页面当然会失败,因为它没有被填充,但是所有 SAML 身份验证步骤都工作正常。):
public class WigWebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests(authz -> authz.anyRequest().authenticated())
.saml2Login();
}
}
原来我用的是org.opensaml:opensaml-api 3.4.6,你要用4.x才能用class OpenSaml4AuthenticationProvider
.如果您使用的是 3.x,则需要使用已弃用的 class OpenSamlAuthenticationProvider
。我无法升级 opensaml 依赖项,因为我使用的是 Java 8,所以这是适合我的代码:
public class WigWebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
// This class is deprecated, but you have to use it if you're using OpenSAML < 4.0
OpenSamlAuthenticationProvider authenticationProvider = new OpenSamlAuthenticationProvider();
authenticationProvider.setAssertionValidator(OpenSamlAuthenticationProvider.createDefaultAssertionValidator());
authenticationProvider.setResponseAuthenticationConverter(OpenSamlAuthenticationProvider.createDefaultResponseAuthenticationConverter());
httpSecurity.authorizeRequests(authz -> authz.anyRequest().authenticated())
.saml2Login(saml2 -> saml2.authenticationManager(new ProviderManager(authenticationProvider)));
}
}
当我发现这就是 Saml2LoginConfigurer 内部所做的事情时,我终于找到了答案。