8.Spring Security SAML 安全配置
8.安全配置
SAML扩展需要配置安全设置,其中包括用于数字签名和加密的加密材料,用于配置远程实体提供的可信加密材料的安全配置文件以及HTTPS连接的验证。
8.1密钥管理
SAML交换涉及使用加密技术进行数据签名和加密。与加密密钥的所有交互都通过接口org.springframework.security.saml.key.KeyManager完成。默认实现org.springframework.security.saml.key.JKSKeyManager依赖于包含所有私钥和公钥的单个JKS密钥库。KeyManager应该包含至少一个私钥,该私钥应该通过使用私钥的别名作为JKSKeyManager构造函数的一部分来标记为默认值。
如果您的应用程序并不需要创建数字签名和/或解密收到的消息,也可以使用空的实现不需要任何JKS文件密钥库- org.springframework.security.saml.key.EmptyKeyManager。例如,仅使用IDP初始化单点登录时就是这种情况。请注意,使用EmptyKeyManager时, 某些Spring SAML功能将不可用。这至少包括SP初始化的单点登录,单点登录,在ExtendedMetadata中使用其他密钥以及验证元数据签名。使用以下bean来初始化EmptyKeyManager:
<bean id="keyManager" class="org.springframework.security.saml.key.EmptyKeyManager"/>
8.1.1 JKS密钥库示例
示例应用程序包含一个默认的JKS密钥库,其中包含可用于测试目的的示例私有证书。密钥库定义为:
<bean id="keyManager" class="org.springframework.security.saml.key.JKSKeyManager">
<constructor-arg value="classpath:security/samlKeystore.jks"/>
<constructor-arg type="java.lang.String" value="nalle123"/>
<constructor-arg>
<map>
<entry key="apollo" value="nalle123"/>
</map>
</constructor-arg>
<constructor-arg type="java.lang.String" value="apollo"/>
</bean>
第一个参数指向使用的密钥存储文件,第二个参数包含密钥库的密码,第三个参数指向带有别名密码值对的私钥的密码。默认证书的别名是最后一个参数。
8.1.2生成和导入私钥
私钥(带有自签名证书或CA签名证书)用于对SAML邮件进行数字签名,加密其内容,在某些情况下还用于服务提供商应用程序的SSL / TLS客户端身份验证。SAML Extension在samlKeystore.jks中附带了一个带有别名apollo的默认私钥 ,可以用于初始测试,但出于安全原因,应该在早期开发阶段用自己的密钥替换。
如果您的IDP不需要由特定证书颁发机构签名的密钥,您可以使用Java实用程序keytool生成您自己的自签名密钥,例如:
keytool -genkeypair -alias some-alias -keypass changeit -keystore samlKeystore.jks
密钥库现在将包含与别名额外PrivateKeyEntry 的myKey可以导入到的KeyManager在securityContext.xml。
由证书颁发机构签名的密钥通常以.p12 / .pfx格式提供(或者可以使用OpenSSL转换为此类)并导入到Java密钥库,例如:
keytool -importkeystore -srckeystore key.p12 -srcstoretype PKCS12 -srcstorepass password \
-alias some-alias -destkeystore samlKeystore.jks -destalias some-alias \
-destkeypass changeit
以下命令可用于确定p12文件中的可用别名:
keytool -list -keystore key.p12 -storetype pkcs12
8.1.3导入公钥
用于解密传入数据并验证SAML消息和元数据中签名信任的加密材料存储在远程实体的元数据中或keyManager中。为了将额外的可信密钥导入密钥库运行,例如:
keytool -importcert -alias some-alias -file key.cer -keystore samlKeystore.jks
可以在ExtendedMetadataDelegate和ExtendedMetadata bean中引用导入的密钥,有关详细信息,请参见第7.2.4节“元数据签名验证”和第8.2节“安全配置文件”。
8.1.4加载SSL / TLS证书
直接SSL / TLS连接(与HTTP-Artifact绑定一起使用)需要验证服务器提供的公钥。的SSL提取工具可以用于提取由SSL / TLS的端点,例如具有提供的证书:
java -jar sslextractor-0.9.jar www.google.com 443
证书存储为.cer文件,可以作为常用公钥导入密钥库。有关为SSL / TLS连接配置信任的详细信息,请参见第8.2节“安全配置文件”。
8.2安全配置文件
身份提供者和服务提供者之间使用SAML协议交换消息涉及使用数字签名。签名通常使用非对称加密和公钥基础结构构建,公钥和私钥由可信证书颁发机构签名。签名可以使用XML签名直接应用于SAML消息的XML表示的一部分,也可以是用于传递SSL / TLS等消息的传输层的一部分。
签名验证分两个阶段执行。首先通过将作为签名的一部分包括的数字哈希与从内容计算的值进行比较来检查签名的有效性。随后,验证创建签名的一方是否被接收者信任。Spring Security SAML提供了两种机制来定义应该接受哪些签名 - 元数据互操作模式和PKIX模式。
安全配置文件在本地SP的扩展元数据中定义。可以使用属性securityProfile为XML签名单独定义配置文件,使用属性sslSecurityProfile为SSL / TLS签名定义配置文件。两个属性的值可以是metaiop 或pkix。有关使用扩展元数据的详细信息,请参阅第7章,元数据配置,以获取允许值的参考,请参见第7.3节“扩展元数据”。
8.2.1元数据互操作性配置文件(MetaIOP)
使用MetaIOP模式不会检查证书是否到期或撤销,并且不验证证书路径。这意味着哪个证书颁发机构颁发证书并不重要,因为使用其他机制(例如,通过安全元数据交换或元数据本身的数字签名)传达证书是否可信的事实。
当用于创建签名的证书包含在以下某个位置时,签名将被视为可信:
- 在远程实体的实体元数据中使用签名或未指定的密钥
- 在远程实体的扩展元数据的属性signingKey中指定的签名密钥
MetaIOP是用于验证XML签名的默认配置文件。有关此配置文件的详细信息请参见规范。
8.2.2 PKIX配置文件
使用PKIX配置文件,可以根据可信CA证书与相关证书之间的证书路径验证签名证书的信任。当可以构建从可信证书到经过验证的证书的路径时,证书是可信的。使用此配置文件证书可以检查到期和撤销。
用于PKIX签名验证的可信密钥(锚点)从以下位置组合:
- 在远程实体的实体元数据中使用签名或未指定的密钥
- 在远程实体的扩展元数据的属性signingKey中指定的签名密钥
- 在trustedKeys中指定的所有密钥远程实体的扩展元数据集,或者当属性为null时,密钥库中可用的所有密钥(默认值)
请注意,信任锚被视为自动受信任,并且不一定受叶子证书的所有检查(取决于您的安全提供程序实现)。您最好只使用CA和中间CA证书作为信任锚。如果要忽略XML元数据中可用的证书并仅使用手动设置的ExtendedMetadata中的设置 ,请将metadataResolver的 property useXmlMetadata设置为false:
<bean id="contextProvider" class="org.springframework.security.saml.context.SAMLContextProviderImpl">
<property name="metadataResolver">
<bean class="org.springframework.security.saml.trust.MetadataCredentialResolver">
<constructor-arg index="0" ref="metadata"/>
<constructor-arg index="1" ref="keyManager"/>
<property name="useXmlMetadata" value="false"/>
</bean>
</property>
</bean>
PKIX验证支持使用默认的底层Java安全提供程序(例如Sun JCE,BouncyCastle JCE)检查CRL(证书吊销列表)。
需要建议PKIX算法启用撤销检查。您可以通过自定义这么做pkixTrustEvaluator内SAMLContextProvider,看一个例子与性能forceRevocationEnabled和revocationEnabled波纹管。
默认情况下,验证算法仅使用CertPathBuilder。某些Java安全实现不支持此类中的撤销检查的完整功能集,并且仅在CertPathValidator中实现它们(例如,Sun提供程序仅支持自Java 1.8以来的CertPathBuilder中的OCSP)。您可以指示系统同时使用 CertPathBuilder和的CertPathValidator通过属性设置validateCertPath到真正的豆CertPathPKIXTrustEvaluator。
可以使用属性securityProvider自定义用于加载PKIX验证工厂的安全提供程序。
<bean id="contextProvider" class="org.springframework.security.saml.context.SAMLContextProviderImpl">
<property name="pkixTrustEvaluator">
<bean class="org.springframework.security.saml.trust.CertPathPKIXTrustEvaluator">
<property name="PKIXValidationOptions">
<bean class="org.opensaml.xml.security.x509.CertPathPKIXValidationOptions">
<property name="forceRevocationEnabled" value="true"/>
<property name="revocationEnabled" value="true"/>
</bean>
</property>
<property name="validateCertPath" value="true"/>
<property name="securityProvider" value="SUN"/>
</bean>
</property>
</bean>
Spring SAML使用标准的CertPath验证API。默认的Sun JCE提供程序支持基于证书的CRL分发点扩展(通过将系统属性com.sun.security.enableCRLDP设置为true)自动撤销检查,使用证书的授权信息访问(AIA)扩展定义的CRL点(通过设置系统属性)com.sun.security.enableAIAcaIssuers to true)和OCSP(通过将系统属性ocsp.enable设置为true)。有关详细信息,请参阅Java PKI程序员指南。如果您正在使用其他安全提供程序,请参阅其手册以获取 与PKIX相关的CertPathBuilder和CertPathValidator相关功能 算法。
您还可以通过扩展类org.springframework.security.saml.trust.PKIXInformationResolver并 使用您自己的CRL填充逻辑覆盖方法populateCRL来手动填充CRL 。填充的CRL会自动添加到PKIX验证机制中。需要 在contextProvider bean 中将自定义类设置为属性pkixResolver。
8.2.3自定义配置文件
用于验证给定SP / IDP组合的签名信任的引擎是在接口 org.springframework.security.saml.context.SAMLContextProvider的populateTrustEngine和populateSSLTrustEngine方法中创建的, 并且可以使用自定义实现覆盖。有关上下文自定义的详细信息,请参见第10.2节“上下文提供程序”。
8.3 HTTPS连接的主机名验证
与HTTPS服务的连接(例如,在工件解析期间)需要验证连接的主机名是否与服务的公共证书中定义的主机名相对应。默认情况下启用主机名验证。
验证可以通过设置ExtendedMetadata财产被禁用sslHostnameVerification 本地SP实体的allowAll。有关使用ExtendedMetadata的详细信息,请参见第7.3节“扩展元数据”。
可以在ExtendedMetadata参考第7.3节“扩展元数据”中找到所有支持的值。