From 1a0588fef1c4be071ac328e660d6e42e446af5af Mon Sep 17 00:00:00 2001 From: Livio Spring Date: Fri, 26 Sep 2025 09:23:24 +0200 Subject: [PATCH] fix(idp): SAML signature algorithm (#10795) # Which Problems Are Solved https://github.com/zitadel/zitadel/pull/10520 added the possibility to specify the signature algorithm for SAML auth requests. After releasing, customer noticed that the Console UI would not correctly display the selected algorithm and that it was not used in the login V1. # How the Problems Are Solved - Correctly map the algorithm in the UI - Provide the option to the idp when creating a SAML request in login V1 # Additional Changes None # Additional Context - closes https://github.com/zitadel/zitadel/issues/10780 - closes https://github.com/zitadel/zitadel/issues/10792 - requires backport to v4.x --- .../provider-saml-sp.component.ts | 6 +++++ .../api/ui/login/external_provider_handler.go | 24 +++++++++++-------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/console/src/app/modules/providers/provider-saml-sp/provider-saml-sp.component.ts b/console/src/app/modules/providers/provider-saml-sp/provider-saml-sp.component.ts index 92fb0c6b3..337ed6a8b 100644 --- a/console/src/app/modules/providers/provider-saml-sp/provider-saml-sp.component.ts +++ b/console/src/app/modules/providers/provider-saml-sp/provider-saml-sp.component.ts @@ -315,11 +315,17 @@ export class ProviderSamlSpComponent { const samlConfig = this.provider.config.saml; const bindingKey = getEnumKeyFromValue(SAMLBinding, samlConfig.binding) || ''; const nameIdFormatKey = getEnumKeyFromValue(SAMLNameIDFormat, samlConfig.nameIdFormat) || ''; + const signatureAlgorithmKey = + getEnumKeyFromValue( + SAMLSignatureAlgorithm, + samlConfig.signatureAlgorithm || SAMLSignatureAlgorithm.SAML_SIGNATURE_UNSPECIFIED, + ) || ''; this.form.patchValue({ metadataXml: typeof samlConfig.metadataXml === 'string' ? samlConfig.metadataXml : '', binding: bindingKey, withSignedRequest: samlConfig.withSignedRequest, + signatureAlgorithm: signatureAlgorithmKey, nameIdFormat: nameIdFormatKey, transientMappingAttributeName: samlConfig.transientMappingAttributeName || '', federatedLogoutEnabled: samlConfig.federatedLogoutEnabled || false, diff --git a/internal/api/ui/login/external_provider_handler.go b/internal/api/ui/login/external_provider_handler.go index 514ff450f..461af46b5 100644 --- a/internal/api/ui/login/external_provider_handler.go +++ b/internal/api/ui/login/external_provider_handler.go @@ -1113,22 +1113,26 @@ func (l *Login) oauthProvider(ctx context.Context, identityProvider *query.IDPTe } func (l *Login) samlProvider(ctx context.Context, identityProvider *query.IDPTemplate) (*saml.Provider, error) { - key, err := crypto.Decrypt(identityProvider.SAMLIDPTemplate.Key, l.idpConfigAlg) + key, err := crypto.Decrypt(identityProvider.Key, l.idpConfigAlg) if err != nil { return nil, err } opts := make([]saml.ProviderOpts, 0, 6) - if identityProvider.SAMLIDPTemplate.WithSignedRequest { + if identityProvider.WithSignedRequest { opts = append(opts, saml.WithSignedRequest()) } - if identityProvider.SAMLIDPTemplate.Binding != "" { - opts = append(opts, saml.WithBinding(identityProvider.SAMLIDPTemplate.Binding)) + if identityProvider.Binding != "" { + opts = append(opts, saml.WithBinding(identityProvider.Binding)) } - if identityProvider.SAMLIDPTemplate.NameIDFormat.Valid { - opts = append(opts, saml.WithNameIDFormat(identityProvider.SAMLIDPTemplate.NameIDFormat.V)) + if identityProvider.WithSignedRequest && + identityProvider.SignatureAlgorithm != "" { + opts = append(opts, saml.WithSignatureAlgorithm(identityProvider.SignatureAlgorithm)) } - if identityProvider.SAMLIDPTemplate.TransientMappingAttributeName != "" { - opts = append(opts, saml.WithTransientMappingAttributeName(identityProvider.SAMLIDPTemplate.TransientMappingAttributeName)) + if identityProvider.NameIDFormat.Valid { + opts = append(opts, saml.WithNameIDFormat(identityProvider.NameIDFormat.V)) + } + if identityProvider.TransientMappingAttributeName != "" { + opts = append(opts, saml.WithTransientMappingAttributeName(identityProvider.TransientMappingAttributeName)) } opts = append(opts, saml.WithEntityID(http_utils.DomainContext(ctx).Origin()+"/idps/"+identityProvider.ID+"/saml/metadata"), @@ -1154,8 +1158,8 @@ func (l *Login) samlProvider(ctx context.Context, identityProvider *query.IDPTem return saml.New( identityProvider.Name, l.baseURL(ctx)+EndpointExternalLogin+"/", - identityProvider.SAMLIDPTemplate.Metadata, - identityProvider.SAMLIDPTemplate.Certificate, + identityProvider.Metadata, + identityProvider.Certificate, key, opts..., )