0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

refactor: update name ID format

This commit is contained in:
Darcy Ye 2024-12-12 15:53:43 +08:00
parent 8cac49bb48
commit e8cfde8d99
No known key found for this signature in database
GPG key ID: B46F4C07EDEFC610

View file

@ -18,6 +18,46 @@ import {
samlValueXmlnsXsi, samlValueXmlnsXsi,
} from '../libraries/consts.js'; } from '../libraries/consts.js';
// We only support email and persistent format at the moment.
const getSamlNameId = (user: IdTokenProfileStandardClaims, idpNameIDFormat?: string | string[]) => {
// If IdP has specified nameIDFormat, use it
if (idpNameIDFormat) {
// Get the first name ID format
const format = Array.isArray(idpNameIDFormat) ? idpNameIDFormat[0] : idpNameIDFormat;
// If email format is specified, try to use email first
if (
format === saml.Constants.namespace.format.emailAddress &&
user.email &&
user.email_verified
) {
return {
NameIDFormat: format,
NameID: user.email,
};
}
// For other formats or when email is not available, use sub
if (format === saml.Constants.namespace.format.persistent) {
return {
NameIDFormat: format,
NameID: user.sub,
};
}
}
// No nameIDFormat specified, use default logic
// Use email if available
if (user.email && user.email_verified) {
return {
NameIDFormat: saml.Constants.namespace.format.emailAddress,
NameID: user.email,
};
}
// Fallback to persistent format with user.sub
return {
NameIDFormat: saml.Constants.namespace.format.persistent,
NameID: user.sub,
};
};
export const createSamlTemplateCallback = export const createSamlTemplateCallback =
( (
idp: saml.IdentityProviderInstance, idp: saml.IdentityProviderInstance,
@ -30,7 +70,7 @@ export const createSamlTemplateCallback =
); );
const { nameIDFormat } = idp.entitySetting; const { nameIDFormat } = idp.entitySetting;
const selectedNameIDFormat = Array.isArray(nameIDFormat) ? nameIDFormat[0] : nameIDFormat; const { NameIDFormat, NameID } = getSamlNameId(user, nameIDFormat);
const id = `ID_${generateStandardId()}`; const id = `ID_${generateStandardId()}`;
const now = new Date(); const now = new Date();
@ -50,8 +90,8 @@ export const createSamlTemplateCallback =
ConditionsNotBefore: now.toISOString(), ConditionsNotBefore: now.toISOString(),
ConditionsNotOnOrAfter: expireAt.toISOString(), ConditionsNotOnOrAfter: expireAt.toISOString(),
SubjectConfirmationDataNotOnOrAfter: expireAt.toISOString(), SubjectConfirmationDataNotOnOrAfter: expireAt.toISOString(),
NameIDFormat: selectedNameIDFormat, NameIDFormat,
NameID: user.sub, NameID,
InResponseTo: 'null', InResponseTo: 'null',
/** /**
* User attributes for SAML response * User attributes for SAML response
@ -62,6 +102,7 @@ export const createSamlTemplateCallback =
* @remarks * @remarks
* By examining the code provided in the link above, we can define all the attributes supported by the attribute mapping here. Only the attributes defined in the `loginResponseTemplate.attributes` added when creating the IdP instance will appear in the SAML response. * By examining the code provided in the link above, we can define all the attributes supported by the attribute mapping here. Only the attributes defined in the `loginResponseTemplate.attributes` added when creating the IdP instance will appear in the SAML response.
*/ */
attrSub: user.sub,
attrEmail: user.email, attrEmail: user.email,
attrName: user.name, attrName: user.name,
}; };
@ -237,6 +278,10 @@ export const setupSamlProviders = (
}, },
], ],
}, },
nameIDFormat: [
saml.Constants.namespace.format.emailAddress,
saml.Constants.namespace.format.persistent,
],
}); });
// eslint-disable-next-line new-cap // eslint-disable-next-line new-cap