From d9a4ae114e18e2631e4a24eef6d5479dbbdfe0e1 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 (cherry picked from commit 1a0588fef1c4be071ac328e660d6e42e446af5af) --- .../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 9db3f1a5682..d9fbf167b3f 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 514ff450fe2..461af46b517 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..., )