From 255a8825868d7cd4d32d67326d15d57a4f4b095a Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 6 Jul 2026 08:59:46 +0800 Subject: [PATCH 1/6] Return anonymous principal instead of null in ThreadCurrentPrincipalAccessor --- .../Abp/Security/Claims/ThreadCurrentPrincipalAccessor.cs | 2 +- .../Abp/Security/Claims/CurrentPrincipalAccessor_Tests.cs | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/ThreadCurrentPrincipalAccessor.cs b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/ThreadCurrentPrincipalAccessor.cs index ab42441f98..e5234a06d1 100644 --- a/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/ThreadCurrentPrincipalAccessor.cs +++ b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/ThreadCurrentPrincipalAccessor.cs @@ -8,6 +8,6 @@ public class ThreadCurrentPrincipalAccessor : CurrentPrincipalAccessorBase, ISin { protected override ClaimsPrincipal GetClaimsPrincipal() { - return (Thread.CurrentPrincipal as ClaimsPrincipal)!; + return Thread.CurrentPrincipal as ClaimsPrincipal ?? new ClaimsPrincipal(new ClaimsIdentity()); } } diff --git a/framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/Claims/CurrentPrincipalAccessor_Tests.cs b/framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/Claims/CurrentPrincipalAccessor_Tests.cs index bbc18089be..9ba384c69f 100644 --- a/framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/Claims/CurrentPrincipalAccessor_Tests.cs +++ b/framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/Claims/CurrentPrincipalAccessor_Tests.cs @@ -31,7 +31,8 @@ public class CurrentPrincipalAccessor_Tests : AbpIntegratedTest Date: Mon, 6 Jul 2026 09:10:03 +0800 Subject: [PATCH 2/6] Simplify anonymous principal assertions in CurrentPrincipalAccessor test --- .../Claims/CurrentPrincipalAccessor_Tests.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/Claims/CurrentPrincipalAccessor_Tests.cs b/framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/Claims/CurrentPrincipalAccessor_Tests.cs index 9ba384c69f..959f605bc4 100644 --- a/framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/Claims/CurrentPrincipalAccessor_Tests.cs +++ b/framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/Claims/CurrentPrincipalAccessor_Tests.cs @@ -31,8 +31,10 @@ public class CurrentPrincipalAccessor_Tests : AbpIntegratedTest Date: Mon, 6 Jul 2026 09:55:34 +0800 Subject: [PATCH 3/6] Restore the previous ambient principal when a Change scope is disposed --- .../Claims/CurrentPrincipalAccessorBase.cs | 6 ++-- .../Claims/CurrentPrincipalAccessor_Tests.cs | 36 +++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/CurrentPrincipalAccessorBase.cs b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/CurrentPrincipalAccessorBase.cs index 1d3e296e38..48e9801049 100644 --- a/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/CurrentPrincipalAccessorBase.cs +++ b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/CurrentPrincipalAccessorBase.cs @@ -8,7 +8,7 @@ public abstract class CurrentPrincipalAccessorBase : ICurrentPrincipalAccessor { public ClaimsPrincipal Principal => _currentPrincipal.Value ?? GetClaimsPrincipal(); - private readonly AsyncLocal _currentPrincipal = new AsyncLocal(); + private readonly AsyncLocal _currentPrincipal = new AsyncLocal(); protected abstract ClaimsPrincipal GetClaimsPrincipal(); @@ -19,10 +19,10 @@ public abstract class CurrentPrincipalAccessorBase : ICurrentPrincipalAccessor private IDisposable SetCurrent(ClaimsPrincipal principal) { - var parent = Principal; + var parent = _currentPrincipal.Value; _currentPrincipal.Value = principal; - return new DisposeAction, ClaimsPrincipal>>(static (state) => + return new DisposeAction, ClaimsPrincipal?>>(static (state) => { var (currentPrincipal, parent) = state; currentPrincipal.Value = parent; diff --git a/framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/Claims/CurrentPrincipalAccessor_Tests.cs b/framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/Claims/CurrentPrincipalAccessor_Tests.cs index 959f605bc4..ed4e6e49ee 100644 --- a/framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/Claims/CurrentPrincipalAccessor_Tests.cs +++ b/framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/Claims/CurrentPrincipalAccessor_Tests.cs @@ -52,4 +52,40 @@ public class CurrentPrincipalAccessor_Tests : AbpIntegratedTest + { + new Claim(ClaimTypes.NameIdentifier, "123456") + })); + + using (accessor.Change(changedPrincipal)) + { + accessor.Principal.ShouldBe(changedPrincipal); + } + + // Disposing the Change scope must not pin the accessor to the fallback principal; + // a principal that becomes available afterwards has to be reflected. + var sourcePrincipal = new ClaimsPrincipal(new ClaimsIdentity(new List + { + new Claim(ClaimTypes.NameIdentifier, "654321") + })); + accessor.SourcePrincipal = sourcePrincipal; + + accessor.Principal.ShouldBe(sourcePrincipal); + } + + private class TestCurrentPrincipalAccessor : CurrentPrincipalAccessorBase + { + public ClaimsPrincipal? SourcePrincipal { get; set; } + + protected override ClaimsPrincipal GetClaimsPrincipal() + { + return SourcePrincipal ?? new ClaimsPrincipal(new ClaimsIdentity()); + } + } } From 6795a5a008749f58a10357cc30c0b324ab5c40d6 Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 6 Jul 2026 09:55:35 +0800 Subject: [PATCH 4/6] Return anonymous principal instead of null from AbpComponentsClaimsCache --- .../Components/Web/Security/AbpComponentsClaimsCache.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Security/AbpComponentsClaimsCache.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Security/AbpComponentsClaimsCache.cs index c98edaef19..e5356da660 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Security/AbpComponentsClaimsCache.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Security/AbpComponentsClaimsCache.cs @@ -8,7 +8,7 @@ namespace Volo.Abp.AspNetCore.Components.Web.Security; public class AbpComponentsClaimsCache : IScopedDependency { - public ClaimsPrincipal Principal { get; private set; } = default!; + public ClaimsPrincipal Principal { get; private set; } = new ClaimsPrincipal(new ClaimsIdentity()); private readonly AuthenticationStateProvider? _authenticationStateProvider; From ce86845818db42f7417874f26392bc9f5d10e7f9 Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 6 Jul 2026 10:07:28 +0800 Subject: [PATCH 5/6] Preserve non-ClaimsPrincipal thread principal instead of treating it as anonymous --- .../Abp/Security/Claims/ThreadCurrentPrincipalAccessor.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/ThreadCurrentPrincipalAccessor.cs b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/ThreadCurrentPrincipalAccessor.cs index e5234a06d1..99e8536eec 100644 --- a/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/ThreadCurrentPrincipalAccessor.cs +++ b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/ThreadCurrentPrincipalAccessor.cs @@ -8,6 +8,12 @@ public class ThreadCurrentPrincipalAccessor : CurrentPrincipalAccessorBase, ISin { protected override ClaimsPrincipal GetClaimsPrincipal() { - return Thread.CurrentPrincipal as ClaimsPrincipal ?? new ClaimsPrincipal(new ClaimsIdentity()); + var principal = Thread.CurrentPrincipal; + if (principal == null) + { + return new ClaimsPrincipal(new ClaimsIdentity()); + } + + return principal as ClaimsPrincipal ?? new ClaimsPrincipal(principal); } } From 20847b1fc101974f1f096884c1310cae5e365d6b Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 6 Jul 2026 10:07:28 +0800 Subject: [PATCH 6/6] Isolate Thread.CurrentPrincipal in CurrentPrincipalAccessor test --- .../Claims/CurrentPrincipalAccessor_Tests.cs | 40 ++++++++++++------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/Claims/CurrentPrincipalAccessor_Tests.cs b/framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/Claims/CurrentPrincipalAccessor_Tests.cs index ed4e6e49ee..6480af9c74 100644 --- a/framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/Claims/CurrentPrincipalAccessor_Tests.cs +++ b/framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/Claims/CurrentPrincipalAccessor_Tests.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Security.Claims; +using System.Threading; using Shouldly; using Volo.Abp.Testing; using Xunit; @@ -30,27 +31,36 @@ public class CurrentPrincipalAccessor_Tests : AbpIntegratedTest