SAML单点登录-spring-security-saml 整合使用

2022-07-24 09:47:46

SAML单点登录-spring-security-saml客户端SP
使用spring-security-saml搭建SAML协议的客户端,该依赖是spring框架的官方库,配置方便、文档详细。提供了包括单点登录、单点登出、获取sq元数据文件等接口,无需自己实现,参考:spring-security-saml与应用程序的集成

SpringBoot接入

Maven添加spring-security-saml依赖

pom配置:
注意:spring-security-saml2-core1.0.4-1.0.10版本用的是opensaml-2.6.6版本,而当前阿里云maven库中没有opensaml-2.6.6版本,所以spring-security-saml2-core需引用1.0.4之前的版本(1.0.3),否则打包时,会报opensaml-2.6.6版本没找到。-当前时间:2022-07-07
阿里云maven公开库查找地址:https://developer.aliyun.com/

<!--saml处理库--><dependency><groupId>org.opensaml</groupId><artifactId>xmltooling</artifactId><version>1.4.1</version></dependency><!--springboot saml--><dependency><groupId>org.springframework.security.extensions</groupId><artifactId>spring-security-saml2-core</artifactId><version>1.0.3.RELEASE</version></dependency>

application.yml配置:

sp:# 认证中心服务信息 -> IDP元数据URLidpMetadataUrl: http://localhost:8080/gc-starter-ac/idp/metadata# entityId,服务提供商唯一标识entityId: cas:saml:sp:springboot# 是否签名断言,则需要在idp上传sp的证书/公钥文件以供解密wantAssertionSigned:false# 是否签名元数据signMetadata:false# 签名算法signAlg: http://www.w3.org/2001/04/xmldsig-more#rsa-sha256# 是否启用服务发现。一个sp可以配置多个idp,启动服务发现允许进入idp选择页面选择idp,如果不启用的话默认使用idp列表的第一个idpDiscoveryEnable:true# 服务发现选择页面路由IdpSelectionPath: /saml/discovery# idp登录成功后的重定向的页面路由,也就是首页路由successLoginUrl: /landing# idp登录失败后的重定向的页面路由failLoginUrl: /error# 登出成功后跳转的页面路由successLogoutUrl: /# 密钥库设置jks:# jks文件位置path: classpath:/saml/samlKeystore.jks# jks密码password: nalle123# 私钥别名defaultKey: apollo

映射配置到bean:

/**
 * @Description: sp配置
 * @Author: thp-mac
 * @Date: 2022/7/7
 * @Version: 1.0
 **/@Data@Component@ConfigurationProperties(prefix="sp")publicclassSpConfig{privateString idpMetadataUrl;privateString entityId;privateBoolean wantAssertionSigned;privateBoolean signMetadata;privateString signAlg;privateBoolean idpDiscoveryEnable;privateStringIdpSelectionPath;privateString successLoginUrl;privateString failLoginUrl;privateString successLogoutUrl;privateJKS jks;@Dataclass JKS{privateString path;privateString password;privateString defaultKey;}}

准备登录成功后回调服务:
需要实现SAMLUserDetailsService

/**
 * @Description: saml登录成功会回调该服务,从samlCredential中获取idp返回的数据
 * @Author: thp-mac
 * @Date: 2022/7/7
 * @Version: 1.0
 **/publicclassSAMLUserDetailsServiceImplimplementsSAMLUserDetailsService{@OverridepublicObjectloadUserBySAML(SAMLCredential samlCredential)throwsUsernameNotFoundException{return samlCredential.getAttributes();}}

SP拦截等配置:

