SAML metadata is an XML document which contains information necessary for interaction with SAML-enabled identity or service providers. The document contains e.g. URLs of endpoints, information about supported bindings, identifiers and public keys. Typically one metadata document will be generated for your own service provider and sent to all identity providers you want to enable single sign-on with. Similarly, each identity provider will make its own metadata available for you to import into your service provider application.
Each metadata document can contain definition for one or many identity or service providers and optionally can be digitally signed. Metadata can be customized either by direct modifications to the XML document, or using extended metadata. Extended metadata is added directly to the Spring configuration file and can contain additional options which are unavailable in the basic metadata document.
Service provider metadata contains keys, services and URLs defining SAML endpoints of your application. Metadata can be either generated automatically upon first request to the service, or it can be pre-created (see Chapter 11, Sample application). Once created metadata needs to be provided to the identity providers with whom we want to establish trust.
Automatic metadata generation is enabled by including the following filter in the Spring Security configuration:
<security:custom-filter before="FIRST" ref="metadataGeneratorFilter"/>
This filter is automatically invoked as part of the first request to a URL processed by Spring Security. In case there is no service provider metadata already specified (meaning property hostedSPName of the metadata bean is empty) filter will generate a new one.
By default metadata will be generated with the following values which can be customized by setting properties of the metadataGenerator bean:
Table 7.1. Metadata generator settings
Property | Description | Default value |
---|---|---|
entityBaseURL | Base URL to construct SAML endpoints from, needs to be a URL with protocol, server, port and context path. | Values from the request in format: scheme://server:port/contextPath |
entityId | Unique identifier of the service provider. | <entityBaseUrl>/saml/metadata |
id | XML identifier of the root metadata element referred in signature. | entityId with removed illegal characters (NCName) |
requestSigned | Flag indicating whether this service signs authentication requests. | true |
wantAssertionSigned | Flag indicating whether this service requires signed assertions. | true |
bindingsSSO | Bindings to be included in the metadata for WebSSO profile. Supported values are: POST, Artifact and PAOS. Order of bindings in the property determines order of endpoints in the generated metadata. | POST, Artifact |
bindingsHoKSSO | Bindings to be included in the metadata for WebSSO Holder-of-Key profile. Supported values are: POST and Artifact. Order of bindings in the property determines order of endpoints in the generated metadata. | |
bindingsSLO | Bindings to be included in the metadata for Single Logout profile. Supported values are: POST and Redirect. Order of bindings in the property determines order of endpoints in the generated metadata. | POST, Redirect |
assertionConsumerIndex | Index of assertion consumer point to be marked as default. | 0 |
includeDiscoveryExtension | When true generated metadata will contain extension indicating that it's able to consume response from an IDP Discovery service. | false |
nameID | Name identifiers to be included in the metadata. Supported values are: EMAIL, TRANSIENT, PERSISTENT, UNSPECIFIED and X509_SUBJECT. Order of NameIDs in the property determines order of NameIDs in the generated metadata. | EMAIL, TRANSIENT, PERSISTENT, UNSPECIFIED, X509_SUBJECT |
extendedMetadata | Additional settings such as security keys, entity alias, metadata signing, IDP discovery, ECP settings, security profiles and signature requirements can be specified in the ExtendedMetadata, see Section 7.3, “Extended metadata” for details. | no extended metadata |
In case property entityBaseURL
is not specified, it will be automatically generated based on values in the first HTTP request.
Generated value can be normalized to exclude standard 80/443 ports for http/https schemes by setting property normalizeBaseUrl
of the MetadataGeneratorFilter
to true
. It is recommended to provide the value explicitly in the configuration.
Providing an empty collection or null value to properties bindingsSSO, bindingsHoKSSO and bindingsSLO will disable and remove the given profile. For example the following setting removes the holder-of-key profile from the generated metadata, forces artifact binding for single sign-on and redirect binding for single logout:
<bean class="org.springframework.security.saml.metadata.MetadataGenerator"> <property name="bindingsSSO"><list><value>artifact</value></list></property> <property name="bindingsSLO"><list><value>redirect</value></list></property> <property name="bindingsHoKSSO"><list/></property> </bean>
By default generated metadata will not be digitally signed. Digital signature can be enabled using property
signMetadata
of the extendedMetadata bean.
In case application is deployed behind a reverse-proxy or other mechanism which makes the URL at the application server different
from the URL seen by client at least property entityBaseURL
should be set to a value e.g. https://www.server.com:8080
For details about load balancing see Section 10.1, “Reverse proxies and load balancers”.
In some situations it is beneficial to provide static version of the metadata document instead of the automatic generation. Need for manual changes in the metadata or fixing of production settings are some of those. A custom metadata document describing local SP application can be added by updating the metadata bean with correct ExtendedMetadata. Please follow these steps in order to do so:
Generate and download metadata, e.g. using the Metadata Administration -> Generate new service provider metadata option in the sample application's administration UI or using instructions in automatic metadata generator.
Store the metadata file as part of your project classpath, e.g. in WEB-INF/classes/metadata/localhost_sp.xml.
Disable the automatic metadata generator by removing the following custom filter from the securityContext.xml:
<security:custom-filter before="FIRST" ref="metadataGeneratorFilter"/>
Include the SP metadata in the metadata bean and mark the entity as local in the extended metadata. Make sure to specify the alias property in case it was used during metadata generation.
It is recommended to use the administration UI which also generates all the Spring declarations ready for inclusion in your securityContext.xml.
Configuration for pre-configured local metadata can look for example like this:
<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.ClasspathResource"> <constructor-arg value="/metadata/localhost_sp.xml"/> </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="metaiop"/> <property name="sslSecurityProfile" value="pkix"/> <property name="signMetadata" value="true"/> <property name="signingKey" value="apollo"/> <property name="encryptionKey" value="apollo"/> <property name="requireArtifactResolveSigned" value="false"/> <property name="requireLogoutRequestSigned" value="false"/> <property name="requireLogoutResponseSigned" value="false"/> <property name="idpDiscoveryEnabled" value="true"/> <property name="idpDiscoveryURL" value="https://www.server.com:8080/context/saml/discovery"/> <property name="idpDiscoveryResponseURL" value="https://www.server.com:8080/context/saml/login?disco=true"/> </bean> </constructor-arg> </bean>
Same instance of your application can include multiple statically declared local service providers each differentiated by its own unique alias and entity ID, see Section 7.4, “Multi-tenancy and entity alias” for details. In case your application defines multiple local service providers, set property hostedSPName of the metadata bean to the entity ID of the default one.
The file with pre-configured metadata doesn't need to include digital signature. Metadata will be automatically signed during runtime when property signMetadata is set to true.
For details about available settings of the ExtendedMetadata see Section 7.3, “Extended metadata”.
Metadata describing the default local application can be downloaded from URL:
https://www.server.com:8080/context/saml/metadata
In case the application is configured to contain multiple service providers metadata for each can be loaded by adding the alias:
https://www.server.com:8080/context/saml/login/alias/defaultAlias
URL for metadata download can be disabled by removing filter metadataDisplayFilter from the securityContext.xml.
Metadata is also available in the sample application's administration UI under Metadata information -> selected SP.
Metadata for identity providers is imported to the metadataManager in a similar way as pre-configured SP metadata. Metadata containing one or many identity providers can be added by providing an URL or a file. Processing of metadata and processing of SAML messages can be customized using properties of ExtendedMetadataDelegate and ExtendedMetadata.
File-based provider loads metadata from a file available in the filesystem or classpath.
<bean class="org.springframework.security.saml.metadata.ExtendedMetadataDelegate"> <constructor-arg> <bean class="org.opensaml.saml2.metadata.provider.FilesystemMetadataProvider"> <constructor-arg> <value type="java.io.File">classpath:security/idp.xml</value> </constructor-arg> <property name="parserPool" ref="parserPool"/> </bean> </constructor-arg> <constructor-arg> <bean class="org.springframework.security.saml.metadata.ExtendedMetadata"/> </constructor-arg> </bean>
Metadata is automatically refreshed in intervals specified by properties minRefreshDelay and maxRefreshDelay of the MetadataProvider bean.
HTTP-based provider loads metadata from an URL.
<bean class="org.springframework.security.saml.metadata.ExtendedMetadataDelegate"> <constructor-arg> <bean class="org.opensaml.saml2.metadata.provider.HTTPMetadataProvider"> <constructor-arg> <value type="java.lang.String">https://idp.ssocircle.com/idp-meta.xml</value> </constructor-arg> <constructor-arg> <!-- Timeout for metadata loading in ms --> <value type="int">5000</value> </constructor-arg> <property name="parserPool" ref="parserPool"/> </bean> </constructor-arg> <constructor-arg> <bean class="org.springframework.security.saml.metadata.ExtendedMetadata"/> </constructor-arg> </bean>
Metadata is automatically refreshed in intervals specified by properties minRefreshDelay and maxRefreshDelay of the MetadataProvider bean.
Alternatively class org.opensaml.saml2.metadata.provider.FileBackedHTTPMetadataProvider can be used to provide a backup in case URL is temporarily unavailable. File to use as backup is specified as third argument in the MetadataProvider bean constructor.
By default, loading of metadata using the HTTP-based provider over HTTPS performs trust verification configured in your JDK. In case you'd like to use certificates in your keyStore, add the following bean which changes the socketFactory used by the HTTP Client:
<bean class="org.springframework.security.saml.trust.httpclient.TLSProtocolConfigurer"/>
The TLSProtocolConfigurer instantiates TLSProtocolSocketFactory and registers is as a default socket factory for https protocol inside the HTTP Client used for metadata loading. The socket factory uses all public certificates present in the keyStore as trust anchors for PKIX validation. The used keys can be constrained with property trustedKeys.
The socket factory configured in this fashion is used for all metadata providers. It is possible to customize metadata loading on a per-provider basis by adding a configured HttpClient instance to the HTTPMetadataProvider constructor.
Importing of digitally signed metadata requires verification of signature's validity and trust. Metadata is not required to be signed by default. When present, signature is verified with PKIX algorithm and uses all public keys present in the configured keyManager as trust anchors. Make sure to include root CA certificate and intermediary CA certificates of the signature in your keyStore. For details see Section 8.1.3, “Importing public keys”.
You can limit certificates used to perform the verification by setting property metadataTrustedKeys of the ExtendedMetadataDelegate bean. The provided collection should contain aliases of keys to be used as trust anchors.
Signature verification can be disabled by setting property metadataTrustCheck to false in the ExtendedMetadataDelegate bean. Setting metadataRequireSignature to true will reject metadata unless it's digitally signed.
Extended metadata provides additional settings for customization of SAML exchanges between SP and IDP which are not supported in the standard SAML 2.0 metadata documents. Examples of such settings are requirements for message signing, IDP discovery and security profiles.
Extended metadata is defined using org.springframework.security.saml.metadata.ExtendedMetadata beans embedded inside ExtendedMetadataDelegate for each SP or IDP metadata definition. In case a single metadata document contains multiple identity providers (in multiple EntityDescriptor elements), extended metadata can be set separately for each of them using a map with entity IDs as keys, e.g.:
<bean class="org.springframework.security.saml.metadata.ExtendedMetadataDelegate"> <constructor-arg> metadata provider bean </constructor-arg> <constructor-arg> <!-- Default extended metadata for entities not specified in the map --> <bean class="org.springframework.security.saml.metadata.ExtendedMetadata"/> </constructor-arg> <constructor-arg> <!-- Extended metadata for specific IDPs --> <map> <entry key="https://idp.ssocircle.com"> <bean class="org.springframework.security.saml.metadata.ExtendedMetadata"/> </entry> </map> </constructor-arg> </bean>
The following table summarizes settings available in the extended metadata. The same class is used for both local service providers and remote identity providers; each value contains information about the entities it's valid for.
Table 7.2. Extended metadata settings
Property | Default | Entities | Description |
---|---|---|---|
local | false | local and remote | True for metadata of a local service provider. False for remote identity providers. |
alias | local only | Unique alias used to identify the selected local service provider based on used URL. See Section 7.4, “Multi-tenancy and entity alias”. | |
signMetadata | false | local only | When true generated metadata will be signed using XML Signature using certificate with alias of signingKey . |
idpDiscoveryEnabled | false | local only | When true system will initialize IDP discovery when no IDP is selected during SSO initialization. See Section 9.1, “IDP selection and discovery”. |
idpDiscoveryURL | internal discovery URL | local only | URL of the IDP discovery service. Only used when discovery is enabled. |
idpDiscoveryResponseURL | internal discovery URL | local only | URL expecting response from the IDP discovery service. Only used when discovery is enabled. |
ecpEnabled | false | local only | Property enables support for the SAML 2.0 ECP profile. See Section 10.4, “Enhanced client/proxy”. |
securityProfile | metaiop | local only | Security profile for verification of message signatures. See Section 8.2, “Security profiles”. |
sslSecurityProfile | pkix | local only | Security profile for vericiation of SSL/TLS endpoint trust. See Section 8.2, “Security profiles”. |
sslHostnameVerification | default | local only | Verification of hostnames for HTTPS calls (e.g. in Artifact resolution). Allowed values are default, defaultAndLocalhost, strict and allowAll. Value allowAll effectively disables hostname verification. All values are case-insensitive. For more details on the supported hostname verifications see Commons-SSL JavaDoc. |
signingAlgorithm | - | local only | Algorithm used to create digital signature on the metadata object. Typical values are https://www.w3.org/2000/09/xmldsig#rsa-sha1, https://www.w3.org/2001/04/xmldsig-more#rsa-sha256 and https://www.w3.org/2001/04/xmldsig-more#rsa-sha512. |
signingKey | - | local and remote | For local entities alias of private key used to create signatures. The default private key is used when no value is provided. For remote identity providers defines an additional public key used to verify signatures. |
encryptionKey | - | local and remote | For local entities alias of private key used to encrypt data. The default private key is used when no value is provided. For remote identity providers defines an additional public key used to decrypt data. |
tlsKey | - | local and remote | For local entities alias of private key used for SSL/TLS client authentication. No client authentication is used when value is not specified. For remote identity providers defines an additional public key used for trust resolution. |
trustedKeys | - | remote | Keys included as trusted anchors during PKIX evaluation. All keys in the keyStore are used as trust anchors with null value. Keys are only used with PKIX security profile. |
requireLogoutRequestSigned | true | local and remote | For local entities enables requirement of signed logout requests. For remote entities enables signing of requests sent to the IDP. |
requireLogoutResponseSigned | false | local and remote | For local entities enables requirement of signed logout responses. For remote entities enables signing of responses sent to the IDP. |
requireArtifactResolveSigned | true | remote only | Enables signing of artifact resolution requests sent to the remote identity providers. |
supportUnsolicitedResponse | true | remote only | Enables support for Unsolicited Responses (IDP-Initialized SSO) sent from this remote entity. |
For additional examples on setting up metadata and extended metadata see Section 7.1, “Service provider metadata” for local SP, and Section 7.2, “Identity provider metadata” for remote IDPs.
Spring SAML contains limited support for multi-tenancy. It is possible to define configuration for multiple instances of local service providers, where each can have different URLs and security settings. System is differentiating between the service provider instances using entity alias which is a unique identifier within deployment of Spring SAML.
Entity alias is appended to URLs of SAML endpoints and used by Spring SAML to identify the correct instance. For example for local service provider with entity alias customer123 the standard URL scheme://server:port/contextPath/saml/login becomes scheme://server:port/contextPath/saml/login/alias/customer123.
The entity alias functionality can only be used together with pre-configured metadata (see Section 7.1.2, “Pre-configured metadata”). The entity alias is specified in the extended metadata of each of the configured service providers.
Spring SAML doesn't enforce any limitations on which Identity Provider can be deliver messages to which of the local Service Providers. In case your application requires similar rules (for example only certain tenants can authenticate using a specific IDP), make sure to implement them for example in your SAMLUserDetailsService (for single sign-on).
Selection of the correct Service Provider instance based on URL is performed inside SAMLContextProviderImpl class.