fix(sso): bind Microsoft sign-in to the IdP identity, not the email claim
SSO picked the local account by the email/preferred_username claim, which Entra does not verify. Anyone able to present a matching email (another tenant with a multi-tenant issuer, or an editable attribute) could sign in as that user without a password. - The first SSO login links the account to "<iss>|<oid>" (new unique column User.ssoSubject); afterwards only that identity signs in, and a matching email from another identity is refused. - Multi-tenant issuers (common/organizations/consumers) disable SSO. - Emails are compared case-insensitively and stored lower-case, so [email protected] and [email protected] can no longer be two accounts; the migration lower-cases existing emails where that does not collide. - An admin changing a user's email clears the link. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
c4a11b4704
commit
a25265b88a
13 files changed
+239
-19
No files matched your search
+15
@@ -0,0 +1,15 @@
|
||||
-- Microsoft sign-in is bound to the IdP identity ("<iss>|<oid>"), set on the
|
||||
-- first SSO login; the unverified email claim no longer picks the account.
|
||||
ALTER TABLE "User" ADD COLUMN "ssoSubject" TEXT;
|
||||
CREATE UNIQUE INDEX "User_ssoSubject_key" ON "User"("ssoSubject");
|
||||
|
||||
-- Emails are compared case-insensitively from now on. Store existing ones
|
||||
-- lower-case, except where that would collide with another account - those
|
||||
-- stay as they are and are still found by the case-insensitive lookup.
|
||||
UPDATE "User" AS u
|
||||
SET "email" = lower(u."email")
|
||||
WHERE u."email" <> lower(u."email")
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM "User" AS o
|
||||
WHERE o."id" <> u."id" AND lower(o."email") = lower(u."email")
|
||||
);
|
||||
@@ -88,6 +88,11 @@ model User {
|
||||
// nach einer Passwortaenderung nicht bis zu 15 Minuten weiter funktioniert.
|
||||
passwordChangedAt DateTime?
|
||||
|
||||
// Unveraenderliche Identitaet beim Identity Provider ("<iss>|<oid>"),
|
||||
// gesetzt bei der ersten Microsoft-Anmeldung. Danach entscheidet nur sie,
|
||||
// nicht mehr der (unverifizierte) E-Mail-Claim, welches Konto sich anmeldet.
|
||||
ssoSubject String? @unique
|
||||
|
||||
refreshTokens RefreshToken[]
|
||||
|
||||
inspections Inspection[]
|
||||
|
||||
Reference in new issue
Block a user