/*
 * Copyright 2021 Vincenzo De Notaris
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */importjava.util.ArrayList;importjava.util.Collection;importjava.util.HashMap;importjava.util.List;importjava.util.Map;importjava.util.Timer;importorg.apache.commons.httpclient.HttpClient;importorg.apache.commons.httpclient.MultiThreadedHttpConnectionManager;importorg.apache.velocity.app.VelocityEngine;importorg.opensaml.saml2.metadata.provider.HTTPMetadataProvider;importorg.opensaml.saml2.metadata.provider.MetadataProvider;importorg.opensaml.saml2.metadata.provider.MetadataProviderException;importorg.opensaml.xml.parse.ParserPool;importorg.opensaml.xml.parse.StaticBasicParserPool;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.beans.factory.annotation.Qualifier;importorg.springframework.beans.factory.DisposableBean;importorg.springframework.beans.factory.InitializingBean;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.core.io.DefaultResourceLoader;importorg.springframework.core.io.Resource;importorg.springframework.security.authentication.AuthenticationManager;importorg.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;importorg.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;importorg.springframework.security.config.annotation.web.builders.HttpSecurity;importorg.springframework.security.config.annotation.web.configuration.EnableWebSecurity;importorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;importorg.springframework.security.saml.SAMLAuthenticationProvider;importorg.springframework.security.saml.SAMLBootstrap;importorg.springframework.security.saml.SAMLDiscovery;importorg.springframework.security.saml.SAMLEntryPoint;importorg.springframework.security.saml.SAMLLogoutFilter;importorg.springframework.security.saml.SAMLLogoutProcessingFilter;importorg.springframework.security.saml.SAMLProcessingFilter;importorg.springframework.security.saml.SAMLWebSSOHoKProcessingFilter;importorg.springframework.security.saml.context.SAMLContextProviderImpl;importorg.springframework.security.saml.key.JKSKeyManager;importorg.springframework.security.saml.key.KeyManager;importorg.springframework.security.saml.log.SAMLDefaultLogger;importorg.springframework.security.saml.metadata.CachingMetadataManager;importorg.springframework.security.saml.metadata.ExtendedMetadata;importorg.springframework.security.saml.metadata.ExtendedMetadataDelegate;importorg.springframework.security.saml.metadata.MetadataDisplayFilter;importorg.springframework.security.saml.metadata.MetadataGenerator;importorg.springframework.security.saml.metadata.MetadataGeneratorFilter;importorg.springframework.security.saml.parser.ParserPoolHolder;importorg.springframework.security.saml.processor.HTTPArtifactBinding;importorg.springframework.security.saml.processor.HTTPPAOS11Binding;importorg.springframework.security.saml.processor.HTTPPostBinding;importorg.springframework.security.saml.processor.HTTPRedirectDeflateBinding;importorg.springframework.security.saml.processor.HTTPSOAP11Binding;importorg.springframework.security.saml.processor.SAMLBinding;importorg.springframework.security.saml.processor.SAMLProcessorImpl;importorg.springframework.security.saml.util.VelocityFactory;importorg.springframework.security.saml.websso.ArtifactResolutionProfile;importorg.springframework.security.saml.websso.ArtifactResolutionProfileImpl;importorg.springframework.security.saml.websso.SingleLogoutProfile;importorg.springframework.security.saml.websso.SingleLogoutProfileImpl;importorg.springframework.security.saml.websso.WebSSOProfile;importorg.springframework.security.saml.websso.WebSSOProfileConsumer;importorg.springframework.security.saml.websso.WebSSOProfileConsumerHoKImpl;importorg.springframework.security.saml.websso.WebSSOProfileConsumerImpl;importorg.springframework.security.saml.websso.WebSSOProfileECPImpl;importorg.springframework.security.saml.websso.WebSSOProfileImpl;importorg.springframework.security.saml.websso.WebSSOProfileOptions;importorg.springframework.security.web.DefaultSecurityFilterChain;importorg.springframework.security.web.FilterChainProxy;importorg.springframework.security.web.SecurityFilterChain;importorg.springframework.security.web.access.channel.ChannelProcessingFilter;importorg.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;importorg.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;importorg.springframework.security.web.authentication.logout.LogoutHandler;importorg.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;importorg.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;importorg.springframework.security.web.authentication.www.BasicAuthenticationFilter;importorg.springframework.security.web.csrf.CsrfFilter;importorg.springframework.security.web.util.matcher.AntPathRequestMatcher;@Configuration@EnableWebSecurity@EnableGlobalMethodSecurity(securedEnabled=true)publicclassWebSecurityConfigextendsWebSecurityConfigurerAdapterimplementsInitializingBean,DisposableBean{@javax.annotation.ResourceprivateSpConfig spConfig;privateTimer backgroundTaskTimer;privateMultiThreadedHttpConnectionManager multiThreadedHttpConnectionManager;publicvoidinit(){this.backgroundTaskTimer=newTimer(true);this.multiThreadedHttpConnectionManager=newMultiThreadedHttpConnectionManager();}publicvoidshutdown(){this.backgroundTaskTimer.purge();this.backgroundTaskTimer.cancel();this.multiThreadedHttpConnectionManager.shutdown();}@javax.annotation.ResourceprivateSAMLUserDetailsServiceImpl samlUserDetailsServiceImpl;// Initialization of the velocity engine@BeanpublicVelocityEnginevelocityEngine(){returnVelocityFactory.getEngine();}// XML parser pool needed for OpenSAML parsing@Bean(initMethod="initialize")publicStaticBasicParserPoolparserPool(){returnnewStaticBasicParserPool();}@Bean(name="parserPoolHolder")publicParserPoolHolderparserPoolHolder(){returnnewParserPoolHolder();}// Bindings, encoders and decoders used for creating and parsing messages@BeanpublicHttpClienthttpClient(){returnnewHttpClient(this.multiThreadedHttpConnectionManager);}// SAML Authentication Provider responsible for validating of received SAML// messages@BeanpublicSAMLAuthenticationProvidersamlAuthenticationProvider(){SAMLAuthenticationProvider samlAuthenticationProvider=newSAMLAuthenticationProvider();
        samlAuthenticationProvider.setUserDetails(samlUserDetailsServiceImpl);
        samlAuthenticationProvider.setForcePrincipalAsString(false);return samlAuthenticationProvider;}// Provider of default SAML Context@BeanpublicSAMLContextProviderImplcontextProvider(){returnnewSAMLContextProviderImpl();}// Initialization of OpenSAML library@BeanpublicstaticSAMLBootstrapsAMLBootstrap(){returnnewSAMLBootstrap();}// Logger for SAML messages and events@BeanpublicSAMLDefaultLoggersamlLogger(){returnnewSAMLDefaultLogger();}// SAML 2.0 WebSSO Assertion Consumer@BeanpublicWebSSOProfileConsumerwebSSOprofileConsumer(){returnnewWebSSOProfileConsumerImpl();}// SAML 2.0 Holder-of-Key WebSSO Assertion Consumer@BeanpublicWebSSOProfileConsumerHoKImplhokWebSSOprofileConsumer(){returnnewWebSSOProfileConsumerHoKImpl();}// SAML 2.0 Web SSO profile@BeanpublicWebSSOProfilewebSSOprofile(){returnnewWebSSOProfileImpl();}// SAML 2.0 Holder-of-Key Web SSO profile@BeanpublicWebSSOProfileConsumerHoKImplhokWebSSOProfile(){returnnewWebSSOProfileConsumerHoKImpl();}// SAML 2.0 ECP profile@BeanpublicWebSSOProfileECPImplecpprofile(){returnnewWebSSOProfileECPImpl();}@BeanpublicSingleLogoutProfilelogoutprofile(){returnnewSingleLogoutProfileImpl();}// sp密钥库// Central storage of cryptographic keys@BeanpublicKeyManagerkeyManager(){DefaultResourceLoader loader=newDefaultResourceLoader();Resource storeFile= loader.getResource(spConfig.getJks().getPath());String storePass= spConfig.getJks().getPassword();Map<String,String> passwords=newHashMap<String,String>();
        passwords.put(spConfig.getJks().getDefaultKey(), spConfig.getJks().getPassword());String defaultKey= spConfig.getJks().getDefaultKey();returnnewJKSKeyManager(storeFile, storePass, passwords, defaultKey);}@BeanpublicWebSSOProfileOptionsdefaultWebSSOProfileOptions(){WebSSOProfileOptions webSSOProfileOptions=newWebSSOProfileOptions();
        webSSOProfileOptions.setIncludeScoping(false);return webSSOProfileOptions;}// Entry point to initialize authentication, default values taken from// properties file@Bean
  • 作者:LuckyTHP
  • 原文链接:https://blog.csdn.net/asd54090/article/details/125653831
    更新时间:2022-07-24 09:47:46