diff --git a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSecurityStampValidatorCallback.cs b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSecurityStampValidatorCallback.cs new file mode 100644 index 0000000000..2adc65d497 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSecurityStampValidatorCallback.cs @@ -0,0 +1,33 @@ +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Identity; + +namespace Volo.Abp.Identity.AspNetCore +{ + public class AbpSecurityStampValidatorCallback + { + /// + /// Implements callback for SecurityStampValidator's OnRefreshingPrincipal event. + /// https://github.com/IdentityServer/IdentityServer4/blob/main/src/AspNetIdentity/src/SecurityStampValidatorCallback.cs + /// + public class SecurityStampValidatorCallback + { + /// + /// Maintains the claims captured at login time that are not being created by ASP.NET Identity. + /// This is needed to preserve claims such as idp, auth_time, amr. + /// + /// The context. + /// + public static Task UpdatePrincipal(SecurityStampRefreshingPrincipalContext context) + { + var newClaimTypes = context.NewPrincipal.Claims.Select(x => x.Type).ToArray(); + var currentClaimsToKeep = context.CurrentPrincipal.Claims.Where(x => !newClaimTypes.Contains(x.Type)).ToArray(); + + var id = context.NewPrincipal.Identities.First(); + id.AddClaims(currentClaimsToKeep); + + return Task.CompletedTask; + } + } + } +}