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 1a0588fef1)
This commit is contained in:
Livio Spring
2025-09-26 09:23:24 +02:00
parent 9b9b3e0550
commit d9a4ae114e
2 changed files with 20 additions and 10 deletions

View File

@@ -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,

View File

@@ -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...,
)