Add ExternalIDClaim option for OAuth2 OIDC auth source (#37229)

This PR adds an External ID Claim Name configuration field to the OIDC
auth source. When set, Gitea uses the specified JWT claim as the user's
`ExternalID` instead of the default `sub` claim.

This PR fixes the bug when migrating from Azure AD V2 to OIDC. When an
admin migrates the same auth source to OIDC, goth's `openidConnect`
provider defaults to using the `sub` claim as `UserID`. However, Azure
AD's `sub` is a pairwise identifier:

> `sub`: The subject is a pairwise identifier and is unique to an
application ID. If a single user signs into two different apps using two
different client IDs, those apps receive two different values for the
subject claim.


https://learn.microsoft.com/en-us/entra/identity-platform/id-token-claims-reference#payload-claims

As a result, every existing user appears as a new account after
migration.

To fix this issue, Gitea should use `oid` claim for `UserID`.

> `oid`: This ID uniquely identifies the user across applications - two
different applications signing in the same user receives the same value
in the oid claim.

Note: The `oid` claim is not included in Azure AD tokens by default. The
`profile` scope must be added to the Scopes field of the auth source.
This commit is contained in:
Zettat123
2026-04-16 11:30:46 -06:00
committed by GitHub
parent 4a2bba9aed
commit b1bfca39f1
9 changed files with 225 additions and 2 deletions

View File

@@ -3180,6 +3180,8 @@
"admin.auths.oauth2_required_claim_name_helper": "Set this name to restrict login from this source to users with a claim with this name",
"admin.auths.oauth2_required_claim_value": "Required Claim Value",
"admin.auths.oauth2_required_claim_value_helper": "Set this value to restrict login from this source to users with a claim with this name and value",
"admin.auths.open_id_connect_external_id_claim": "External ID Claim Name (Optional)",
"admin.auths.open_id_connect_external_id_claim_helper": "Claim name to use as the user's external identity. Defaults to \"sub\". For Azure AD / Entra ID, set this to \"oid\" to maintain continuity when migrating from the Azure AD V2 provider. Note: the \"oid\" claim requires the \"profile\" scope to be included in the Scopes field above.",
"admin.auths.oauth2_group_claim_name": "Claim name providing group names for this source. (Optional)",
"admin.auths.oauth2_full_name_claim_name": "Full Name Claim Name. (Optional — if set, the user's full name will always be synchronized with this claim)",
"admin.auths.oauth2_ssh_public_key_claim_name": "SSH Public Key Claim Name",