Spring boot Spring boot SAML 2身份验证对象为空
我需要将SAML身份验证与RESTAPI集成,以便使我的rest服务成为无状态的,我采取的方法如下Spring boot Spring boot SAML 2身份验证对象为空,spring-boot,spring-security,saml-2.0,netflix-zuul,spring-saml,Spring Boot,Spring Security,Saml 2.0,Netflix Zuul,Spring Saml,我需要将SAML身份验证与RESTAPI集成,以便使我的rest服务成为无状态的,我采取的方法如下 在zuul代理背后开发了一个身份验证服务,该代理在AWS ALB背后运行 用户尝试通过端点生成令牌https://my-domain/as/auth/login 由于用户未登录,所以他会被重定向到IDP,并在那里进行身份验证 身份验证后,IDP将用户重定向回我的服务,即URLhttps://my-domain/as/auth/login 我检查用户身份验证主体,如果用户经过身份验证,则生成JWT
- 在zuul代理背后开发了一个身份验证服务,该代理在AWS ALB背后运行
- 用户尝试通过端点生成令牌https://my-domain/as/auth/login
- 由于用户未登录,所以他会被重定向到IDP,并在那里进行身份验证
- 身份验证后,IDP将用户重定向回我的服务,即URLhttps://my-domain/as/auth/login
- 我检查用户身份验证主体,如果用户经过身份验证,则生成JWT令牌并将其返回给用户
https://my-domain/as/auth/login
然后身份验证对象为空,因为成功身份验证后SecurityContextHolder被清除,401处理程序启动并将用户重定向到IDP in循环,直到SAML断言失败,请告诉我哪里错了
我的Zuul代理配置如下所示
zuul:
ribbon:
eager-load:
enabled: true
host:
connect-timeout-millis: 5000000
socket-timeout-millis: 5000000
ignoredServices: ""
ignoredPatterns:
- /as/*
routes:
sensitiveHeaders: Cookie,Set-Cookie
import-data-service:
path: /ids/*
serviceId: IDS
stripPrefix: true
authentication-service:
path: /as/*
serviceId: AS
stripPrefix: true
customSensitiveHeaders: false
@Configuration
public class SamlSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public WebSSOProfileOptions defaultWebSSOProfileOptions() {
WebSSOProfileOptions webSSOProfileOptions = new WebSSOProfileOptions();
webSSOProfileOptions.setIncludeScoping(false);
webSSOProfileOptions.setBinding(SAMLConstants.SAML2_POST_BINDING_URI);
return webSSOProfileOptions;
}
@Bean
public SAMLEntryPoint samlEntryPoint() {
SAMLEntryPoint samlEntryPoint = new SAMLEntryPoint();
samlEntryPoint.setDefaultProfileOptions(defaultWebSSOProfileOptions());
return samlEntryPoint;
}
@Bean
public MetadataDisplayFilter metadataDisplayFilter() {
return new MetadataDisplayFilter();
}
@Bean
public SimpleUrlAuthenticationFailureHandler authenticationFailureHandler() {
return new SimpleUrlAuthenticationFailureHandler();
}
@Bean
public SavedRequestAwareAuthenticationSuccessHandler successRedirectHandler() {
SavedRequestAwareAuthenticationSuccessHandler successRedirectHandler =
new SavedRequestAwareAuthenticationSuccessHandler();
successRedirectHandler.setDefaultTargetUrl("https://my-domain/as/saml/SSO");
return successRedirectHandler;
}
@Bean
public SessionRepositoryFilter sessionFilter() {
HttpSessionStrategy cookieStrategy = new CookieHttpSessionStrategy();
MapSessionRepository repository = new MapSessionRepository();
((CookieHttpSessionStrategy) cookieStrategy).setCookieName("JSESSIONID");
SessionRepositoryFilter sessionRepositoryFilter = new SessionRepositoryFilter(repository);
sessionRepositoryFilter.setHttpSessionStrategy(cookieStrategy);
return sessionRepositoryFilter;
}
@Bean
public SAMLProcessingFilter samlWebSSOProcessingFilter() throws Exception {
SAMLProcessingFilter samlWebSSOProcessingFilter = new SAMLProcessingFilter();
samlWebSSOProcessingFilter.setAuthenticationManager(authenticationManager());
samlWebSSOProcessingFilter.setAuthenticationSuccessHandler(successRedirectHandler());
samlWebSSOProcessingFilter.setAuthenticationFailureHandler(authenticationFailureHandler());
return samlWebSSOProcessingFilter;
}
@Bean
public HttpStatusReturningLogoutSuccessHandler successLogoutHandler() {
return new HttpStatusReturningLogoutSuccessHandler();
}
@Bean
public SecurityContextLogoutHandler logoutHandler() {
SecurityContextLogoutHandler logoutHandler = new SecurityContextLogoutHandler();
logoutHandler.setInvalidateHttpSession(true);
logoutHandler.setClearAuthentication(true);
return logoutHandler;
}
@Bean
public SAMLLogoutFilter samlLogoutFilter() {
return new SAMLLogoutFilter(successLogoutHandler(), new LogoutHandler[] {logoutHandler()},
new LogoutHandler[] {logoutHandler()});
}
@Bean
public SAMLLogoutProcessingFilter samlLogoutProcessingFilter() {
return new SAMLLogoutProcessingFilter(successLogoutHandler(), logoutHandler());
}
@Bean
public MetadataGeneratorFilter metadataGeneratorFilter() {
return new MetadataGeneratorFilter(metadataGenerator());
}
@Bean
public MetadataGenerator metadataGenerator() {
MetadataGenerator metadataGenerator = new MetadataGenerator();
metadataGenerator.setEntityId("entityUniqueIdenifier");
metadataGenerator.setExtendedMetadata(extendedMetadata());
metadataGenerator.setIncludeDiscoveryExtension(false);
metadataGenerator.setRequestSigned(true);
metadataGenerator.setKeyManager(keyManager());
metadataGenerator.setEntityBaseURL("https://my-domain/as");
return metadataGenerator;
}
@Bean
public KeyManager keyManager() {
ClassPathResource storeFile = new ClassPathResource("/saml-keystore.jks");
String storePass = "samlstorepass";
Map<String, String> passwords = new HashMap<>();
passwords.put("mykeyalias", "mykeypass");
return new JKSKeyManager(storeFile, storePass, passwords, "mykeyalias");
}
@Bean
public ExtendedMetadata extendedMetadata() {
ExtendedMetadata extendedMetadata = new ExtendedMetadata();
extendedMetadata.setIdpDiscoveryEnabled(false);
extendedMetadata.setSignMetadata(false);
extendedMetadata.setSigningKey("mykeyalias");
extendedMetadata.setEncryptionKey("mykeyalias");
return extendedMetadata;
}
@Bean
public FilterChainProxy samlFilter() throws Exception {
List<SecurityFilterChain> chains = new ArrayList<>();
chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/metadata/**"),
metadataDisplayFilter()));
chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/login/**"),
samlEntryPoint()));
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/logout/**"),
samlLogoutFilter()));
chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/SingleLogout/**"),
samlLogoutProcessingFilter()));
return new FilterChainProxy(chains);
}
@Bean
public TLSProtocolConfigurer tlsProtocolConfigurer() {
return new TLSProtocolConfigurer();
}
@Bean
public ProtocolSocketFactory socketFactory() {
return new TLSProtocolSocketFactory(keyManager(), null, "default");
}
@Bean
public Protocol socketFactoryProtocol() {
return new Protocol("https", socketFactory(), 443);
}
@Bean
public MethodInvokingFactoryBean socketFactoryInitialization() {
MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean();
methodInvokingFactoryBean.setTargetClass(Protocol.class);
methodInvokingFactoryBean.setTargetMethod("registerProtocol");
Object[] args = {"https", socketFactoryProtocol()};
methodInvokingFactoryBean.setArguments(args);
return methodInvokingFactoryBean;
}
@Bean
public VelocityEngine velocityEngine() {
return VelocityFactory.getEngine();
}
@Bean(initMethod = "initialize")
public StaticBasicParserPool parserPool() {
return new StaticBasicParserPool();
}
@Bean(name = "parserPoolHolder")
public ParserPoolHolder parserPoolHolder() {
return new ParserPoolHolder();
}
@Bean
public HTTPPostBinding httpPostBinding() {
return new HTTPPostBinding(parserPool(), velocityEngine());
}
@Bean
public HTTPRedirectDeflateBinding httpRedirectDeflateBinding() {
return new HTTPRedirectDeflateBinding(parserPool());
}
@Bean
public SAMLProcessorImpl processor() {
Collection<SAMLBinding> bindings = new ArrayList<>();
bindings.add(httpRedirectDeflateBinding());
bindings.add(httpPostBinding());
return new SAMLProcessorImpl(bindings);
}
@Bean
public HttpClient httpClient() {
return new HttpClient(multiThreadedHttpConnectionManager());
}
@Bean
public MultiThreadedHttpConnectionManager multiThreadedHttpConnectionManager() {
return new MultiThreadedHttpConnectionManager();
}
@Bean
public static SAMLBootstrap sAMLBootstrap() {
return new CustomSamlBootStrap();
}
@Bean
public SAMLDefaultLogger samlLogger() {
SAMLDefaultLogger samlDefaultLogger = new SAMLDefaultLogger();
samlDefaultLogger.setLogAllMessages(true);
samlDefaultLogger.setLogErrors(true);
return samlDefaultLogger;
}
@Bean
public SAMLContextProviderImpl contextProvider() {
SAMLContextProviderLB samlContextProviderLB = new SAMLContextProviderLB();
samlContextProviderLB.setServerName("my-domain/as");
samlContextProviderLB.setScheme("https");
samlContextProviderLB.setServerPort(443);
samlContextProviderLB.setIncludeServerPortInRequestURL(false);
samlContextProviderLB.setContextPath("");
// samlContextProviderLB.setStorageFactory(new EmptyStorageFactory());
return samlContextProviderLB;
}
// SAML 2.0 WebSSO Assertion Consumer
@Bean
public WebSSOProfileConsumer webSSOprofileConsumer() {
return new WebSSOProfileConsumerImpl();
}
// SAML 2.0 Web SSO profile
@Bean
public WebSSOProfile webSSOprofile() {
return new WebSSOProfileImpl();
}
// not used but autowired...
// SAML 2.0 Holder-of-Key WebSSO Assertion Consumer
@Bean
public WebSSOProfileConsumerHoKImpl hokWebSSOprofileConsumer() {
return new WebSSOProfileConsumerHoKImpl();
}
// not used but autowired...
// SAML 2.0 Holder-of-Key Web SSO profile
@Bean
public WebSSOProfileConsumerHoKImpl hokWebSSOProfile() {
return new WebSSOProfileConsumerHoKImpl();
}
@Bean
public SingleLogoutProfile logoutprofile() {
return new SingleLogoutProfileImpl();
}
@Bean
public ExtendedMetadataDelegate idpMetadata()
throws MetadataProviderException, ResourceException {
Timer backgroundTaskTimer = new Timer(true);
ResourceBackedMetadataProvider resourceBackedMetadataProvider =
new ResourceBackedMetadataProvider(backgroundTaskTimer,
new ClasspathResource("/IDP-metadata.xml"));
resourceBackedMetadataProvider.setParserPool(parserPool());
ExtendedMetadataDelegate extendedMetadataDelegate =
new ExtendedMetadataDelegate(resourceBackedMetadataProvider, extendedMetadata());
extendedMetadataDelegate.setMetadataTrustCheck(true);
extendedMetadataDelegate.setMetadataRequireSignature(false);
return extendedMetadataDelegate;
}
@Bean
@Qualifier("metadata")
public CachingMetadataManager metadata() throws MetadataProviderException, ResourceException {
List<MetadataProvider> providers = new ArrayList<>();
providers.add(idpMetadata());
return new CachingMetadataManager(providers);
}
@Bean
public SAMLUserDetailsService samlUserDetailsService() {
return new SamlUserDetailsServiceImpl();
}
@Bean
public SAMLWebSSOHoKProcessingFilter samlWebSSOHoKProcessingFilter() throws Exception {
final SAMLWebSSOHoKProcessingFilter filter = new SAMLWebSSOHoKProcessingFilter();
filter.setAuthenticationManager(authenticationManager());
filter.setAuthenticationSuccessHandler(successRedirectHandler());
filter.setAuthenticationFailureHandler(authenticationFailureHandler());
return filter;
}
@Bean
public SAMLAuthenticationProvider samlAuthenticationProvider() {
SAMLAuthenticationProvider samlAuthenticationProvider = new SAMLAuthenticationProvider();
samlAuthenticationProvider.setUserDetails(samlUserDetailsService());
samlAuthenticationProvider.setForcePrincipalAsString(false);
return samlAuthenticationProvider;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(samlAuthenticationProvider());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.exceptionHandling().authenticationEntryPoint(samlEntryPoint());
http.csrf().disable();
http.addFilterBefore(metadataGeneratorFilter(), ChannelProcessingFilter.class)
.addFilterAfter(samlFilter(), BasicAuthenticationFilter.class);
http.authorizeRequests().antMatchers("/error").permitAll().antMatchers("/saml/**").permitAll()
.anyRequest().authenticated();
http.logout().logoutSuccessUrl("/");
}
我的SAML安全配置如下所示
zuul:
ribbon:
eager-load:
enabled: true
host:
connect-timeout-millis: 5000000
socket-timeout-millis: 5000000
ignoredServices: ""
ignoredPatterns:
- /as/*
routes:
sensitiveHeaders: Cookie,Set-Cookie
import-data-service:
path: /ids/*
serviceId: IDS
stripPrefix: true
authentication-service:
path: /as/*
serviceId: AS
stripPrefix: true
customSensitiveHeaders: false
@Configuration
public class SamlSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public WebSSOProfileOptions defaultWebSSOProfileOptions() {
WebSSOProfileOptions webSSOProfileOptions = new WebSSOProfileOptions();
webSSOProfileOptions.setIncludeScoping(false);
webSSOProfileOptions.setBinding(SAMLConstants.SAML2_POST_BINDING_URI);
return webSSOProfileOptions;
}
@Bean
public SAMLEntryPoint samlEntryPoint() {
SAMLEntryPoint samlEntryPoint = new SAMLEntryPoint();
samlEntryPoint.setDefaultProfileOptions(defaultWebSSOProfileOptions());
return samlEntryPoint;
}
@Bean
public MetadataDisplayFilter metadataDisplayFilter() {
return new MetadataDisplayFilter();
}
@Bean
public SimpleUrlAuthenticationFailureHandler authenticationFailureHandler() {
return new SimpleUrlAuthenticationFailureHandler();
}
@Bean
public SavedRequestAwareAuthenticationSuccessHandler successRedirectHandler() {
SavedRequestAwareAuthenticationSuccessHandler successRedirectHandler =
new SavedRequestAwareAuthenticationSuccessHandler();
successRedirectHandler.setDefaultTargetUrl("https://my-domain/as/saml/SSO");
return successRedirectHandler;
}
@Bean
public SessionRepositoryFilter sessionFilter() {
HttpSessionStrategy cookieStrategy = new CookieHttpSessionStrategy();
MapSessionRepository repository = new MapSessionRepository();
((CookieHttpSessionStrategy) cookieStrategy).setCookieName("JSESSIONID");
SessionRepositoryFilter sessionRepositoryFilter = new SessionRepositoryFilter(repository);
sessionRepositoryFilter.setHttpSessionStrategy(cookieStrategy);
return sessionRepositoryFilter;
}
@Bean
public SAMLProcessingFilter samlWebSSOProcessingFilter() throws Exception {
SAMLProcessingFilter samlWebSSOProcessingFilter = new SAMLProcessingFilter();
samlWebSSOProcessingFilter.setAuthenticationManager(authenticationManager());
samlWebSSOProcessingFilter.setAuthenticationSuccessHandler(successRedirectHandler());
samlWebSSOProcessingFilter.setAuthenticationFailureHandler(authenticationFailureHandler());
return samlWebSSOProcessingFilter;
}
@Bean
public HttpStatusReturningLogoutSuccessHandler successLogoutHandler() {
return new HttpStatusReturningLogoutSuccessHandler();
}
@Bean
public SecurityContextLogoutHandler logoutHandler() {
SecurityContextLogoutHandler logoutHandler = new SecurityContextLogoutHandler();
logoutHandler.setInvalidateHttpSession(true);
logoutHandler.setClearAuthentication(true);
return logoutHandler;
}
@Bean
public SAMLLogoutFilter samlLogoutFilter() {
return new SAMLLogoutFilter(successLogoutHandler(), new LogoutHandler[] {logoutHandler()},
new LogoutHandler[] {logoutHandler()});
}
@Bean
public SAMLLogoutProcessingFilter samlLogoutProcessingFilter() {
return new SAMLLogoutProcessingFilter(successLogoutHandler(), logoutHandler());
}
@Bean
public MetadataGeneratorFilter metadataGeneratorFilter() {
return new MetadataGeneratorFilter(metadataGenerator());
}
@Bean
public MetadataGenerator metadataGenerator() {
MetadataGenerator metadataGenerator = new MetadataGenerator();
metadataGenerator.setEntityId("entityUniqueIdenifier");
metadataGenerator.setExtendedMetadata(extendedMetadata());
metadataGenerator.setIncludeDiscoveryExtension(false);
metadataGenerator.setRequestSigned(true);
metadataGenerator.setKeyManager(keyManager());
metadataGenerator.setEntityBaseURL("https://my-domain/as");
return metadataGenerator;
}
@Bean
public KeyManager keyManager() {
ClassPathResource storeFile = new ClassPathResource("/saml-keystore.jks");
String storePass = "samlstorepass";
Map<String, String> passwords = new HashMap<>();
passwords.put("mykeyalias", "mykeypass");
return new JKSKeyManager(storeFile, storePass, passwords, "mykeyalias");
}
@Bean
public ExtendedMetadata extendedMetadata() {
ExtendedMetadata extendedMetadata = new ExtendedMetadata();
extendedMetadata.setIdpDiscoveryEnabled(false);
extendedMetadata.setSignMetadata(false);
extendedMetadata.setSigningKey("mykeyalias");
extendedMetadata.setEncryptionKey("mykeyalias");
return extendedMetadata;
}
@Bean
public FilterChainProxy samlFilter() throws Exception {
List<SecurityFilterChain> chains = new ArrayList<>();
chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/metadata/**"),
metadataDisplayFilter()));
chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/login/**"),
samlEntryPoint()));
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/logout/**"),
samlLogoutFilter()));
chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/SingleLogout/**"),
samlLogoutProcessingFilter()));
return new FilterChainProxy(chains);
}
@Bean
public TLSProtocolConfigurer tlsProtocolConfigurer() {
return new TLSProtocolConfigurer();
}
@Bean
public ProtocolSocketFactory socketFactory() {
return new TLSProtocolSocketFactory(keyManager(), null, "default");
}
@Bean
public Protocol socketFactoryProtocol() {
return new Protocol("https", socketFactory(), 443);
}
@Bean
public MethodInvokingFactoryBean socketFactoryInitialization() {
MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean();
methodInvokingFactoryBean.setTargetClass(Protocol.class);
methodInvokingFactoryBean.setTargetMethod("registerProtocol");
Object[] args = {"https", socketFactoryProtocol()};
methodInvokingFactoryBean.setArguments(args);
return methodInvokingFactoryBean;
}
@Bean
public VelocityEngine velocityEngine() {
return VelocityFactory.getEngine();
}
@Bean(initMethod = "initialize")
public StaticBasicParserPool parserPool() {
return new StaticBasicParserPool();
}
@Bean(name = "parserPoolHolder")
public ParserPoolHolder parserPoolHolder() {
return new ParserPoolHolder();
}
@Bean
public HTTPPostBinding httpPostBinding() {
return new HTTPPostBinding(parserPool(), velocityEngine());
}
@Bean
public HTTPRedirectDeflateBinding httpRedirectDeflateBinding() {
return new HTTPRedirectDeflateBinding(parserPool());
}
@Bean
public SAMLProcessorImpl processor() {
Collection<SAMLBinding> bindings = new ArrayList<>();
bindings.add(httpRedirectDeflateBinding());
bindings.add(httpPostBinding());
return new SAMLProcessorImpl(bindings);
}
@Bean
public HttpClient httpClient() {
return new HttpClient(multiThreadedHttpConnectionManager());
}
@Bean
public MultiThreadedHttpConnectionManager multiThreadedHttpConnectionManager() {
return new MultiThreadedHttpConnectionManager();
}
@Bean
public static SAMLBootstrap sAMLBootstrap() {
return new CustomSamlBootStrap();
}
@Bean
public SAMLDefaultLogger samlLogger() {
SAMLDefaultLogger samlDefaultLogger = new SAMLDefaultLogger();
samlDefaultLogger.setLogAllMessages(true);
samlDefaultLogger.setLogErrors(true);
return samlDefaultLogger;
}
@Bean
public SAMLContextProviderImpl contextProvider() {
SAMLContextProviderLB samlContextProviderLB = new SAMLContextProviderLB();
samlContextProviderLB.setServerName("my-domain/as");
samlContextProviderLB.setScheme("https");
samlContextProviderLB.setServerPort(443);
samlContextProviderLB.setIncludeServerPortInRequestURL(false);
samlContextProviderLB.setContextPath("");
// samlContextProviderLB.setStorageFactory(new EmptyStorageFactory());
return samlContextProviderLB;
}
// SAML 2.0 WebSSO Assertion Consumer
@Bean
public WebSSOProfileConsumer webSSOprofileConsumer() {
return new WebSSOProfileConsumerImpl();
}
// SAML 2.0 Web SSO profile
@Bean
public WebSSOProfile webSSOprofile() {
return new WebSSOProfileImpl();
}
// not used but autowired...
// SAML 2.0 Holder-of-Key WebSSO Assertion Consumer
@Bean
public WebSSOProfileConsumerHoKImpl hokWebSSOprofileConsumer() {
return new WebSSOProfileConsumerHoKImpl();
}
// not used but autowired...
// SAML 2.0 Holder-of-Key Web SSO profile
@Bean
public WebSSOProfileConsumerHoKImpl hokWebSSOProfile() {
return new WebSSOProfileConsumerHoKImpl();
}
@Bean
public SingleLogoutProfile logoutprofile() {
return new SingleLogoutProfileImpl();
}
@Bean
public ExtendedMetadataDelegate idpMetadata()
throws MetadataProviderException, ResourceException {
Timer backgroundTaskTimer = new Timer(true);
ResourceBackedMetadataProvider resourceBackedMetadataProvider =
new ResourceBackedMetadataProvider(backgroundTaskTimer,
new ClasspathResource("/IDP-metadata.xml"));
resourceBackedMetadataProvider.setParserPool(parserPool());
ExtendedMetadataDelegate extendedMetadataDelegate =
new ExtendedMetadataDelegate(resourceBackedMetadataProvider, extendedMetadata());
extendedMetadataDelegate.setMetadataTrustCheck(true);
extendedMetadataDelegate.setMetadataRequireSignature(false);
return extendedMetadataDelegate;
}
@Bean
@Qualifier("metadata")
public CachingMetadataManager metadata() throws MetadataProviderException, ResourceException {
List<MetadataProvider> providers = new ArrayList<>();
providers.add(idpMetadata());
return new CachingMetadataManager(providers);
}
@Bean
public SAMLUserDetailsService samlUserDetailsService() {
return new SamlUserDetailsServiceImpl();
}
@Bean
public SAMLWebSSOHoKProcessingFilter samlWebSSOHoKProcessingFilter() throws Exception {
final SAMLWebSSOHoKProcessingFilter filter = new SAMLWebSSOHoKProcessingFilter();
filter.setAuthenticationManager(authenticationManager());
filter.setAuthenticationSuccessHandler(successRedirectHandler());
filter.setAuthenticationFailureHandler(authenticationFailureHandler());
return filter;
}
@Bean
public SAMLAuthenticationProvider samlAuthenticationProvider() {
SAMLAuthenticationProvider samlAuthenticationProvider = new SAMLAuthenticationProvider();
samlAuthenticationProvider.setUserDetails(samlUserDetailsService());
samlAuthenticationProvider.setForcePrincipalAsString(false);
return samlAuthenticationProvider;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(samlAuthenticationProvider());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.exceptionHandling().authenticationEntryPoint(samlEntryPoint());
http.csrf().disable();
http.addFilterBefore(metadataGeneratorFilter(), ChannelProcessingFilter.class)
.addFilterAfter(samlFilter(), BasicAuthenticationFilter.class);
http.authorizeRequests().antMatchers("/error").permitAll().antMatchers("/saml/**").permitAll()
.anyRequest().authenticated();
http.logout().logoutSuccessUrl("/");
}
@配置
公共类SamlSecurityConfig扩展了WebSecurity配置适配器{
@豆子
公共网站soprofileoptions默认网站soprofileoptions(){
websoprofileoptions websoprofileoptions=新的websoprofileoptions();
websoprofileoptions.setIncludeScoping(false);
websoprofileoptions.setBinding(SAMLConstants.SAML2\u POST\u BINDING\u URI);
返回WebsProfileOptions;
}
@豆子
公共SamlentPoint SamlentPoint(){
SAMLEntryPoint SAMLEntryPoint=新的SAMLEntryPoint();
setDefaultProfileOptions(DefaultWebsProfileOptions());
返回samlEntryPoint;
}
@豆子
公共MetadataDisplayFilter MetadataDisplayFilter(){
返回新的MetadataDisplayFilter();
}
@豆子
公共SimpleRuthenticationFailureHandler身份验证FailureHandler(){
返回新的SimpleRuthenticationFailureHandler();
}
@豆子
public SavedRequestAwareAuthenticationSuccessHandler successRedirectHandler(){
SavedRequestStawareAuthenticationSuccessHandler successRedirectHandler=
新建SavedRequestAwareAuthenticationSuccessHandler();
successRedirectHandler.setDefaultTargetUrl(“https://my-domain/as/saml/SSO");
返回成功重定向处理程序;
}
@豆子
public SessionRepositoryFilter sessionFilter(){
HttpSessionStrategy cookieStrategy=新CookieHttpSessionStrategy();
MapSessionRepository repository=新建MapSessionRepository();
((CookieHttpSessionStrategy)cookieStrategy.setCookieName(“JSSessionID”);
SessionRepositoryFilter SessionRepositoryFilter=新建SessionRepositoryFilter(存储库);
setHttpSessionStrategy(cookieStrategy);
returnsessionrepositoryfilter;
}
@豆子
公共SAMLProcessingFilter samlWebSSOProcessingFilter()引发异常{
SAMLProcessingFilter samlWebSSOProcessingFilter=新建SAMLProcessingFilter();
samlWebSSOProcessingFilter.setAuthenticationManager(authenticationManager());
samlWebSSOProcessingFilter.setAuthenticationSuccessHandler(successRedirectHandler());
samlWebSSOProcessingFilter.setAuthenticationFailureHandler(authenticationFailureHandler());
返回samlWebSSOProcessingFilter;
}
@豆子
公共HttpStatusReturningLogoutSuccessHandler successLogoutHandler(){
返回新的HttpStatusReturningLogoutSuccessHandler();
}
@豆子
公共安全ContextLogoutHandler logoutHandler(){
SecurityContextLogoutHandler logoutHandler=新的SecurityContextLogoutHandler();
logoutHandler.setInvalidateHttpSession(true);
logoutHandler.setClearAuthentication(true);
返回logoutHandler;
}
@豆子
公共SAMLLogoutFilter SAMLLogoutFilter(){
返回新的SAMLLogoutFilter(successLogoutHandler(),newlogouthandler[]{LogoutHandler()},
新LogoutHandler[]{LogoutHandler()});
}
@豆子
公共SAMLLogoutProcessingFilter SAMLLogoutProcessingFilter(){
返回新的SAMLLogoutProcessingFilter(成功logoutHandler(),logoutHandler());
}
@豆子
公共MetadataGeneratorFilter MetadataGeneratorFilter(){
返回新的MetadataGeneratorFilter(metadataGenerator());
}
@豆子
公共元数据生成器元数据生成器(){
MetadataGenerator MetadataGenerator=新的MetadataGenerator();
metadataGenerator.setEntityId(“EntityUniqueIdentifier”);
setExtendedMetadata(extendedMetadata());
metadataGenerator.setIncludeDiscoveryExtension(false);
metadataGenerator.setRequestSigned(true);
setKeyManager(keyManager());
metadataGenerator.setEntityBaseURL(“https://my-domain/as");
返回元数据生成器;
}
@豆子
公钥管理器密钥管理器(){
ClassPathResourceStoreFile=新的ClassPathResource(“/saml keystore.jks”);
字符串storePass=“samlstorepass”;
Map passwords=new HashMap();
密码。输入(“mykeyalias”、“mykeypass”);
返回新的JKSKeyManager(storeFile、storePass、密码,“mykeyalias”);
}
@豆子
公共扩展元数据扩展元数据(){
ExtendedMetadata ExtendedMetadata=新的ExtendedMetadata();
extendedMetadata.SetIdDiscoveryEnabled(false);
extendedMetadata.setSignMetadata(false);
extendedMetadata.setSigningKey(“mykeyalias”);
setEncryptionKey(“mykeyalias”);
返回扩展元数据;
}
@豆子
public FilterChainProxy samlFilter()引发异常{
列表链=新的ArrayList();
add(新的DefaultSecurityFilterChain(新的AntPathRequestMatcher(“/saml/metadata/**”),
metadataDisplayFilter());
add(新的DefaultSecurityFilterChain(新的AntPathRequestMatcher(“/saml/login/**”),
samlEntryPoint());
添加(新的DefaultSecurityFilterChain(新的AntPathRequestMatcher(“/saml/SSO/**”),
samlWebSSOProcessingFilter());
添加(新的默认值)