By including the SAML IdP Spring Boot starter as a dependency you basically get a ready-to-go SAML IdP.
<dependency>
<groupId>se.swedenconnect.spring.saml.idp</groupId>
<artifactId>saml-idp-spring-boot-starter</artifactId>
<version>${saml.idp.version}</version>
</dependency>
You will need to supply application properties (described in Configuration Properties below) and also define at least one UserAuthenticationProvider bean. This bean contains the logic for user authentication. Normally, we need to redirect the user agent (browser) to a separate endpoint where user authentication is performed. In those cases the UserRedirectAuthenticationProvider is used.
See the supplied example IdP in this project (demo-boot-idp
), or perhaps even better the Swedish eID Reference IdP.
This section documents all properties that can be provided to configure the IdP.
Property | Description | Type | Default value |
---|---|---|---|
saml.idp.entity-id |
The Identity Provider SAML entityID. | String | Required - No default value |
saml.idp.base-url |
The Identity Provider base URL, i.e., the protocol, domain and context path. Must not end with an ‘/’. | String | Required - No default value |
saml.idp.hok-base-url |
The Identity Provider base URL for Holder-of-key support, i.e., the protocol, domain and context path. Must not end ‘/’. This setting is optional, and if HoK is being used and that requires a different IdP domain or context path this setting represents this base URL. | String | - |
saml.idp.requires-signed-requests |
Whether the IdP requires signed authentication requests. | Boolean | true |
saml.idp.clock-skew-adjustment |
Clock skew adjustment (in both directions) to consider for accepting messages based on their age. | Duration | 30 seconds |
saml.idp.max-message-age |
Maximum allowed age of received messages. | Duration | 3 minutes |
saml.idp.sso-duration-limit |
Based on a previous authentication, for how long may this authentication be re-used? Set to 0 seconds to disable SSO. | Duration | 1 hour |
saml.idp.credentials.* |
Configuration for IdP credentials, see Credentials Configuration below. | CredentialConfigurationProperties | No default value, but named beans may be provided (see below). |
saml.idp.endpoints.* |
Configuration for the endpoints that the IdP exposes, see Endpoints Configuration below. | EndpointsConfigurationProperties | See below. |
saml.idp.assertions.* |
Configuration for IdP Assertion issuance, see Assertion Settings Configuration below. | AssertionSettingsConfigurationProperties | See below. |
saml.idp.metadata.* |
Configuration for the SAML metadata produced (and published) by the IdP, see MetadataConfiguration below. | MetadataConfigurationProperties | See below. |
saml.idp-metadata-providers[].* |
A list of “metadata providers” that tells how the IdP downloads federation metadata. See Metadata Provider Configuration below. | MetadataProviderConfigurationProperties | See below. |
saml.idp.audit.* |
Audit logging configuration. See Audit Configuration below. | AuditRepositoryConfigurationProperties | See below. |
saml.idp.replay.* |
Configuration for message replay checking. See Replay Checker Configuration below. | ReplayCheckerConfigurationProperties | See below. |
saml.idp.session.module |
The session module to use. Supported values are “memory” and “redis”. Set to other value if you extend the IdP with your own session handling. | String | If Redis and Spring Session are available redis is the default, otherwise memory . |
The IdP needs to be configured with at least one credential (private key and certificate). Each of the credential types below may be created by declared named beans instead of using the property configuration.
See the credentials-support library for details about the PkiCredential type and how it is configured.
Property | Description | Type |
---|---|---|
default-credential.* |
The IdP default credential. This will be used if no specific credential is defined for the usages sign, encrypt or metadata signing. It is also possible to define the default credential by declaring a bean of type PkiCredential and name it saml.idp.credentials.Default . |
PkiCredentialConfigurationProperties |
sign.* |
The credential the IdP uses to sign (responses and assertions). It is also possible to define the signing credential by declaring a bean of type PkiCredential and name it saml.idp.credentials.Sign . |
PkiCredentialConfigurationProperties |
future-sign |
A certificate that will be the future signing certificate. Is set before a key-rollover is performed. It is also possible to define the future signing certificate by declaring a bean of type X509Certificate and name it saml.idp.credentials.FutureSign . |
Resource (pointing at a certificate resource) or a string that holds the PEM encoding of the certificate. |
encrypt.* |
The IdP encryption credential. This will be used by SP:s to encrypt data (the certificate) for the IdP (for example sign messages), and by the IdP to decrypt these messages. If no Sweden Connect features are used, no encrypt-credential is needed. It is also possible to define the encrypt credential by declaring a bean of type PkiCredential and name it saml.idp.credentials.Encrypt . |
PkiCredentialConfigurationProperties |
previous-encrypt.* |
The previous IdP encryption credential. Assigned after a key-rollover of the encrypt credential. It is also possible to define the previous encrypt credential by declaring a bean of type PkiCredential and name it saml.idp.credentials.PreviousEncrypt . |
PkiCredentialConfigurationProperties |
metadata-sign.* |
The credential the IdP uses to sign its published metadata. It is also possible to define the metadata signing credential by declaring a bean of type PkiCredential and name it saml.idp.credentials.MetadataSign .If no metadata sign credential is configured, the default credential will be used. If no default credential exists, metadata published will not be signed. |
PkiCredentialConfigurationProperties |
:raised_hand: It is recommended to use the Credential Bundles feature when configuring credentials. See the example below:
credential:
bundles:
keystore:
idp-store:
location: file:/opt/config/idp-credentials.jks
password: secret
type: JKS
jks:
sign:
name: "IdP Signature Credential"
store-reference: idp-store
key:
alias: sign
key-password: secret
encrypt:
name: "IdP Encrypt/decrypt Credential"
store-reference: idp-store
key:
alias: encrypt
key-password: secret
metadata:
name: "IdP Metadata Signing Credential"
store-reference: idp-store
key:
alias: metadata
key-password: secret
saml:
idp:
...
credentials:
sign:
bundle: sign
encrypt:
bundle: encrypt
metadata-sign:
bundle: metadata
endpoints:
...
There are many benefits in configuring all credentials in the same place, and for future versions of this library, this may be the only way to configure credentials.
Property | Description | Type | Default value |
---|---|---|---|
redirect-authn |
The endpoint where the Identity Provider receives authentication requests via HTTP redirect. | String | /saml2/redirect/authn |
post-authn |
The endpoint where the Identity Provider receives authentication requests via HTTP POST. | String | /saml2/post/authn |
hok-redirect-authn |
The endpoint where the Identity Provider receives authentication requests via HTTP redirect where Holder-of-key (HoK) is used. | String | - |
hok-post-authn |
The endpoint where the Identity Provider receives authentication requests via HTTP POST where Holder-of-key (HoK) is used. | String | - |
metadata |
The SAML metadata publishing endpoint. | String | /saml2/metadata |
Property | Description | Type | Default value |
---|---|---|---|
encrypt |
Tells whether the Identity Provider encrypts assertions. | Boolean | true |
not-after |
A setting that tells the time restrictions the IdP puts on an Assertion concerning “not on or after”. | Duration | 5 minutes |
not-before |
A setting that tells the time restrictions the IdP puts on an Assertion concerning “not before”. | Duration | 10 seconds. |
Property | Description | Type | Default value |
---|---|---|---|
template |
A template for the SAML metadata. This is an XML document containing (partial) SAML metadata. | Resource (pointing at a XML-file resource). | - |
cache-duration |
Tells how long the published metadata can remain in a cache. | Duration | 24 hours |
validity-period |
Tells for how long a published metadata entry should be valid. | Duration | 7 days |
digest-methods[] |
A list of algorithm URI:s representing the alg:DigestMethod elements to include in the metadata. |
List of strings. | - |
include-digest-methods -under-role |
Tells whether alg:DigestMethod elements should be placed in an Extensions element under the role descriptor (i.e., the IDPSSODescriptor ). If false , the alg:DigestMethod elements are included as elements in the Extensions element of the EntityDescriptor . |
Boolean | false |
signing-methods[].* |
The alg:SigningMethod elements to include in the metadata. Each element is configured with algorithm that identifier the algorithm by means of the URL defined for its use with the XML Signature specification, and optionally min-key-size which is the smallest key size, in bits, that the entity supports in conjunction with the algorithm and max-key-size which is the largest key size, in bits, that the entity supports in conjunction with the algorithm. |
List of MetadataConfigurationProperties.SigningMethod | - |
include-signing-methods -under-role |
Tells whether alg:SigningMethod elements should be placed in an Extensions element under the role descriptor (i.e., the IDPSSODescriptor ). If false , the alg:SigningMethod elements are included as elements in the Extensions element of the EntityDescriptor . |
Boolean | false |
encryption-methods[].* |
The md:EncryptionMethod elements that should be included under the md:KeyDescriptor for the encryption key. Note that these algorithms must match the configured encryption key. |
See Encryption Methods below. | - |
ui-info.* |
Configuration for the metadata UIInfo element. See the UIInfo class in MetadataConfigurationProperties for details. |
MetadataConfigurationProperties.UIInfo | - |
organization.* |
Settings for the Organization metadata element. See the Organization class in the MetadataConfigurationProperties for details. |
MetadataConfigurationProperties.Organization | - |
contact-persons.* |
A map of the metadata ContactPerson elements, where the key is the type and the value is a ContactPerson . |
MetadataConfigurationProperties.ContactPerson | - |
Property | Description | Type | Default value |
---|---|---|---|
algorithm |
The algorithm URI of the encryption method. | String | - |
key-size |
The key size. | Integer | - |
oaep-params |
The OAEP parameters (in Base64-encoding). | String | - |
digest-method |
If algorithm indicates a key transport algorithm where the digest algorithm needs to be given, this field should be set to this algorithm URI. |
String | - |
Property | Description | Type | Default value |
---|---|---|---|
location |
The location of the metadata. Can be an URL, a file, or even a classpath resource. | Resource | - |
https-trust-bundle |
If location is an HTTPS resource, this setting may be used to specify a Spring SSL Bundle that specifies the trusted root certificates to be used for TLS server certificate verification. If no bundle is given, the Java trust defaults will be used. |
String | - |
backup-location |
If the location setting is an URL, a “backup location” may be assigned to store downloaded metadata. |
File | - |
mdq |
If the location setting is an URL, setting the MDQ-flag means that the metadata MDQ (https://www.ietf.org/id/draft-young-md-query-17.html) protocol is used. |
Boolean | false |
validation-certificate |
The certificate used to validate the metadata. | Resource pointing at the certificate resource. | - |
http-proxy.* |
If the location setting is an URL and a HTTP proxy is required this setting configures this proxy.Note: This setting is only needed if you require another HTTP proxy that what is configured for the system, or if the system HTTP proxy settings are not set. If Java’s HTTP proxy settings are set (see Java Networking and Proxies), these settings will be used by the metadata provider. |
MetadataProviderConfigurationProperties.HttpProxy | - |
The SAML IdP Spring Boot starter offers automatic support for setting up a AuditEventRepository bean based on the below settings. Also see the Identity Provider Auditing page.
Property | Description | Type | Default value |
---|---|---|---|
file.log-file |
For audit logging to a file. | String | - |
log-system.logger-name |
For audit logging using the underlying logsystem. The logger-name property tells the name of the logger. This name is used when configuring the log system appender, for example to use Syslog. |
String | - |
log-system.log-level |
The log level to use. Possible values are “error”, “warn”, “info”, “debug” and “trace”. The default is “info”. | String | “info” |
in-memory.capacity |
For audit logging to an in-memory repository. Sets the capacity (number of stored events) of this repository. | Integer | - |
redis.name |
For logging to Redis. The name of the Redis list/time series object that will hold the audit events. | String | - |
redis.type |
For logging to Redis. The type of Redis storage - “list” or “timeseries”. Note that Redisson is required for Redis Timeseries. | String | - |
include-events[] |
A list of event ID:s for the events that will be logged to the repository. If not set, all events will be logged (except to excluded by the exclude-events ). |
List of strings | Empty list |
exclude-events[] |
A list of event ID:s to exclude from being logged to the repository. See also the include-events setting. |
List of strings | Empty list |
If no repository is configured and no AuditEventRepository bean exists, an in-memory
repository with the capacity
set to 1000
will be created.
The SAML IdP makes use of a MessageReplayChecker to protect against replay attacks (i.e., that an authentication request is “replayed”).
If no MessageReplayChecker bean is provided by the application the IdP Spring Boot starter will create this bean (using the configuration settings below).
Property | Description | Type | Default value |
---|---|---|---|
type |
The type of replay checker. Supported values are “memory” and “redis”. If set to “redis”, Redis must be available and configured. | String | If Redis is available, redis is the default, otherwise memory |
expiration |
For how long should authentication request ID:s be stored in the cache before they expire? | Duration | 5 minutes |
context |
Under which context should the cache be stored? Applies to repositories that persist/distribute the cache. | String | idp-replay-checker |
Redis may be used for session handling and/or replay checking.
How Redis is configured and setup for Spring Boot is described here:
:raised_hand: If you are not using Redis, but have Redis on your classpath make sure to disable the Redis health check by setting the management.health.redis.enabled
setting to false
.
The SAML IdP Spring Boot Starter defines a few extensions to the core Spring Redis configuration:
The setting spring.data.redis.ssl-ext.enable-hostname-verification
may be set to false
in
order to turn off hostname verification when SSL/TLS is configured (using SslBundles) for the Redis connection. This can
be useful during testing.
Example:
spring:
...
data:
redis:
...
ssl:
enabled: true
bundle: redis-tls-bundle
ssl-ext:
enable-hostname-verification: false
It Redisson is used for the Redis client, the starter also adds extended support to configure Redis clusters:
In order to configure Redis Clusters NAT translation for addresses have been added. This is done
so that the application knows how to reach the Redis cluster if it is not located on the same network.
This can be done under the key spring.data.redis.cluster-ext
. This property key is a list of
entries as described below:
Property | Description | Type |
---|---|---|
nat-translation[].from |
Address to translate from. e.g. “172.20.0.31:2001”. | String |
nat-translation[].to |
Address to translate to, e.g., “redis1.local.dev.swedenconnect.se:2001”. | String |
read-mode |
Set cluster read mode to either SLAVE , MASTER or MASTER_SLAVE . The default value is MASTER since read/write is highly coupled in Spring Session, selecting SLAVE can result in race-conditions leading to the session not being synchronized to the slave in time causing errors. |
String |
Example:
The three Redis nodes are exposed via NAT to the application on redis(1-3).local.dev.swedenconnect.se. But internally they refer to eachother as 172.20.0.3(1-3). When the application connects to the first node, it will reconfigure itself by reading the configuration from redis1.
Since the application is not located on the same network the connection will fail since those addresses are not located on the same network.
This solution is to add the configuration below that will re-map outgoing connections to the correct node.
spring:
...
data:
redis:
cluster:
nodes:
- redis1.local.dev.swedenconnect.se:2001
- redis2.local.dev.swedenconnect.se:2002
- redis3.local.dev.swedenconnect.se:2003
cluster-ext:
nat-translation:
- from: "172.20.0.31:2001"
to: "redis1.local.dev.swedenconnect.se:2001"
- from: "172.20.0.32:2002"
to: "redis2.local.dev.swedenconnect.se:2002"
- from: "172.20.0.33:2003"
to: "redis3.local.dev.swedenconnect.se:2003"
Copyright © 2022-2024, Myndigheten för digital förvaltning - Swedish Agency for Digital Government (DIGG). Licensed under version 2.0 of the Apache License.