SAML Extension requires configuration of security settings which include cryptographic material used for digital signatures and encryption, security profiles for configuration of trusted cryptographic material provided by remote entities and verifications of HTTPS connections.
SAML exchanges involve usage of cryptography for signing and encryption of data. All interaction with cryptographic keys is done through interface org.springframework.security.saml.key.KeyManager. The default implementation org.springframework.security.saml.key.JKSKeyManager relies on a single JKS key store which contains all private and public keys. KeyManager should contain at least one private key which should be marked as default by using the alias of the private key as part of the JKSKeyManager constructor.
In case your application doesn't need to create digital signatures and/or decrypt incoming messages, it is possible to use an empty implementation of the keystore which doesn't require any JKS file - org.springframework.security.saml.key.EmptyKeyManager. This can be the case for example when using only IDP-Initialized single sign-on. Please note that when using the EmptyKeyManager some of Spring SAML features will be unavailable. This includes at least SP-initialized Single Sign-on, Single Logout, usage of additional keys in ExtendedMetadata and verification of metadata signatures. Use the following bean in order to initialize the EmptyKeyManager:
<bean id="keyManager" class="org.springframework.security.saml.key.EmptyKeyManager"/>
Sample application contains a default JKS key store with a sample private certificate usable for test purposes. The key store is defined as:
<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>
The first argument points to the used key store file, second contains password for the keystore, third then map with passwords for private keys with alias-password value pairs. Alias of the default certificate is the last parameter.
Private keys (with either self-signed or CA signed certificates) are used to digitally sign SAML messages, encrypt their content and in some cases for SSL/TLS Client authentication of your service provider application. SAML Extension ships with a default private key in the samlKeystore.jks with alias apollo which can be used for initial testing, but for security reason should be replaced with your own key in early development stages.
In case your IDP doesn't require keys signed by a specific certification authority you can generate your own self-signed key using the Java utility keytool, e.g. with:
keytool -genkeypair -alias some-alias -keypass changeit -keystore samlKeystore.jks
The keystore will now contain additional PrivateKeyEntry with alias mykey which can be imported to the keyManager in your securityContext.xml.
Keys signed by certification authorities are typically provided in .p12/.pfx format (or can be converted to such using OpenSSL) and imported to Java keystore with, e.g.:
keytool -importkeystore -srckeystore key.p12 -srcstoretype PKCS12 -srcstorepass password \ -alias some-alias -destkeystore samlKeystore.jks -destalias some-alias \ -destkeypass changeit
The following command can be used to determine available alias in the p12 file:
keytool -list -keystore key.p12 -storetype pkcs12
Cryptographic material used to decrypt incoming data and verify trust of signatures in SAML messages and metadata is stored either in metadata of remote entities or in the keyManager. In order to import additional trusted key to the keystore run, e.g.:
keytool -importcert -alias some-alias -file key.cer -keystore samlKeystore.jks
Imported keys can be referenced in ExtendedMetadataDelegate and ExtendedMetadata beans, for details see Section 7.2.4, “Metadata signature verification” and Section 8.2, “Security profiles”.
Direct SSL/TLS connections (used with HTTP-Artifact binding) require verification of the public key presented by the server. The SSL Extractor utility can be used to extract certificates presented by an SSL/TLS endpoint, e.g. with:
java -jar sslextractor-0.9.jar www.google.com 443
The certificates are stored as .cer files and can be imported to the keystore as a usual public key. For details about configuring of trust for SSL/TLS connections see Section 8.2, “Security profiles”.
Exchanges of messages between identity providers and service providers with SAML protocol involves usage of digital signatures. Signatures are typically constructed using means of asymmetric cryptography and public key infrastructure with public and private keys signed by trusted certification authorities. Signatures are either applied directly to parts of XML representation of SAML messages using XML Signature or are part of the transport layer used to deliver the message like SSL/TLS.
Verification of signatures is executed in two phases. Signature is first checked for validity by comparing digital hash included as part of the signature with value calculated from the content. Subsequently it is verified whether party who created the signature is trusted by the recipient. Spring Security SAML provides two mechanisms for defining which signatures should be accepted - metadata interoperability mode and PKIX mode.
Security profiles are defined in Extended Metadata of your local SP. Profile can be defined separately for XML Signatures using property securityProfile and for SSL/TLS Signatures using propertysslSecurityProfile. Value of both properties can be either metaiop or pkix. For details about using Extended Metadata see Chapter 7, Metadata configuration, for reference of allowed values see Section 7.3, “Extended metadata”.
With MetaIOP mode certificates are not checked for expiration or revocation and certificate paths are not verified. This means that it does not matter which certification authority issued the certificate, as the fact whether the certificate is trusted or not is conveyed using other mechanisms (e.g. by secure metadata exchange or digital signature of metadata itself).
Signature is deemed trusted when the certificate used to create it is included in one of the following places:
Key with usage of signing or unspecified in entity metadata of a remote entity
Signing key specified in property signingKey of extended metadata of a remote entity
MetaIOP is the default profile for verification of XML signatures. For details about this profile see the specification.
With PKIX profile trust of signature certificates is verified based on a certificate path between trusted CA certificates and the certificate in question. Certificate is trusted when it's possible to construct path from a trusted certificate to the validated one. With this profile certificate expiration and revocation can be checked.
Trusted keys (anchors) for PKIX verification of signatures are combined from the following places:
Key with usage of signing or unspecified in entity metadata of a remote entity
Signing key specified in property signingKey of extended metadata of a remote entity
All keys specified in trustedKeys set of extended metadata of a remote entity, or all keys available in the key store when the property is null (default value)
Please note that trust anchors are treated as automatically trusted and are not necessarily subject to all checks as leaf certificates are (depending on your security provider implementation). You should preferably use only your CA and intermediary CA certificates as trust anchors. In case you want to ignore certificates available in your XML metadata and only use settings from your manually set ExtendedMetadata, set property useXmlMetadata of your metadataResolver to 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 verification supports checking of CRLs (certificate revocation lists) using the default underlaying Java Security Provider (e.g. Sun JCE, BouncyCastle JCE).
The PKIX algorithm needs to be advised that the revocation checking is enabled. You can do so by customizing the pkixTrustEvaluator inside SAMLContextProvider, see an example with properties forceRevocationEnabled and revocationEnabled bellow.
By default the validation algorithm only uses the CertPathBuilder. Some Java security implementations do not support full feature set of revocation checking in this class and only implement them in the CertPathValidator (e.g. Sun provider only supports OCSP in CertPathBuilder since Java 1.8). You can instruct system to use both CertPathBuilder and CertPathValidator by setting property validateCertPath to true on bean CertPathPKIXTrustEvaluator.
The security provider used for loading of PKIX verification factories can be customized using property securityProvider.
<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 uses standard CertPath verification API. The default Sun JCE provider supports automatic revocation checking based on the certificate's CRL Distribution Points Extension (by setting system property com.sun.security.enableCRLDP to true), CRL point defined using certificate's Authority Information Access (AIA) Extension (by setting system property com.sun.security.enableAIAcaIssuers to true) and OCSP (by setting system property ocsp.enable to true). For details see the Java PKI Programmer's Guide. In case you are using another security provider, please consult its manual for functionality related to CertPathBuilder and CertPathValidator with the PKIX algorithm.
You can also manually populate CRLs by extending class org.springframework.security.saml.trust.PKIXInformationResolver and overriding method populateCRLs with your own CRL population logic. Populated CRLs are automatically added to the PKIX verification mechanism. The customized class needs to be set to property pkixResolver in the contextProvider bean.
Engine used to verify trust of signatures for given combination of SP/IDP is created in methods populateTrustEngine and populateSSLTrustEngine of interface org.springframework.security.saml.context.SAMLContextProvider and can be overridden with custom implementation. See Section 10.2, “Context provider” for details on context customization.
Connections to HTTPS services (e.g. during Artifact resolution) require verification that the connected hostname corresponds with the hostname defined in the service's public certificate. Hostname verification is enabled by default.
Verification can be disabled by setting ExtendedMetadata property sslHostnameVerification of the local SP entity to allowAll. For details on using the ExtendedMetadata see Section 7.3, “Extended metadata”.
All supported values can be found in the ExtendedMetadata reference Section 7.3, “Extended metadata”.