From ecc3c0e19bb902a54b41abb1ae542d152ced25a3 Mon Sep 17 00:00:00 2001 From: Marco Rossignoli Date: Wed, 12 Feb 2020 17:25:10 +0100 Subject: [PATCH] Fix AppDomain.SetPrincipalPolicy bug for new threads (#32104) * fix principal policy for new threads Fixes #31717 --- .../src/CoreLib/System/Threading/Thread.cs | 7 +- .../tests/ThreadTests.cs | 88 ++++++++++++++++++- 2 files changed, 88 insertions(+), 7 deletions(-) diff --git a/src/Common/src/CoreLib/System/Threading/Thread.cs b/src/Common/src/CoreLib/System/Threading/Thread.cs index 28b2e6eb8f5a..a2be70c847fc 100644 --- a/src/Common/src/CoreLib/System/Threading/Thread.cs +++ b/src/Common/src/CoreLib/System/Threading/Thread.cs @@ -136,11 +136,12 @@ public static IPrincipal? CurrentPrincipal { get { - if (s_asyncLocalPrincipal is null) + IPrincipal? principal = s_asyncLocalPrincipal?.Value; + if (principal is null) { - CurrentPrincipal = AppDomain.CurrentDomain.GetThreadPrincipal(); + CurrentPrincipal = (principal = AppDomain.CurrentDomain.GetThreadPrincipal()); } - return s_asyncLocalPrincipal?.Value; + return principal; } set { diff --git a/src/System.Threading.Thread/tests/ThreadTests.cs b/src/System.Threading.Thread/tests/ThreadTests.cs index b76021885294..961f2904199b 100644 --- a/src/System.Threading.Thread/tests/ThreadTests.cs +++ b/src/System.Threading.Thread/tests/ThreadTests.cs @@ -331,7 +331,8 @@ public static void CurrentCultureTest_DifferentThread() CultureInfo uiCulture = (CultureInfo)CultureInfo.CurrentCulture.Clone(); ExceptionDispatchInfo exceptionFromThread = null; - var t = new Thread(() => { + var t = new Thread(() => + { try { Assert.Same(culture, Thread.CurrentThread.CurrentCulture); @@ -437,11 +438,11 @@ public static void CurrentPrincipalContextFlowTest() { Thread.CurrentPrincipal = new ClaimsPrincipal(); - await Task.Run(async() => { + await Task.Run(async () => { Assert.IsType(Thread.CurrentPrincipal); - await Task.Run(async() => + await Task.Run(async () => { Assert.IsType(Thread.CurrentPrincipal); @@ -471,7 +472,7 @@ public static void CurrentPrincipalContextFlowTest_NotFlow() Thread.CurrentPrincipal = new ClaimsPrincipal(); Task task; - using(ExecutionContext.SuppressFlow()) + using (ExecutionContext.SuppressFlow()) { Assert.True(ExecutionContext.IsFlowSuppressed()); @@ -1121,6 +1122,85 @@ public static void WindowsPrincipalPolicyTest_Windows() }).Dispose(); } + + [Fact] + [PlatformSpecific(TestPlatforms.Windows)] + public static void WindowsPrincipalPolicyTest_Windows_NewThreads() + { + RemoteExecutor.Invoke(() => + { + AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal); + + IPrincipal currentPrincipal = Thread.CurrentPrincipal; + + Assert.NotNull(currentPrincipal); + Assert.True(currentPrincipal.Identity.IsAuthenticated); + + var first = new Thread(CheckPrincipal); + first.Start(currentPrincipal); + first.Join(); + + var second = new Thread(CheckPrincipal); + second.Start(currentPrincipal); + second.Join(); + }).Dispose(); + + static void CheckPrincipal(object principal) + { + Assert.True(Thread.CurrentPrincipal.Identity.IsAuthenticated); + Assert.NotNull(Thread.CurrentPrincipal); + Assert.Equal((IPrincipal)principal, Thread.CurrentPrincipal); + } + } + + [Fact] + public static void NoPrincipalPolicyTest_NewThreads() + { + RemoteExecutor.Invoke(() => + { + AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.NoPrincipal); + + Assert.Null(Thread.CurrentPrincipal); + + var first = new Thread(() => Assert.Null(Thread.CurrentPrincipal)); + first.Start(); + first.Join(); + + var second = new Thread(() => Assert.Null(Thread.CurrentPrincipal)); + second.Start(); + second.Join(); + }).Dispose(); + } + + [Fact] + [PlatformSpecific(TestPlatforms.Windows)] + public static void NoPrincipalToWindowsPrincipalPolicyTest_Windows_NewThreads() + { + RemoteExecutor.Invoke(() => + { + AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.NoPrincipal); + + Assert.Null(Thread.CurrentPrincipal); + + var first = new Thread(() => Assert.Null(Thread.CurrentPrincipal)); + first.Start(); + first.Join(); + + AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal); + + var second = new Thread(CheckPrincipal); + second.Start(Thread.CurrentPrincipal); + second.Join(); + }).Dispose(); + + static void CheckPrincipal(object principal) + { + Assert.True(Thread.CurrentPrincipal.Identity.IsAuthenticated); + Assert.NotNull(Thread.CurrentPrincipal); + Assert.Equal((IPrincipal)principal, Thread.CurrentPrincipal); + } + } + [Fact] [PlatformSpecific(TestPlatforms.AnyUnix)] public static void WindowsPrincipalPolicyTest_Unix()