feat(saml): add SignatureMethod config for SAML IDP (#10520)

# Which Problems Are Solved
When a SAML IDP is created, the signing algorithm defaults to
`RSA-SHA1`.
This PR adds the functionality to configure the signing algorithm while
creating or updating a SAML IDP. When nothing is specified, `RSA-SHA1`
is the default.

Available options:
* RSA_SHA1
* RSA_SHA256
* RSA_SHA512


# How the Problems Are Solved

By introducing a new optional config to specify the Signing Algorithm. 

# Additional Changes
N/A

# Additional Context
- Closes #9842 

An existing bug in the UpdateSAMLProvider API will be fixed as a
followup in a different
[PR](https://github.com/zitadel/zitadel/pull/10557).

---------

Co-authored-by: Stefan Benz <[email protected]>
This commit is contained in:
Gayathri Vijayan
2025-08-27 09:07:13 +00:00
committed by GitHub
co-authored by Stefan Benz
parent 6699a6f966
commit 255d42da65
42 changed files with 413 additions and 7 deletions
@@ -71,6 +71,15 @@
</div>
<div *ngIf="showOptional">
<div class="transient-info">
<cnsl-form-field class="formfield">
<cnsl-label>{{ 'IDP.SAML.SIGNATUREALGORITHM' | translate }}</cnsl-label>
<mat-select formControlName="signatureAlgorithm">
<mat-option *ngFor="let signatureAlgorithm of signatureAlgorithmValues" [value]="signatureAlgorithm">{{
signatureAlgorithm
}}</mat-option>
</mat-select>
</cnsl-form-field>
<cnsl-form-field class="formfield">
<cnsl-label>{{ 'IDP.SAML.NAMEIDFORMAT' | translate }}</cnsl-label>
<mat-select formControlName="nameIdFormat">
@@ -6,6 +6,7 @@ import {
Provider,
SAMLBinding,
SAMLNameIDFormat,
SAMLSignatureAlgorithm,
} from '../../../proto/generated/zitadel/idp_pb';
import { AbstractControl, FormControl, FormGroup } from '@angular/forms';
import { PolicyComponentServiceType } from '../../policies/policy-component-types.enum';
@@ -38,6 +39,7 @@ interface SAMLProviderForm {
metadataUrl: FormControl<string>;
binding: FormControl<string>;
withSignedRequest: FormControl<boolean>;
signatureAlgorithm: FormControl<string>;
nameIdFormat: FormControl<string>;
transientMappingAttributeName: FormControl<string>;
federatedLogoutEnabled: FormControl<boolean>;
@@ -65,6 +67,7 @@ export class ProviderSamlSpComponent {
private service!: ManagementService | AdminService;
bindingValues: string[] = getEnumKeys(SAMLBinding);
nameIDFormatValues: string[] = getEnumKeys(SAMLNameIDFormat);
signatureAlgorithmValues: string[] = Object.keys(SAMLSignatureAlgorithm);
public justCreated$: BehaviorSubject<string> = new BehaviorSubject<string>('');
public justActivated$ = new BehaviorSubject<boolean>(false);
@@ -131,6 +134,9 @@ export class ProviderSamlSpComponent {
private _initializeForm(): void {
const defaultBinding = getEnumKeyFromValue(SAMLBinding, SAMLBinding.SAML_BINDING_POST) || this.bindingValues[0];
const defaultSignatureAlgorithm =
getEnumKeyFromValue(SAMLSignatureAlgorithm, SAMLSignatureAlgorithm.SAML_SIGNATURE_UNSPECIFIED) ||
this.signatureAlgorithmValues[0];
const defaultNameIdFormat =
getEnumKeyFromValue(SAMLNameIDFormat, SAMLNameIDFormat.SAML_NAME_ID_FORMAT_PERSISTENT) || this.nameIDFormatValues[0];
@@ -141,6 +147,7 @@ export class ProviderSamlSpComponent {
metadataUrl: new FormControl('', { nonNullable: true }),
binding: new FormControl(defaultBinding, { nonNullable: true, validators: [requiredValidator] }),
withSignedRequest: new FormControl(true, { nonNullable: true, validators: [requiredValidator] }),
signatureAlgorithm: new FormControl(defaultSignatureAlgorithm, { nonNullable: true }),
nameIdFormat: new FormControl(defaultNameIdFormat, { nonNullable: true }),
transientMappingAttributeName: new FormControl('', { nonNullable: true }),
federatedLogoutEnabled: new FormControl(false, { nonNullable: true }),
@@ -223,6 +230,10 @@ export class ProviderSamlSpComponent {
}
req.setWithSignedRequest(this.withSignedRequest.value);
req.setBinding(SAMLBinding[this.binding.value as keyof typeof SAMLBinding]);
req.setSignatureAlgorithm(
SAMLSignatureAlgorithm[this.signatureAlgorithm.value as keyof typeof SAMLSignatureAlgorithm],
);
// @ts-ignore
req.setNameIdFormat(SAMLNameIDFormat[this.nameIDFormat.value as keyof typeof SAMLNameIDFormat]);
req.setTransientMappingAttributeName(this.transientMapping.value);
req.setFederatedLogoutEnabled(this.federatedLogoutEnabled.value);
@@ -260,6 +271,12 @@ export class ProviderSamlSpComponent {
req.setProviderOptions(this.options);
req.setBinding(SAMLBinding[this.binding.value as keyof typeof SAMLBinding]);
req.setWithSignedRequest(this.withSignedRequest.value);
if (this.signatureAlgorithm) {
// @ts-ignore
req.setSignatureAlgorithm(
SAMLSignatureAlgorithm[this.signatureAlgorithm.value as keyof typeof SAMLSignatureAlgorithm],
);
}
if (this.nameIDFormat) {
req.setNameIdFormat(SAMLNameIDFormat[this.nameIDFormat.value as keyof typeof SAMLNameIDFormat]);
}
@@ -343,6 +360,10 @@ export class ProviderSamlSpComponent {
return this.form.controls.nameIdFormat;
}
private get signatureAlgorithm(): FormControl<string> {
return this.form.controls.signatureAlgorithm;
}
private get transientMapping(): FormControl<string> {
return this.form.controls.transientMappingAttributeName;
}
+1
View File
@@ -2373,6 +2373,7 @@
"METADATAURL": "Metadata URL",
"BINDING": "Binding",
"SIGNEDREQUEST": "Signed Request",
"SIGNATUREALGORITHM": "Signature Algorithm",
"NAMEIDFORMAT": "NameID Format",
"TRANSIENTMAPPINGATTRIBUTENAME": "Custom Mapping Attribute Name",
"TRANSIENTMAPPINGATTRIBUTENAME_DESC": "Alternative attribute name to map the user in case the `nameid-format` returned is `transient`, e.g. `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress`"
+1
View File
@@ -2368,6 +2368,7 @@
"METADATAURL": "Metaadatok URL",
"BINDING": "Kötés",
"SIGNEDREQUEST": "Aláírt kérés",
"SIGNATUREALGORITHM": "Aláírási algoritmus",
"NAMEIDFORMAT": "NameID formátum",
"TRANSIENTMAPPINGATTRIBUTENAME": "Egyéni leképezési attribútumnév",
"TRANSIENTMAPPINGATTRIBUTENAME_DESC": "Alternatív attribútumnév a felhasználó leképezéséhez, ha a visszakapott `nameid-format` `transient`, pl. `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress`"
+1
View File
@@ -2150,6 +2150,7 @@
"METADATAURL": "URL metadata",
"BINDING": "Mengikat",
"SIGNEDREQUEST": "Permintaan yang Ditandatangani",
"SIGNATUREALGORITHM": "Algoritma tanda tangan",
"NAMEIDFORMAT": "Format ID Nama",
"TRANSIENTMAPPINGATTRIBUTENAME": "Nama Atribut Pemetaan Khusus",
"TRANSIENTMAPPINGATTRIBUTENAME_DESC": "Nama atribut alternatif untuk memetakan pengguna jika `format nameid` yang dikembalikan adalah `sementara`, mis. `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress`"
+1
View File
@@ -2370,6 +2370,7 @@
"METADATAURL": "Metadata URL",
"BINDING": "Binding",
"SIGNEDREQUEST": "署名付きリクエスト",
"SIGNATUREALGORITHM": "署名アルゴリズム",
"NAMEIDFORMAT": "NameIDフォーマット",
"TRANSIENTMAPPINGATTRIBUTENAME": "カスタム属性名",
"TRANSIENTMAPPINGATTRIBUTENAME_DESC": "NameIDフォーマットが`transient`の場合にユーザーをマッピングするためのカスタム属性名 (例: `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress`)"
+1
View File
@@ -2370,6 +2370,7 @@
"METADATAURL": "메타데이터 URL",
"BINDING": "바인딩",
"SIGNEDREQUEST": "서명된 요청",
"SIGNATUREALGORITHM": "서명 알고리즘",
"NAMEIDFORMAT": "NameID 형식",
"TRANSIENTMAPPINGATTRIBUTENAME": "사용자 매핑 속성 이름",
"TRANSIENTMAPPINGATTRIBUTENAME_DESC": "`nameid-format`이 `transient`인 경우 사용자 매핑에 사용할 대체 속성 이름, 예: `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress`"
+2 -1
View File
@@ -2369,7 +2369,8 @@
"METADATAXML": "Metadata Xml",
"METADATAURL": "Metadata URL",
"BINDING": "Binding",
"SIGNEDREQUEST": "Ondertekend Verzoek"
"SIGNEDREQUEST": "Ondertekend Verzoek",
"SIGNATUREALGORITHM": "Handtekeningalgoritme"
},
"TOAST": {
"SAVED": "Succesvol opgeslagen.",
+1
View File
@@ -2368,6 +2368,7 @@
"METADATAURL": "URL metadata",
"BINDING": "Legare",
"SIGNEDREQUEST": "Solicitare semnată",
"SIGNATUREALGORITHM": "Algoritm de semnătură",
"NAMEIDFORMAT": "Format ID nume",
"TRANSIENTMAPPINGATTRIBUTENAME": "Nume atribut mapare personalizat",
"TRANSIENTMAPPINGATTRIBUTENAME_DESC": "Nume alternativ de atribut pentru a mapa utilizatorul în cazul în care nameid-format returnat este tranzitoriu, de exemplu, http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
+1
View File
@@ -2373,6 +2373,7 @@
"METADATAURL": "Metadata URL",
"BINDING": "Binding",
"SIGNEDREQUEST": "İmzalı İstek",
"SIGNATUREALGORITHM": "İmza algoritması",
"NAMEIDFORMAT": "NameID Formatı",
"TRANSIENTMAPPINGATTRIBUTENAME": "Özel Eşleme Özellik Adı",
"TRANSIENTMAPPINGATTRIBUTENAME_DESC": "`nameid-format` `transient` döndürülmesi durumunda kullanıcıyı eşlemek için alternatif özellik adı, örn. `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress`"