- 我能够将我的应用程序(SP)与Okta(IDP)集成。
- 我将只执行 IDP 启动的登录。
- 但是 Okta 不会是我唯一的 IDP,我不想继续向我的应用程序添加新的 IDP 元数据 XML(因为这意味着我需要编辑我的 spring XML 文件并添加新的 IDP 并重新启动服务器)。
因此,我只想将 IDP x509证书(公钥)导入我的密钥库,并使用它们来验证我的 SAML 响应。这可能吗?或者换句话说,我想在运行时注册 IDP,而无需对我的应用程序进行任何更改或重新启动它。
如果是,您能否提供有关如何执行此操作的资源?
目前,我已经在我的应用程序的 spring xml 文件中提供了 Okta 的元数据 XML,如下所示。
<bean id="metadata" class="org.springframework.security.saml.metadata.MetadataManager">
<constructor-arg>
<list>
<bean class="org.opensaml.saml2.metadata.provider.FilesystemMetadataProvider">
<constructor-arg>
<value type="java.io.File">C:\DEV\idp_metadata\metadata.xml</value>
</constructor-arg>
<property name="parserPool" ref="parserPool" />
</bean>
</list>
</constructor-arg>
</bean>
谢谢
阿布舍克
我完成了对应用程序的更改,使其依赖于密钥库中存在的 IDP 证书。但需要注意的是,如果将来添加新的 IDP 证书,则需要重新启动服务器。
-
我将
securityProfile
更改为pkix
而不是默认metaIOP
<bean class="org.springframework.security.saml.metadata.ExtendedMetadataDelegate"> <constructor-arg> <bean class="org.opensaml.saml2.metadata.provider.ResourceBackedMetadataProvider"> <constructor-arg> <bean class="java.util.Timer" /> </constructor-arg> <constructor-arg> <bean class="org.opensaml.util.resource.FilesystemResource"> <constructor-arg value="${path.to.SP.metadata}" /> </bean> </constructor-arg> <property name="parserPool" ref="parserPool" /> </bean> </constructor-arg> <constructor-arg> <bean class="org.springframework.security.saml.metadata.ExtendedMetadata"> <property name="local" value="true" /> <property name="securityProfile" value="pkix" /> <property name="sslSecurityProfile" value="pkix" /> <property name="requireArtifactResolveSigned" value="false" /> <property name="requireLogoutRequestSigned" value="false" /> <property name="requireLogoutResponseSigned" value="false" /> <property name="idpDiscoveryEnabled" value="false" /> <property name="supportUnsolicitedResponse" value="true" /> </bean> </constructor-arg> </bean>
-
已将证书添加到 .jks 文件:
keytool -importcert -file certificate.txt -keystore keystore.jks -alias "Alias"
-
实施
SAMLContextProviderLB
并注入pkixresolver
<bean id="contextProvider" class="org.springframework.security.saml.context.SAMLContextProviderLB"> <property name="scheme" value="${saml.loadBalancer.scheme}" /> <property name="serverName" value="${saml.loadBalancer.serverName}" /> <property name="serverPort" value="${saml.loadBalancer.serverPort}" /> <property name="includeServerPortInRequestURL" value="${saml.loadBalancer.includeServerPortInRequestURL}" /> <property name="contextPath" value="/contextPath" /> <property name="pkixResolver"> <bean class="org.springframework.security.saml.trust.PKIXInformationResolver"> <constructor-arg index="0" ref="metadataCredResolver" /> <constructor-arg index="1" ref="metadata" /> <constructor-arg index="2" ref="trustedKeyManager" /> </bean> </property> <property name="storageFactory"> <bean class="org.springframework.security.saml.storage.EmptyStorageFactory" /> </property> </bean>
<bean id="metadataCredResolver" class="org.springframework.security.saml.trust.MetadataCredentialResolver"> <constructor-arg index="0" ref="metadata" /> <constructor-arg index="1" ref="trustedKeyManager" /> <property name="useXmlMetadata" value="false" /> </bean>
<bean id="trustedKeyManager" class="org.springframework.security.saml.key.JKSKeyManager"> <constructor-arg value="${saml.trust.jks.filePath}" /> <constructor-arg type="java.lang.String" value="${saml.trust.jks.password}" /> <constructor-arg> <map> <entry key="${saml.trust.jks.defaultKey.name}" value="${saml.trust.jks.defaultKey.password}" /> </map> </constructor-arg> <constructor-arg type="java.lang.String" value="${saml.trust.jks.defaultKey.name}" /> </bean>
-
实现了几个类来覆盖元数据 XML 的需求。
SAMLProcessorImpl
和WebSSOProfileConsumerImpl
我删除了对 getPeerEntityID
/getPeerEntityMetadata.getEntityID()
的依赖并将其替换为 response.getIssuer().getValue()
,因为两者必须相同才能使 SAML 正常工作。信任证书是从密钥库中获取的,密钥库在启动期间加载一次。
在我的下一次更新中,我将尝试弄清楚如何执行 .jks 文件的定时刷新以加载新证书。