Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| 261:integration:saml [2026/04/28 07:42] – [Enable SAML for Stages] Weinlein, Thomas | 261:integration:saml [2026/04/28 09:04] (current) – [Configure signing] Weinlein, Thomas | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== Configure SAML Authentication | + | ====== Configure SAML Authentication ====== |
| SAML stands for Security Assertion Markup Language. It is a current standard for authenticating users in a distributed system. | SAML stands for Security Assertion Markup Language. It is a current standard for authenticating users in a distributed system. | ||
| Line 59: | Line 59: | ||
| </ | </ | ||
| - | please | + | // |
| Line 100: | Line 100: | ||
| The most reliable way to configure the SAML Identity Provider (IdP) is to ask the access management team for the IdP metadata. | The most reliable way to configure the SAML Identity Provider (IdP) is to ask the access management team for the IdP metadata. | ||
| + | Store this metadata in '' | ||
| + | '' | ||
| + | <code xml> | ||
| + | <method type=" | ||
| + | < | ||
| + | [...] | ||
| + | < | ||
| + | [...] | ||
| + | </ | ||
| + | [...] | ||
| + | </ | ||
| + | </ | ||
| + | '' | ||
| + | <code properties> | ||
| + | idp.saml.metadata.path = file: | ||
| + | </ | ||
| - | From this metadata, you will be able to derive the parameters | + | A complete SAML configuration |
| - | + | < | |
| - | * EntityIdfromMetadata | + | <method type="SAML2" |
| - | + | <properties> | |
| - | * SingleSignOnServiceLocationFromMetadata (should | + | < |
| - | + | <property name="keystorePath" | |
| - | * DisplayName (alternative: | + | |
| - | + | <property | |
| - | * EMailAddress | + | <property |
| - | + | <property name="serviceProviderMetadataPath" | |
| - | for the following configuration: | + | <property |
| - | + | <property | |
| - | < | + | <property |
| - | <authentication | + | <property |
| - | | + | <property name=" |
| - | | + | <property name="mappedAttributes(${idp.saml.attribute.email})" |
| - | | + | < |
| - | + | </ | |
| - | <service-provider | + | < |
| - | providerId="yourStagesURL" | + | |
| - | | + | |
| - | + | ||
| - | </service-provider> | + | |
| - | + | ||
| - | | + | |
| - | providerId="EntityIDfromMetadata" | + | |
| - | providerUrl="SingleSignOnServiceLocationFromMetadata" | + | |
| - | | + | |
| - | sendBinding="urn: | + | |
| - | userFullnameTemplate=" | + | |
| - | + | ||
| - | <!-- userFullnameTemplate is used to build the user's full name from multiple IDP attributes | + | |
| - | as defined below as < | + | |
| - | In the example above the firstname and lastname attributes are concatenated speparated by a space. --> | + | |
| - | + | ||
| - | <!-- hardcoded magic value that specifies the NameID from the SAML reply --> | + | |
| - | < | + | |
| - | + | ||
| - | <!-- either | + | |
| - | <!--< | + | |
| - | <identity-provider-attribute | + | |
| - | <identity-provider-attribute | + | |
| - | + | ||
| - | <identity-provider-attribute | + | |
| - | + | ||
| - | <!-- This matches if the SAML assertion contains a SAML attribute "Organization" | + | |
| - | <!-- | + | |
| - | < | + | |
| - | id="Organization" | + | |
| - | pattern="External" | + | |
| - | | + | |
| - | defaultLicenseType="DEV" | + | |
| - | licensePoolIdent="" | + | |
| - | autocreateUser=" | + | |
| - | | + | |
| - | --> | + | |
| <!-- This is the default matcher, identified by id and pattern attributes set to " | <!-- This is the default matcher, identified by id and pattern attributes set to " | ||
| - | <identity-provider-attribute-match | + | < |
| - | id=" | + | id=" |
| - | pattern=" | + | pattern=" |
| - | | + | |
| - | defaultLicenseType=" | + | defaultLicenseType=" |
| - | licensePoolIdent=" | + | autocreateUser=" |
| - | autocreateUser=" | + | |
| /> | /> | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| - | | + | '' |
| - | | + | <code properties> |
| - | signature verification of the authentication response. | + | sp.id = https:// |
| - | The key data can also be copied from the IdP metadata. | + | #needs to be generated. Path needs to be relative to ${STAGES_ROOT} |
| - | If no signing certificate is specified, no signature | + | sp.saml.keystore.path = file: |
| - | validation will be performed. | + | #will be generated on first login page access (path needs to be relative to ${STAGES_ROOT}) |
| - | --> | + | sp.saml.metadata.path = file: |
| - | < | + | |
| - | <!-- MIIDCTCC...Qwgf5bXby+ug== --> | + | idp.saml.enabled = false |
| - | </ | + | #exported metadata from SAML IDP (path needs to be relative to ${STAGES_ROOT}) |
| + | idp.saml.metadata.path = file: | ||
| + | idp.saml.attribute.firstname | ||
| + | idp.saml.attribute.lastname | ||
| + | idp.saml.attribute.email = urn: | ||
| + | idp.saml.fullname.template = %firstname% %lastname% | ||
| + | idp.saml.autocreate = true | ||
| - | <!-- | + | user.default.username |
| - | In case the IDP only provides encrypted assertions specify | + | user.default.licenseType |
| - | | + | |
| - | IdP metadata. If no encryption certificate is specified, no encrypted | + | |
| - | | + | |
| - | --> | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | <!-- | + | |
| - | This identity provider statement with the " | + | |
| - | magic id enables local Stages logins to be available | + | |
| - | for selection between multiple identity providers | + | |
| - | (NOT IMPLEMENTED YET). | + | |
| - | If the authentication with the IdP fails and the " | + | |
| - | provider is enabled, the Stages login screen is shown, so | + | |
| - | the user may log in with a local user id. If it is not | + | |
| - | configured, the server answers with a 403 (Forbidden) | + | |
| - | status code. | + | |
| - | --> | + | |
| - | < | + | |
| - | </ | + | |
| </ | </ | ||
| Line 244: | Line 207: | ||
| <code xml> | <code xml> | ||
| - | <identity-provider-attribute-match | + | < |
| id=" | id=" | ||
| pattern=" | pattern=" | ||
| Line 279: | Line 242: | ||
| [...] | [...] | ||
| </ | </ | ||
| + | </ | ||
| + | |||
| + | ===== Configure signature validation ===== | ||
| + | |||
| + | By default Stages send authentication requests signed and expects assertions in the response as well as the response itself to be signed. | ||
| + | In case this is not supported by the IDP it can be disabled by setting the according property to **false**. | ||
| + | |||
| + | //Please use with care as it degrades security.// | ||
| + | <code xml> | ||
| + | <method type=" | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | ===== Configure multiple SAML IDPs ===== | ||
| + | |||
| + | Stages does now allow to configure multiple IDPs. Just add another authentication method of type SAML2 and ensure it has an **unique name**. E.g. | ||
| + | |||
| + | <code xml> | ||
| + | < | ||
| + | [...] | ||
| + | <method type=" | ||
| + | [...] | ||
| + | </ | ||
| + | <method type=" | ||
| + | [...] | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | This will create a SSO button on the login page for each IDP. | ||
| + | Please provide a user understandable naming by defining a translation property for each login.sso.[name] propertyin each supported language: | ||
| + | '' | ||
| + | <code properties> | ||
| + | login.sso.saml-idp-1 = Single Sign-On for company 1 | ||
| + | login.sso.saml-idp-2 = Single Sign-On for company 2 | ||
| </ | </ | ||