- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
最近领导派了一个活儿, 需要把我们CAS系统的身份识别交给甲方的系统, 甲方的系统是SAML2.0的协议.
由于之前对SAML2.0协议了解不多,折腾了不少时间,在这里记录一下。以后忘掉还可以看看.
首先是关于SAML2.0协议的简单介绍,在B站找到一个还不错的视频。 https://www.bilibili.com/video/BV1sA411Y758/ 。
。
1. 配置cas.properties,让cas作为 SAML2.0 的 IDP(身份提供方) 。
这一步其实没啥用, 因为我是要对接别人的IDP 而不是让自己的cas成为IDP,如果需要自己建一个cas作为IDP的话可以参考 。
cas.properties: cas.authn.saml-idp.core.entity-id=${cas.server.name}/idp
build.gradle: implementation "org.apereo.cas:cas-server-support-saml-idp:${project.'cas.version'}"
配置完之后可以打开idp路径查看idp/metadata-> http://localhost:8888/cas/idp/metadata
上面两个配置完成后其实作为IDP还是不能运作的(未授权的服务),你要对外提供身份验证的话,除了别人配置你作为IDP, 你也需要知道是哪个服务在用你, 你还需要给SP(服务提供方)权限,并且配置sp的metadata 。
在/etc/cas/services下面配置sp的信息,测试环境的话可以配置得粗暴一点
saml2-10004.json:
{ "@class" : "org.apereo.cas.support.saml.services.SamlRegisteredService" , "serviceId" : ".+" , "name" : "SAMLService" , "id" : 10000003 , "evaluationOrder" : 10 , "metadataLocation" : "file:/etc/cas/config/sp-metadata-local.xml" }
sp-metadata-local.xml: 这个文件一般是sp提供的。里面一般包含EntityID, 签名和加密的共钥,以及支持的NameID格式。需要的属性字段(这里没有配属性字段).
<? xml version="1.0" encoding="UTF-8" ?> < md:EntityDescriptor ID ="_cb7748cb6778495398727ae8bfcaa72e62beea3" entityID ="liveramp-sp" validUntil ="2043-03-16T11:36:25.739Z" xmlns:md ="urn:oasis:names:tc:SAML:2.0:metadata" > < md:Extensions xmlns:alg ="urn:oasis:names:tc:SAML:metadata:algsupport" > < alg:SigningMethod Algorithm ="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" /> < alg:SigningMethod Algorithm ="http://www.w3.org/2001/04/xmldsig-more#rsa-sha384" /> < alg:SigningMethod Algorithm ="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512" /> < alg:SigningMethod Algorithm ="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /> < alg:SigningMethod Algorithm ="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256" /> < alg:SigningMethod Algorithm ="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384" /> < alg:SigningMethod Algorithm ="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512" /> < alg:SigningMethod Algorithm ="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1" /> < alg:SigningMethod Algorithm ="http://www.w3.org/2000/09/xmldsig#dsa-sha1" /> < alg:SigningMethod Algorithm ="http://www.w3.org/2001/04/xmldsig-more#hmac-sha256" /> < alg:SigningMethod Algorithm ="http://www.w3.org/2001/04/xmldsig-more#hmac-sha384" /> < alg:SigningMethod Algorithm ="http://www.w3.org/2001/04/xmldsig-more#hmac-sha512" /> < alg:SigningMethod Algorithm ="http://www.w3.org/2000/09/xmldsig#hmac-sha1" /> < alg:DigestMethod Algorithm ="http://www.w3.org/2001/04/xmlenc#sha256" /> < alg:DigestMethod Algorithm ="http://www.w3.org/2001/04/xmldsig-more#sha384" /> < alg:DigestMethod Algorithm ="http://www.w3.org/2000/09/xmldsig#sha1" /> </ md:Extensions > < md:SPSSODescriptor AuthnRequestsSigned ="false" WantAssertionsSigned ="false" protocolSupportEnumeration ="urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.0:protocol urn:oasis:names:tc:SAML:1.1:protocol" > < md:Extensions xmlns:init ="urn:oasis:names:tc:SAML:profiles:SSO:request-init" > < init:RequestInitiator Binding ="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Location ="http://localhost:8888/cas/login?client_name=IHG-SAML2.0-CLIENT" /> </ md:Extensions > < md:KeyDescriptor use ="signing" > < ds:KeyInfo xmlns:ds ="http://www.w3.org/2000/09/xmldsig#" > < ds:X509Data > < ds:X509Certificate > xxxx </ ds:X509Certificate > </ ds:X509Data > </ ds:KeyInfo > </ md:KeyDescriptor > < md:KeyDescriptor use ="encryption" > < ds:KeyInfo xmlns:ds ="http://www.w3.org/2000/09/xmldsig#" > < ds:X509Data > < ds:X509Certificate > xxxx </ ds:X509Certificate > </ ds:X509Data > </ ds:KeyInfo > </ md:KeyDescriptor > < md:SingleLogoutService Binding ="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location ="http://localhost:8888/cas/login?client_name=IHG-SAML2.0-CLIENT&logoutendpoint=true" /> < md:SingleLogoutService Binding ="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location ="http://localhost:8888/cas/login?client_name=IHG-SAML2.0-CLIENT&logoutendpoint=true" /> < md:SingleLogoutService Binding ="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location ="http://localhost:8888/cas/login?client_name=IHG-SAML2.0-CLIENT&logoutendpoint=true" /> < md:SingleLogoutService Binding ="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location ="http://localhost:8888/cas/login?client_name=IHG-SAML2.0-CLIENT&logoutendpoint=true" /> < md:NameIDFormat > urn:oasis:names:tc:SAML:2.0:nameid-format:transient </ md:NameIDFormat > < md:NameIDFormat > urn:oasis:names:tc:SAML:2.0:nameid-format:persistent </ md:NameIDFormat > < md:NameIDFormat > urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress </ md:NameIDFormat > < md:NameIDFormat > urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified </ md:NameIDFormat > < md:AssertionConsumerService Binding ="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location ="http://localhost:8888/cas/login?client_name=IHG-SAML2.0-CLIENT" index ="0" /> </ md:SPSSODescriptor > </ md:EntityDescriptor >
如果里面含有属性字段, sp-metadata.xml会多出一些内容:
< md:AttributeConsumingService index ="0" > < md:RequestedAttribute Name ="firstName" NameFormat ="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" isRequired ="false" /> < md:RequestedAttribute Name ="lastName" NameFormat ="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" isRequired ="false" /> < md:RequestedAttribute Name ="email" NameFormat ="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" isRequired ="false" /> < md:RequestedAttribute FriendlyName ="displayName" Name ="urn:oid:2.16.840.1.113730.3.1.241" NameFormat ="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired ="false" /> < md:RequestedAttribute FriendlyName ="cn" Name ="cn" NameFormat ="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired ="false" /> </ md:AttributeConsumingService >
。
2. 配置委托认证 。
1). cas的委托认证都是通过pac4j去做的, 所以先要加上pac4j的依赖.
build.gradle里加上依赖: implementation " org.apereo.cas:cas-server-support-pac4j-webflow:${project.'cas.version'} " 。
2) 修改cas.properties加上委托认证的配置 。
cas.authn.pac4j.core.lazy-init= false cas.authn.pac4j.saml[ 0].client-name=SAML2.0- CLIENT cas.authn.pac4j.saml[ 0].display-name= SAML # 如果是文件 file: /xxx/ xxx.xml cas.authn.pac4j.saml[ 0].identity-provider-metadata-path=https: // yd-dev.liverampapac.com/sso/idp/metadata cas.authn.pac4j.saml[ 0].keystore-path=file:/ private /etc/cas/config/saml2.0/cer/ samlKeystore.jks cas.authn.pac4j.saml[ 0].keystore-password= xxx cas.authn.pac4j.saml[ 0]. private -key-password= xxx cas.authn.pac4j.saml[ 0].service-provider-entity-id= xxxxx # this is important cas.authn.pac4j.saml[ 0].service-provider-metadata-path=file:/etc/cas/config/saml2.0/sp- metadata.xml # If false global logout may not work, it's depends on IDP settings cas.authn.pac4j.saml[0].sign-service-provider-logout-request= true
使用委托认证就是要把认证的行为交给IDP, 而自己成为SP. IDP跟SP之间的通信的安全,或者说他们之前的信任是需要证书支持的,一般在IDP和SP的metadata都会配置证书的公钥,当信息传到自己系统时, 用自己的私钥做验签/解密.
上面在cas.properties的改动里还有一个 sp-metadata.xml需要我们自己构建(下面这个sp-metadata.xml 最低配置其实只需要配两个公钥就能工作了,其它的cas会帮我们自动生成) 。
<?xml version="1.0" encoding="UTF-8"?> <md:EntityDescriptor ID="aabc3592a94845c6b38b88894e6d19415746a23" entityID ="liveramp-sp" xmlns:md ="urn:oasis:names:tc:SAML:2.0:metadata"> <md:SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="false" protocolSupportEnumeration ="urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.0:protocol urn:oasis:names:tc:SAML:1.1:protocol"> <md:KeyDescriptor use="signing"> <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:X509Data> <ds:X509Certificate> xxx </ds:X509Certificate> </ds:X509Data> </ds:KeyInfo> </md:KeyDescriptor> <md:KeyDescriptor use="encryption"> <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:X509Data> <ds:X509Certificate> xxx </ds:X509Certificate> </ds:X509Data> </ds:KeyInfo> </md:KeyDescriptor> <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:8888/cas/login?client_name=IHG-SAML2.0-CLIENT&logoutendpoint=true"/> <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="http://localhost:8888/cas/login?client_name=IHG-SAML2.0-CLIENT&logoutendpoint=true"/> <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://localhost:8888/cas/login?client_name=IHG-SAML2.0-CLIENT&logoutendpoint=true"/> <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://localhost:8888/cas/login?client_name=IHG-SAML2.0-CLIENT&logoutendpoint=true"/> <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat> <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format: transient </md:NameIDFormat> <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat> <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat> <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName</md:NameIDFormat> <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:8888/cas/login?client_name=IHG-SAML2.0-CLIENT" index="0"/> <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="http://localhost:8888/cas/login?client_name=IHG-SAML2.0-CLIENT" index="1"/> <!-- 配置在这里 sp/metadata并不会展示和实际起作用 需要在cas.properties中配置 --> <md:AttributeConsumingService index="0" xmlns:md ="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:saml ="urn:oasis:names:tc:SAML:2.0:assertion"> <!-- SAML V2.0 attribute syntax --> <md:RequestedAttribute isRequired="true" NameFormat ="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" Name ="cn" FriendlyName ="cn"/> < md:RequestedAttribute NameFormat ="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" Name ="urn:oid:2.16.840.1.113730.3.1.241" FriendlyName ="displayName"/> <md:RequestedAttribute Name="firstName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/> <md:RequestedAttribute Name="email" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/> <md:RequestedAttribute Name="lastName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/> </md:AttributeConsumingService> </md:SPSSODescriptor> </md:EntityDescriptor>
证书的生成如果觉得麻烦的话, 这里有一键生成工具,两个文件放一个目录下面 然后一键生成 ./gen. sh [*name] [*domain] [* passwd ] ,生成出来把crt文件的内容放到<X509Certificate>里面。jks文件路径和passwd也都需要配置到 。
cas.porperties里面. 。
gen.sh
#!/bin/ bash echo " 自动创建自定义证书 " region =$ 1 region_suffix =$ 2 pass =$ 3 if [[ " X$region " == " X " ]]; then echo " region is empty " exit 1 fi if [[ " X$region_suffix " == " X " ]]; then echo " region_suffix is empty " exit 1 fi if [[ ! -f " openssl.cnf " ]]; then echo " openssl.cnf file is not exist " exit 1 fi mkdir $region cp openssl.cnf $region/ cd $region mkdir demoCA cd demoCA mkdir private SAN = " [SAN]\nsubjectAltName=DNS:*.$region_suffix " subj = " /C=CN/ST=NT/L=NT/O=LIVERAMP-CN/OU=TS/CN=$region_suffix " echo " 生成CA根证书 " openssl genrsa -des3 -passout pass:$pass -out private/cakey.pem 2048 openssl req -sha256 -new -nodes -key private/cakey.pem - passin pass:$pass \ -x509 -days 3650 -out cacert.pem -subj " $subj " cd .. echo " 生成中间CA证书 " openssl genrsa -des3 -passout pass:$pass -out $region.key 2048 openssl req -new - key $region.key \ - passin pass:$pass \ -subj " $subj " - reqexts SAN \ -config <( cat openssl.cnf \ <(printf " $SAN " )) \ - out $region.csr echo " 移除密码 " cp $region.key $region.key.org openssl rsa -passin pass:$pass - in $region.key.org - out $region.key echo " 生成x509 crt证书 " openssl x509 - req \ -days 36500 \ - in $region.csr \ - signkey $region.key \ - out $region.crt \ - extensions SAN \ -extfile <( cat openssl.cnf <(printf " $SAN " )) echo " 查看crt证书 " openssl x509 -text - in $region.crt echo " 生成pkcs12 " openssl pkcs12 -passout pass:$pass -export - in $region.crt -inkey $region.key -out $region.p12 - CAfile $region.crt echo " 生成JKS " keytool -importkeystore -v -srckeystore $region.p12 -srcstoretype pkcs12 -srcstorepass $pass -destkeystore $region.jks -deststoretype pkcs12 -deststorepass $pass
HOME = . oid_section = new_oids [ new_oids ] tsa_policy1 = 1.2 . 3.4 . 1 tsa_policy2 = 1.2 . 3.4 . 5.6 tsa_policy3 = 1.2 . 3.4 . 5.7 [ ca ] default_ca = CA_default [ CA_default ] dir = ./ demoCA certs = $ dir / certs crl_dir = $ dir / crl database = $ dir / index.txt new_certs_dir = $ dir / newcerts certificate = $ dir / cacert.pem serial = $ dir / serial crlnumber = $ dir / crlnumber crl = $ dir / crl.pem private_key = $ dir /private/ cakey.pem x509_extensions = usr_cert name_opt = ca_default cert_opt = ca_default default_days = 365 default_crl_days = 30 default_md = default preserve = no policy = policy_match [ policy_match ] countryName = match stateOrProvinceName = match organizationName = match organizationalUnitName = optional commonName = supplied emailAddress = optional [ policy_anything ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional [ req ] default_bits = 2048 default_keyfile = privkey.pem distinguished_name = req_distinguished_name attributes = req_attributes x509_extensions = v3_ca string_mask = utf8only [ req_distinguished_name ] countryName = Country Name ( 2 letter code) countryName_default = AU countryName_min = 2 countryName_max = 2 stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = Some- State localityName = Locality Name (eg, city) 0 .organizationName = Organization Name (eg, company) 0 .organizationName_default = Internet Widgits Pty Ltd organizationalUnitName = Organizational Unit Name (eg, section) commonName = Common Name (e.g. server FQDN or YOUR name) commonName_max = 64 emailAddress = Email Address emailAddress_max = 64 [ req_attributes ] challengePassword = A challenge password challengePassword_min = 4 challengePassword_max = 20 unstructuredName = An optional company name [ usr_cert ] basicConstraints = CA:FALSE nsComment = " OpenSSL Generated Certificate " subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer [ v3_req ] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment [ v3_ca ] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer basicConstraints = critical,CA: true [ crl_ext ] authorityKeyIdentifier = keyid:always [ proxy_cert_ext ] basicConstraints = CA:FALSE nsComment = " OpenSSL Generated Certificate " subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer proxyCertInfo =critical,language: id -ppl-anyLanguage,pathlen: 3 ,policy:foo [ tsa ] default_tsa = tsa_config1 [ tsa_config1 ] dir = ./ demoCA serial = $ dir / tsaserial crypto_device = builtin signer_cert = $ dir / tsacert.pem certs = $ dir / cacert.pem signer_key = $ dir /private/ tsakey.pem signer_digest = sha256 default_policy = tsa_policy1 other_policies = tsa_policy2, tsa_policy3 digests = sha1, sha256, sha384, sha512 accuracy = secs: 1 , millisecs: 500 , microsecs: 100 clock_precision_digits = 0 ordering = yes tsa_name = yes ess_cert_id_chain = no ess_cert_id_alg = sha1
配置完这些,顺利的话可以在 http://localhost:8888/cas/sp/metadata 看到sp的元数据。 然后将这个元数据提供给IDP.
接下来在cas登录的时候, 应该可以从右侧看到IDP的名字,点一下试试能不能登录。如果不能的话, 说明配置还有一些问题.
3. 属性释放 Attribute Release (IDP需要配置),这个是为了本地测试配置的, 实际上如果IDP那边配置好了,是不用管这个的 。
作为IDP,当有SP登录成功时, 你需要确定将登录者的哪些属性给到SP, 可以配置services/xx.json 添加以下配置
" attributeReleasePolicy " : { " @class " : " org.apereo.cas.support.saml.services.PatternMatchingEntityIdAttributeReleasePolicy " , " allowedAttributes " : [ " java.util.ArrayList " , [ " cn " , " sn " , " email " , " firstName " , " lastName " ]], " fullMatch " : " true " , " reverseMatch " : " false " , " entityIds " : " .+ " }
。
4. 属性请求(SP需要配置) 。
当SP向IDP请求登录时, 希望IDP返回登录者的一些信息比如email之类的。 配置cas.properties 。
cas.authn.pac4j.saml[ 0 ].attribute-consuming-service-index= 0 cas.authn.pac4j.saml[ 0 ].requested-attributes[ 0 ].name= FirstName cas.authn.pac4j.saml[ 0 ].requested-attributes[ 0 ].nameFormat=urn:oasis:names:tc:SAML: 2.0 :attrname- format:basic cas.authn.pac4j.saml[ 0 ].requested-attributes[ 1 ].name= LastName cas.authn.pac4j.saml[ 0 ].requested-attributes[ 1 ].nameFormat=urn:oasis:names:tc:SAML: 2.0 :attrname- format:basic cas.authn.pac4j.saml[ 0 ].requested-attributes[ 2 ].name= email cas.authn.pac4j.saml[ 0 ].requested-attributes[ 2 ].nameFormat=urn:oasis:names:tc:SAML: 2.0 :attrname- format:basic #eduPersonNickname urn:oid: 2.16 . 840.1 . 113730.3 . 1.241 #cas.authn.pac4j.saml[ 0 ].requested-attributes[ 3 ].name=urn:oid: 2.16 . 840.1 . 113730.3 . 1.241 #cas.authn.pac4j.saml[ 0 ].requested-attributes[ 3 ].nameFormat=urn:oasis:names:tc:SAML: 2.0 :attrname- format:uri #cas.authn.pac4j.saml[ 0 ].requested-attributes[ 3 ].friendlyName= displayName #cas.authn.pac4j.saml[ 0 ].requested-attributes[ 4 ].name= cn #cas.authn.pac4j.saml[ 0 ].requested-attributes[ 4 ].nameFormat=urn:oasis:names:tc:SAML: 2.0 :attrname- format:uri #cas.authn.pac4j.saml[ 0 ].requested-attributes[ 4 ].friendlyName=cn
最后此篇关于CAS6.x+DelegatedAuthenticationSAML2.0配置记录的文章就讲到这里了,如果你想了解更多关于CAS6.x+DelegatedAuthenticationSAML2.0配置记录的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我是一名优秀的程序员,十分优秀!