Spring security spring saml多租户环境下的端点验证方法
我正在构建一个多租户环境。 您需要能够在Spring security spring saml多租户环境下的端点验证方法,spring-security,saml,multi-tenant,spring-saml,Spring Security,Saml,Multi Tenant,Spring Saml,我正在构建一个多租户环境。 您需要能够在https://tenant1.com或https://tenant2.com 事实证明,要为每个URL指定SP元数据,可以通过为元数据指定别名来指定。 然而,端点验证也需要相应地进行 tenant1.com是在samlContextProviderLB的服务器名中设置的。在这种状态下 使用https://tenant2.com,出现以下错误 SAML消息目标端点'https://tenant2.com/xxx' 与收件人终结点的名称不匹配https://
https://tenant1.com
或https://tenant2.com
事实证明,要为每个URL指定SP元数据,可以通过为元数据指定别名来指定。
然而,端点验证也需要相应地进行
tenant1.com
是在samlContextProviderLB的服务器名中设置的。在这种状态下
使用https://tenant2.com
,出现以下错误
SAML消息目标端点'https://tenant2.com/xxx'
与收件人终结点的名称不匹配https://tenant1.com/xxx"
以下是一些securityConfig设置
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private SecurityProperties securityProperties;
・
・
・
@Bean
public SAMLContextProviderLB contextProvider() {
SAMLContextProviderLB samlContextProviderLB = new SAMLContextProviderLB();
samlContextProviderLB.setScheme("https");
samlContextProviderLB.setServerName("tenant1.com");
samlContextProviderLB.setServerPort(443);
samlContextProviderLB.setIncludeServerPortInRequestURL(false);
samlContextProviderLB.setContextPath("");
EmptyStorageFactory emptyStorageFactory = new EmptyStorageFactory();
samlContextProviderLB.setStorageFactory(emptyStorageFactory);
return samlContextProviderLB;
}
@Bean
public ExtendedMetadataDelegate ssoCircleExtendedMetadataProvider1()
throws MetadataProviderException, ResourceException {
ClasspathResource classpathResource = new ClasspathResource("/metadata/sp_metadata2.xml");
ResourceBackedMetadataProvider resourceBackedMetadataProvider = new ResourceBackedMetadataProvider(
this.backgroundTaskTimer, classpathResource);
resourceBackedMetadataProvider.setParserPool(parserPool());
ExtendedMetadata extendedMetadata = new ExtendedMetadata();
extendedMetadata.setAlias("alias-tenant1");
extendedMetadata.setLocal(true);
extendedMetadata.setSigningKey("keyVal");
extendedMetadata.setEncryptionKey("keyVal");
extendedMetadata.setIdpDiscoveryEnabled(false);
extendedMetadata.setIdpDiscoveryURL("https://login.windows.net/xxx..../saml2");
ExtendedMetadataDelegate extendedMetadataDelegate = new ExtendedMetadataDelegate(resourceBackedMetadataProvider,
extendedMetadata);
backgroundTaskTimer.purge();
return extendedMetadataDelegate;
}
@Bean
public ExtendedMetadataDelegate idpExtendedMetadataProvider1()
throws MetadataProviderException, ResourceException {
ClasspathResource classpathResource = new ClasspathResource("/metadata/idp_metadata1.xml");
ResourceBackedMetadataProvider resourceBackedMetadataProvider = new ResourceBackedMetadataProvider(
this.backgroundTaskTimer, classpathResource);
resourceBackedMetadataProvider.setParserPool(parserPool());
ExtendedMetadataDelegate extendedMetadataDelegate = new ExtendedMetadataDelegate(
resourceBackedMetadataProvider);
backgroundTaskTimer.purge();
return extendedMetadataDelegate;
}
public ExtendedMetadataDelegate ssoCircleExtendedMetadataProvider2()
throws MetadataProviderException, ResourceException {
ClasspathResource classpathResource = new ClasspathResource("/metadata/sp_metadata2.xml");
ResourceBackedMetadataProvider resourceBackedMetadataProvider = new ResourceBackedMetadataProvider(
this.backgroundTaskTimer, classpathResource);
resourceBackedMetadataProvider.setParserPool(parserPool());
ExtendedMetadata extendedMetadata = new ExtendedMetadata();
extendedMetadata.setAlias("alias-tenant2");
extendedMetadata.setLocal(true);
extendedMetadata.setSigningKey("keyVal");
extendedMetadata.setEncryptionKey("keyVal");
extendedMetadata.setIdpDiscoveryEnabled(false);
extendedMetadata.setIdpDiscoveryURL("https://login.windows.net/xxx..../saml2");
ExtendedMetadataDelegate extendedMetadataDelegate = new ExtendedMetadataDelegate(resourceBackedMetadataProvider,
extendedMetadata);
backgroundTaskTimer.purge();
return extendedMetadataDelegate;
}
public ExtendedMetadataDelegate idpExtendedMetadataProvider2()
throws MetadataProviderException, ResourceException {
ClasspathResource classpathResource = new ClasspathResource("/metadata/idp_metadata2.xml");
ResourceBackedMetadataProvider resourceBackedMetadataProvider = new ResourceBackedMetadataProvider(
this.backgroundTaskTimer, classpathResource);
resourceBackedMetadataProvider.setParserPool(parserPool());
ExtendedMetadataDelegate extendedMetadataDelegate = new ExtendedMetadataDelegate(
resourceBackedMetadataProvider);
backgroundTaskTimer.purge();
return extendedMetadataDelegate;
}
@Bean
@Qualifier("metadata")
public CachingMetadataManager metadata() throws MetadataProviderException, ResourceException {
List<MetadataProvider> providers = new ArrayList<MetadataProvider>();
// SP MetaData
providers.add(ssoCircleExtendedMetadataProvider1());
providers.add(ssoCircleExtendedMetadataProvider2());
// IDP MetaData
providers.add(idpExtendedMetadataProvider1());
providers.add(idpExtendedMetadataProvider2());
CachingMetadataManager cachingMetadataManager = new CachingMetadataManager(providers);
cachingMetadataManager.setDefaultIDP("https://sts.windows.net/xxx..../");
return cachingMetadataManager;
}
・
・
・
@Bean
public FilterChainProxy samlFilter() throws Exception {
List<SecurityFilterChain> chains = new ArrayList<SecurityFilterChain>();
chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/login/**"),
samlEntryPoint()));
chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/samlForceLogin/**"),
samlForceEntryPoint()));
chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/logout/**"),
samlLogoutFilter()));
chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/metadata/**"),
metadataDisplayFilter()));
chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/SSO/**"),
samlWebSSOProcessingFilter()));
chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/SSOHoK/**"),
samlWebSSOHoKProcessingFilter()));
chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/SingleLogout/**"),
samlLogoutProcessingFilter()));
chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/discovery/**"),
samlIDPDiscovery()));
return new FilterChainProxy(chains);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic()
.authenticationEntryPoint(samlEntryPoint())
.authenticationEntryPoint(samlForceEntryPoint());
http.csrf()
.ignoringAntMatchers("/saml/**")
.ignoringAntMatchers("/");
http.addFilterAfter(samlFilter(), BasicAuthenticationFilter.class);
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/saml/**").permitAll()
.anyRequest().authenticated();
http.logout()
.logoutSuccessUrl("/");
http.headers().xssProtection();
if (securityProperties.isEnableCsrf()) {
http.addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class).csrf();
} else {
http.csrf().disable();
}
}
}
@配置
@启用Web安全性
@EnableGlobalMethodSecurity(securedEnabled=true)
公共类SecurityConfig扩展了WebSecurity配置适配器{
@自动连线
私人证券财产证券财产;
・
・
・
@豆子
公共SAMLContextProviderLB contextProvider(){
SAMLContextProviderLB SAMLContextProviderLB=新的SAMLContextProviderLB();
samlContextProviderLB.setScheme(“https”);
samlContextProviderLB.setServerName(“tenant1.com”);
samlContextProviderLB.setServerPort(443);
samlContextProviderLB.setIncludeServePortInRequestUrl(false);
samlContextProviderLB.setContextPath(“”);
EmptyStorageFactory EmptyStorageFactory=新的EmptyStorageFactory();
samlContextProviderLB.设置存储工厂(清空存储工厂);
返回samlContextProviderLB;
}
@豆子
public ExtendedMetadataDelegate SSOCirleExtendedMetadataProvider1()
抛出MetadataProviderException、ResourceException{
ClasspathResource ClasspathResource=new ClasspathResource(“/metadata/sp_metadata2.xml”);
ResourceBackedMetadataProvider ResourceBackedMetadataProvider=新ResourceBackedMetadataProvider(
this.backgroundTaskTimer,classpathResource);
setParserPool(parserPool());
ExtendedMetadata ExtendedMetadata=新的ExtendedMetadata();
setAlias(“alias-tenant1”);
extendedMetadata.setLocal(true);
extendedMetadata.setSigningKey(“keyVal”);
setEncryptionKey(“keyVal”);
extendedMetadata.SetIdDiscoveryEnabled(false);
extendedMetadata.SetIdDiscoveryUrl(“https://login.windows.net/xxx..../saml2");
ExtendedMetadataDelegate ExtendedMetadataDelegate=新的ExtendedMetadataDelegate(resourceBackedMetadataProvider,
扩展元数据);
backgroundTaskTimer.purge();
返回extendedMetadataDelegate;
}
@豆子
公共ExtendedMetadataDelegate IdExtendedMetadataProvider1()
抛出MetadataProviderException、ResourceException{
ClasspathResource ClasspathResource=new ClasspathResource(“/metadata/idp_metadata1.xml”);
ResourceBackedMetadataProvider ResourceBackedMetadataProvider=新ResourceBackedMetadataProvider(
this.backgroundTaskTimer,classpathResource);
setParserPool(parserPool());
ExtendedMetadataDelegate ExtendedMetadataDelegate=新的ExtendedMetadataDelegate(
resourceBackedMetadataProvider);
backgroundTaskTimer.purge();
返回extendedMetadataDelegate;
}
public ExtendedMetadataDelegate SSOCirleExtendedMetadataProvider2()
抛出MetadataProviderException、ResourceException{
ClasspathResource ClasspathResource=new ClasspathResource(“/metadata/sp_metadata2.xml”);
ResourceBackedMetadataProvider ResourceBackedMetadataProvider=新ResourceBackedMetadataProvider(
this.backgroundTaskTimer,classpathResource);
setParserPool(parserPool());
ExtendedMetadata ExtendedMetadata=新的ExtendedMetadata();
setAlias(“别名-tenant2”);
extendedMetadata.setLocal(true);
extendedMetadata.setSigningKey(“keyVal”);
setEncryptionKey(“keyVal”);
extendedMetadata.SetIdDiscoveryEnabled(false);
extendedMetadata.SetIdDiscoveryUrl(“https://login.windows.net/xxx..../saml2");
ExtendedMetadataDelegate ExtendedMetadataDelegate=新的ExtendedMetadataDelegate(resourceBackedMetadataProvider,
扩展元数据);
backgroundTaskTimer.purge();
返回extendedMetadataDelegate;
}
公共ExtendedMetadataDelegate IdExtendedMetadataProvider2()
抛出MetadataProviderException、ResourceException{
ClasspathResource ClasspathResource=new ClasspathResource(“/metadata/idp_metadata2.xml”);
ResourceBackedMetadataProvider ResourceBackedMetadataProvider=新ResourceBackedMetadataProvider(
this.backgroundTaskTimer,classpathResource);
setParserPool(parserPool());
ExtendedMetadataDelegate ExtendedMetadataDelegate=新的ExtendedMetadataDelegate(
resourceBackedMetadataProvider);
backgroundTaskTimer.purge();
返回extendedMetadataDelegate;
}
@豆子
@限定符(“元数据”)
public CachingMetadataManager元数据()引发MetadataProviderException,ResourceException{
列表提供程序=新的ArrayList();
//SP元数据
add(ssoCircleExtendedMetadataProvider1());
add(ssoCircleExtendedMetadataProvider2());
//IDP元数据
add(idpExtendedMetadataProvider1());
add(idpExtendedMetadataProvider2());
cachingmetadatmanager cachingmetadatmanager=新cachingmetadatmanager(提供程序);
cachingMetadataManager.setDefaultIDP(“https://sts.windows.net/xxx..../");
返回cachingmetadata管理器;