mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 14:47:33 +00:00
feat: add PKCE option to generic OAuth2 / OIDC identity providers (#9373)
# Which Problems Are Solved Some OAuth2 and OIDC providers require the use of PKCE for all their clients. While ZITADEL already recommended the same for its clients, it did not yet support the option on the IdP configuration. # How the Problems Are Solved - A new boolean `use_pkce` is added to the add/update generic OAuth/OIDC endpoints. - A new checkbox is added to the generic OAuth and OIDC provider templates. - The `rp.WithPKCE` option is added to the provider if the use of PKCE has been set. - The `rp.WithCodeChallenge` and `rp.WithCodeVerifier` options are added to the OIDC/Auth BeginAuth and CodeExchange function. - Store verifier or any other persistent argument in the intent or auth request. - Create corresponding session object before creating the intent, to be able to store the information. - (refactored session structs to use a constructor for unified creation and better overview of actual usage) Here's a screenshot showing the URI including the PKCE params:  # Additional Changes None. # Additional Context - Closes #6449 - This PR replaces the existing PR (#8228) of @doncicuto. The base he did was cherry picked. Thank you very much for that! --------- Co-authored-by: Miguel Cabrerizo <doncicuto@gmail.com> Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com>
This commit is contained in:
@@ -110,6 +110,15 @@
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
|
||||
<div class="specific-oauth-option">
|
||||
<cnsl-info-section>
|
||||
<div>
|
||||
<p class="checkbox-desc">{{ 'IDP.USEPKCE_DESC' | translate }}</p>
|
||||
<mat-checkbox formControlName="usePkce">{{ 'IDP.USEPKCE' | translate }}</mat-checkbox>
|
||||
</div>
|
||||
</cnsl-info-section>
|
||||
</div>
|
||||
|
||||
<cnsl-provider-options
|
||||
[initialOptions]="provider?.config?.options"
|
||||
(optionsChanged)="options = $event"
|
||||
|
@@ -0,0 +1,8 @@
|
||||
.specific-oauth-option {
|
||||
max-width: 500px;
|
||||
|
||||
.checkbox-desc {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
}
|
@@ -28,6 +28,7 @@ import { ProviderNextService } from '../provider-next/provider-next.service';
|
||||
|
||||
@Component({
|
||||
selector: 'cnsl-provider-oauth',
|
||||
styleUrls: ['./provider-oauth.component.scss'],
|
||||
templateUrl: './provider-oauth.component.html',
|
||||
})
|
||||
export class ProviderOAuthComponent {
|
||||
@@ -88,6 +89,7 @@ export class ProviderOAuthComponent {
|
||||
userEndpoint: new UntypedFormControl('', [requiredValidator]),
|
||||
idAttribute: new UntypedFormControl('', [requiredValidator]),
|
||||
scopesList: new UntypedFormControl(['openid', 'profile', 'email'], []),
|
||||
usePkce: new UntypedFormControl(false),
|
||||
});
|
||||
|
||||
this.authService
|
||||
@@ -187,6 +189,7 @@ export class ProviderOAuthComponent {
|
||||
req.setClientSecret(this.clientSecret?.value);
|
||||
req.setScopesList(this.scopesList?.value);
|
||||
req.setProviderOptions(this.options);
|
||||
req.setUsePkce(this.usePkce?.value);
|
||||
|
||||
this.loading = true;
|
||||
this.service
|
||||
@@ -217,6 +220,7 @@ export class ProviderOAuthComponent {
|
||||
req.setClientSecret(this.clientSecret?.value);
|
||||
req.setScopesList(this.scopesList?.value);
|
||||
req.setProviderOptions(this.options);
|
||||
req.setUsePkce(this.usePkce?.value);
|
||||
|
||||
this.loading = true;
|
||||
this.service
|
||||
@@ -297,4 +301,8 @@ export class ProviderOAuthComponent {
|
||||
public get scopesList(): AbstractControl | null {
|
||||
return this.form.get('scopesList');
|
||||
}
|
||||
|
||||
public get usePkce(): AbstractControl | null {
|
||||
return this.form.get('usePkce');
|
||||
}
|
||||
}
|
||||
|
@@ -92,14 +92,22 @@
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
|
||||
<div class="id-token-mapping">
|
||||
<div class="specific-oidc-option">
|
||||
<cnsl-info-section>
|
||||
<div>
|
||||
<p class="checkbox-desc">{{ 'IDP.ISIDTOKENMAPPING_DESC' | translate }}</p>
|
||||
<mat-checkbox formControlName="isIdTokenMapping">{{ 'IDP.ISIDTOKENMAPPING' | translate }}</mat-checkbox>
|
||||
</div>
|
||||
</cnsl-info-section>
|
||||
|
||||
<cnsl-info-section>
|
||||
<div>
|
||||
<p class="checkbox-desc">{{ 'IDP.USEPKCE_DESC' | translate }}</p>
|
||||
<mat-checkbox formControlName="usePkce">{{ 'IDP.USEPKCE' | translate }}</mat-checkbox>
|
||||
</div>
|
||||
</cnsl-info-section>
|
||||
</div>
|
||||
|
||||
<cnsl-provider-options
|
||||
[initialOptions]="provider?.config?.options"
|
||||
(optionsChanged)="options = $event"
|
||||
|
@@ -1,5 +1,7 @@
|
||||
.id-token-mapping {
|
||||
max-width: 400px;
|
||||
.specific-oidc-option {
|
||||
max-width: 500px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.checkbox-desc {
|
||||
margin-top: 0;
|
||||
|
@@ -85,6 +85,7 @@ export class ProviderOIDCComponent {
|
||||
issuer: new UntypedFormControl('', [requiredValidator]),
|
||||
scopesList: new UntypedFormControl(['openid', 'profile', 'email'], []),
|
||||
isIdTokenMapping: new UntypedFormControl(),
|
||||
usePkce: new UntypedFormControl(false),
|
||||
});
|
||||
|
||||
this.route.data.pipe(take(1)).subscribe((data) => {
|
||||
@@ -165,6 +166,7 @@ export class ProviderOIDCComponent {
|
||||
req.setScopesList(this.scopesList?.value);
|
||||
req.setProviderOptions(this.options);
|
||||
req.setIsIdTokenMapping(this.isIdTokenMapping?.value);
|
||||
req.setUsePkce(this.usePkce?.value);
|
||||
|
||||
this.loading = true;
|
||||
this.service
|
||||
@@ -193,6 +195,7 @@ export class ProviderOIDCComponent {
|
||||
req.setScopesList(this.scopesList?.value);
|
||||
req.setProviderOptions(this.options);
|
||||
req.setIsIdTokenMapping(this.isIdTokenMapping?.value);
|
||||
req.setUsePkce(this.usePkce?.value);
|
||||
|
||||
this.loading = true;
|
||||
this.service
|
||||
@@ -261,4 +264,8 @@ export class ProviderOIDCComponent {
|
||||
public get isIdTokenMapping(): AbstractControl | null {
|
||||
return this.form.get('isIdTokenMapping');
|
||||
}
|
||||
|
||||
public get usePkce(): AbstractControl | null {
|
||||
return this.form.get('usePkce');
|
||||
}
|
||||
}
|
||||
|
@@ -2200,7 +2200,9 @@
|
||||
"REMOVED": "Премахнато успешно."
|
||||
},
|
||||
"ISIDTOKENMAPPING": "Съответствие от ID токен",
|
||||
"ISIDTOKENMAPPING_DESC": "Ако е избрано, информацията на доставчика се съответства от ID токена, а не от userinfo крайната точка."
|
||||
"ISIDTOKENMAPPING_DESC": "Ако е избрано, информацията на доставчика се съответства от ID токена, а не от userinfo крайната точка.",
|
||||
"USEPKCE": "Използвайте PKCE",
|
||||
"USEPKCE_DESC": "Определя дали параметрите code_challenge и code_challenge_method са включени в заявката за удостоверяване"
|
||||
},
|
||||
"MFA": {
|
||||
"LIST": {
|
||||
|
@@ -2213,7 +2213,9 @@
|
||||
"REMOVED": "Úspěšně odebráno."
|
||||
},
|
||||
"ISIDTOKENMAPPING": "Mapování z ID tokenu",
|
||||
"ISIDTOKENMAPPING_DESC": "Pokud je vybráno, informace o poskytovateli jsou mapovány z ID tokenu, nikoli z koncového bodu userinfo."
|
||||
"ISIDTOKENMAPPING_DESC": "Pokud je vybráno, informace o poskytovateli jsou mapovány z ID tokenu, nikoli z koncového bodu userinfo.",
|
||||
"USEPKCE": "Použijte PKCE",
|
||||
"USEPKCE_DESC": "Určuje, zda jsou v požadavku na ověření zahrnuty parametry code_challenge a code_challenge_method"
|
||||
},
|
||||
"MFA": {
|
||||
"LIST": {
|
||||
|
@@ -2204,7 +2204,9 @@
|
||||
"REMOVED": "Erfolgreich entfernt."
|
||||
},
|
||||
"ISIDTOKENMAPPING": "Zuordnung vom ID-Token",
|
||||
"ISIDTOKENMAPPING_DESC": "Legt fest, ob für das Mapping der Provider Informationen das ID-Token verwendet werden soll, anstatt des Userinfo-Endpoints."
|
||||
"ISIDTOKENMAPPING_DESC": "Legt fest, ob für das Mapping der Provider Informationen das ID-Token verwendet werden soll, anstatt des Userinfo-Endpoints.",
|
||||
"USEPKCE": "Verwenden Sie PKCE",
|
||||
"USEPKCE_DESC": "Bestimmt, ob die Parameter code_challenge und code_challenge_method in der Authentifizierungsanforderung enthalten sind"
|
||||
},
|
||||
"MFA": {
|
||||
"LIST": {
|
||||
|
@@ -2225,7 +2225,9 @@
|
||||
"REMOVED": "Removed successfully."
|
||||
},
|
||||
"ISIDTOKENMAPPING": "Map from the ID token",
|
||||
"ISIDTOKENMAPPING_DESC": "If selected, provider information gets mapped from the ID token, not from the userinfo endpoint."
|
||||
"ISIDTOKENMAPPING_DESC": "If selected, provider information gets mapped from the ID token, not from the userinfo endpoint.",
|
||||
"USEPKCE": "Use PKCE",
|
||||
"USEPKCE_DESC": "Determines whether the code_challenge and code_challenge_method params are included in the auth request"
|
||||
},
|
||||
"MFA": {
|
||||
"LIST": {
|
||||
|
@@ -2201,7 +2201,9 @@
|
||||
"REMOVED": "Eliminado con éxito."
|
||||
},
|
||||
"ISIDTOKENMAPPING": "Asignación del ID token",
|
||||
"ISIDTOKENMAPPING_DESC": "Si se selecciona, la información del proveedor se asigna desde el ID token, no desde el punto final de userinfo."
|
||||
"ISIDTOKENMAPPING_DESC": "Si se selecciona, la información del proveedor se asigna desde el ID token, no desde el punto final de userinfo.",
|
||||
"USEPKCE": "Usa PKCE",
|
||||
"USEPKCE_DESC": "Determina si los parámetros code_challenge y code_challenge_method son incluidos en la solicitud de autenticación."
|
||||
},
|
||||
"MFA": {
|
||||
"LIST": {
|
||||
|
@@ -2205,7 +2205,9 @@
|
||||
"REMOVED": "Suppression réussie."
|
||||
},
|
||||
"ISIDTOKENMAPPING": "Mappage depuis le jeton ID",
|
||||
"ISIDTOKENMAPPING_DESC": "Si sélectionné, les informations du fournisseur sont mappées à partir du jeton ID, et non à partir du point d'extrémité userinfo."
|
||||
"ISIDTOKENMAPPING_DESC": "Si sélectionné, les informations du fournisseur sont mappées à partir du jeton ID, et non à partir du point d'extrémité userinfo.",
|
||||
"USEPKCE": "Utiliser PKCE",
|
||||
"USEPKCE_DESC": "Détermine si les paramètres code_challenge et code_challenge_method sont inclus dans la demande d'authentification"
|
||||
},
|
||||
"MFA": {
|
||||
"LIST": {
|
||||
|
@@ -2223,7 +2223,9 @@
|
||||
"REMOVED": "Sikeresen eltávolítva."
|
||||
},
|
||||
"ISIDTOKENMAPPING": "Hozzárendelés az ID token alapján",
|
||||
"ISIDTOKENMAPPING_DESC": "Ha ezt választod, a szolgáltatói információkat az ID token alapján rendeljük hozzá, nem a userinfo végpontból."
|
||||
"ISIDTOKENMAPPING_DESC": "Ha ezt választod, a szolgáltatói információkat az ID token alapján rendeljük hozzá, nem a userinfo végpontból.",
|
||||
"USEPKCE": "PKCE használata",
|
||||
"USEPKCE_DESC": "Meghatározza, hogy a code_challenge és a code_challenge_method paraméterek szerepeljenek-e a hitelesítési kérelemben"
|
||||
},
|
||||
"MFA": {
|
||||
"LIST": {
|
||||
|
@@ -2006,7 +2006,9 @@
|
||||
"REMOVED": "Berhasil dihapus."
|
||||
},
|
||||
"ISIDTOKENMAPPING": "Peta dari token ID",
|
||||
"ISIDTOKENMAPPING_DESC": "Jika dipilih, informasi penyedia akan dipetakan dari token ID, bukan dari titik akhir info pengguna."
|
||||
"ISIDTOKENMAPPING_DESC": "Jika dipilih, informasi penyedia akan dipetakan dari token ID, bukan dari titik akhir info pengguna.",
|
||||
"USEPKCE": "Gunakan PKCE",
|
||||
"USEPKCE_DESC": "Menentukan apakah parameter code_challenge dan code_challenge_method disertakan dalam permintaan autentikasi"
|
||||
},
|
||||
"MFA": {
|
||||
"LIST": {
|
||||
|
@@ -2205,7 +2205,9 @@
|
||||
"REMOVED": "Rimosso con successo."
|
||||
},
|
||||
"ISIDTOKENMAPPING": "Mappatura dal token ID",
|
||||
"ISIDTOKENMAPPING_DESC": "Se selezionato, le informazioni del provider vengono mappate dal token ID, non dal punto finale userinfo."
|
||||
"ISIDTOKENMAPPING_DESC": "Se selezionato, le informazioni del provider vengono mappate dal token ID, non dal punto finale userinfo.",
|
||||
"USEPKCE": "Usa PKCE",
|
||||
"USEPKCE_DESC": "Determina se i parametri code_challenge e code_challenge_method sono inclusi nella richiesta di autenticazione"
|
||||
},
|
||||
"MFA": {
|
||||
"LIST": {
|
||||
|
@@ -2225,7 +2225,9 @@
|
||||
"REMOVED": "正常に削除されました。"
|
||||
},
|
||||
"ISIDTOKENMAPPING": "IDトークンからのマッピング",
|
||||
"ISIDTOKENMAPPING_DESC": "選択された場合、プロバイダ情報はIDトークンからマッピングされ、userinfoエンドポイントからではありません。"
|
||||
"ISIDTOKENMAPPING_DESC": "選択された場合、プロバイダ情報はIDトークンからマッピングされ、userinfoエンドポイントからではありません。",
|
||||
"USEPKCE": "PKCEを使用する",
|
||||
"USEPKCE_DESC": "code_challenge パラメータと code_challenge_method パラメータが認証リクエストに含まれるかどうかを決定します。"
|
||||
},
|
||||
"MFA": {
|
||||
"LIST": {
|
||||
|
@@ -2225,7 +2225,9 @@
|
||||
"REMOVED": "성공적으로 제거되었습니다."
|
||||
},
|
||||
"ISIDTOKENMAPPING": "ID 토큰에서 매핑",
|
||||
"ISIDTOKENMAPPING_DESC": "선택 시, 사용자 정보 엔드포인트가 아닌 ID 토큰에서 제공자 정보를 매핑합니다."
|
||||
"ISIDTOKENMAPPING_DESC": "선택 시, 사용자 정보 엔드포인트가 아닌 ID 토큰에서 제공자 정보를 매핑합니다.",
|
||||
"USEPKCE": "PKCE 사용",
|
||||
"USEPKCE_DESC": "code_challenge 및 code_challenge_method 매개변수가 인증 요청에 포함되는지 여부를 결정합니다"
|
||||
},
|
||||
"MFA": {
|
||||
"LIST": {
|
||||
|
@@ -2201,7 +2201,9 @@
|
||||
"REMOVED": "Успешно отстрането."
|
||||
},
|
||||
"ISIDTOKENMAPPING": "Совпаѓање од ID токен",
|
||||
"ISIDTOKENMAPPING_DESC": "Ако е избрано, информациите од провајдерот се мапираат од ID токенот, а не од userinfo крајната точка."
|
||||
"ISIDTOKENMAPPING_DESC": "Ако е избрано, информациите од провајдерот се мапираат од ID токенот, а не од userinfo крајната точка.",
|
||||
"USEPKCE": "Користете PKCE",
|
||||
"USEPKCE_DESC": "Определува дали параметрите code_challenge и code_challenge_method се вклучени во барањето за авторизација"
|
||||
},
|
||||
"MFA": {
|
||||
"LIST": {
|
||||
|
@@ -2220,7 +2220,9 @@
|
||||
"REMOVED": "Succesvol verwijderd."
|
||||
},
|
||||
"ISIDTOKENMAPPING": "Kaart van de ID token",
|
||||
"ISIDTOKENMAPPING_DESC": "Als geselecteerd, wordt provider informatie in kaart gebracht van de ID token, niet van de userinfo eindpunt."
|
||||
"ISIDTOKENMAPPING_DESC": "Als geselecteerd, wordt provider informatie in kaart gebracht van de ID token, niet van de userinfo eindpunt.",
|
||||
"USEPKCE": "Gebruik PKCE",
|
||||
"USEPKCE_DESC": "Bepaalt of de parameters code_challenge en code_challenge_method zijn opgenomen in het verificatieverzoek"
|
||||
},
|
||||
"MFA": {
|
||||
"LIST": {
|
||||
|
@@ -2204,7 +2204,9 @@
|
||||
"REMOVED": "Usunięto pomyślnie."
|
||||
},
|
||||
"ISIDTOKENMAPPING": "Mapowanie z tokena ID",
|
||||
"ISIDTOKENMAPPING_DESC": "Jeśli wybrane, informacje dostawcy są mapowane z tokena ID, a nie z punktu końcowego userinfo."
|
||||
"ISIDTOKENMAPPING_DESC": "Jeśli wybrane, informacje dostawcy są mapowane z tokena ID, a nie z punktu końcowego userinfo.",
|
||||
"USEPKCE": "Skorzystaj z PKCE",
|
||||
"USEPKCE_DESC": "Określa, czy parametry code_challenge i code_challenge_method są uwzględnione w żądaniu uwierzytelnienia"
|
||||
},
|
||||
"MFA": {
|
||||
"LIST": {
|
||||
|
@@ -2200,7 +2200,9 @@
|
||||
"REMOVED": "Removido com sucesso."
|
||||
},
|
||||
"ISIDTOKENMAPPING": "Mapeamento do token ID",
|
||||
"ISIDTOKENMAPPING_DESC": "Se selecionado, as informações do provedor são mapeadas a partir do token ID, e não do ponto final userinfo."
|
||||
"ISIDTOKENMAPPING_DESC": "Se selecionado, as informações do provedor são mapeadas a partir do token ID, e não do ponto final userinfo.",
|
||||
"USEPKCE": "Usar PKCE",
|
||||
"USEPKCE_DESC": "Determina se os parâmetros code_challenge e code_challenge_method estão incluídos na solicitação de autenticação"
|
||||
},
|
||||
"MFA": {
|
||||
"LIST": {
|
||||
|
@@ -2316,7 +2316,9 @@
|
||||
"REMOVED": "Удалено успешно."
|
||||
},
|
||||
"ISIDTOKENMAPPING": "Карта из ID-токена",
|
||||
"ISIDTOKENMAPPING_DESC": "Если этот флажок установлен, информация о поставщике сопоставляется с маркером идентификатора, а не с конечной точкой информации о пользователе."
|
||||
"ISIDTOKENMAPPING_DESC": "Если этот флажок установлен, информация о поставщике сопоставляется с маркером идентификатора, а не с конечной точкой информации о пользователе.",
|
||||
"USEPKCE": "Используйте ПКСЕ",
|
||||
"USEPKCE_DESC": "Определяет, включены ли параметры code_challenge и code_challenge_method в запрос аутентификации."
|
||||
},
|
||||
"MFA": {
|
||||
"LIST": {
|
||||
|
@@ -2229,7 +2229,9 @@
|
||||
"REMOVED": "Borttagen framgångsrikt."
|
||||
},
|
||||
"ISIDTOKENMAPPING": "Mappa från ID-token",
|
||||
"ISIDTOKENMAPPING_DESC": "Om valt, mappas leverantörsinformation från ID-token, inte från användarinfo-slutpunkten."
|
||||
"ISIDTOKENMAPPING_DESC": "Om valt, mappas leverantörsinformation från ID-token, inte från användarinfo-slutpunkten.",
|
||||
"USEPKCE": "Använd PKCE",
|
||||
"USEPKCE_DESC": "Avgör om parametrarna code_challenge och code_challenge_method ingår i autentiseringsbegäran"
|
||||
},
|
||||
"MFA": {
|
||||
"LIST": {
|
||||
|
@@ -2204,7 +2204,9 @@
|
||||
"REMOVED": "成功删除。"
|
||||
},
|
||||
"ISIDTOKENMAPPING": "从ID令牌映射",
|
||||
"ISIDTOKENMAPPING_DESC": "如果选中,提供商信息将从ID令牌映射,而不是从userinfo端点。"
|
||||
"ISIDTOKENMAPPING_DESC": "如果选中,提供商信息将从ID令牌映射,而不是从userinfo端点。",
|
||||
"USEPKCE": "使用PKCE",
|
||||
"USEPKCE_DESC": "确定 auth 请求中是否包含 code_challenge 和 code_challenge_method 参数"
|
||||
},
|
||||
"MFA": {
|
||||
"LIST": {
|
||||
|
Reference in New Issue
Block a user