diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Startup.cs b/src/OrchardCore.Modules/OrchardCore.Users/Startup.cs index 21ec8b3c407..06a547db5ca 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Startup.cs +++ b/src/OrchardCore.Modules/OrchardCore.Users/Startup.cs @@ -206,7 +206,7 @@ public override void ConfigureServices(IServiceCollection services) options.LogoutPath = "/" + userOptions.Value.LogoffPath; options.AccessDeniedPath = "/Error/403"; }); - + services.AddTransient, ConfigureSecurityStampOptions>(); services.AddDataMigration(); services.AddScoped(); diff --git a/src/OrchardCore/OrchardCore.Users.Core/Services/ConfigureSecurityStampOptions.cs b/src/OrchardCore/OrchardCore.Users.Core/Services/ConfigureSecurityStampOptions.cs new file mode 100644 index 00000000000..01cc9d179b2 --- /dev/null +++ b/src/OrchardCore/OrchardCore.Users.Core/Services/ConfigureSecurityStampOptions.cs @@ -0,0 +1,35 @@ +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Identity; +using Microsoft.Extensions.Options; + +namespace OrchardCore.Users.Services; + +public class ConfigureSecurityStampOptions : IPostConfigureOptions +{ + public void PostConfigure(string name, SecurityStampValidatorOptions options) + { + options.OnRefreshingPrincipal = principalContext => + { + var currentIdentity = principalContext.CurrentPrincipal?.Identities?.FirstOrDefault(); + + if (currentIdentity is not null && principalContext.NewPrincipal.Identities is not null) + { + var newIdentity = principalContext.NewPrincipal.Identities.First(); + + foreach (var claim in currentIdentity.Claims) + { + if (newIdentity.HasClaim(claim.Type, claim.Value)) + { + continue; + } + + newIdentity.AddClaim(new Claim(claim.Type, claim.Value)); + } + } + + return Task.CompletedTask; + }; + } +}