设置线程.CurrentPrincipal异步

本文关键字:异步 CurrentPrincipal 线程 设置 | 更新日期: 2023-09-27 18:13:27

. NET WebAPI,在认证期间,设置Thread.CurrentPrincipal,以便控制器以后可以使用ApiController.User属性。

如果该认证步骤变为异步(以咨询另一个系统),则CurrentPrincipal的任何突变都将丢失(当调用者的await恢复同步上下文时)。

下面是一个非常简化的示例(在实际代码中,身份验证发生在操作过滤器中):

using System.Diagnostics;
using System.Security.Principal;
using System.Threading;
using System.Threading.Tasks;
public class ExampleAsyncController : System.Web.Http.ApiController
{
    public async Task GetAsync()
    {
        await AuthenticateAsync();
        // The await above saved/restored the current synchronization
        // context, thus undoing the assignment in AuthenticateAsync(). 
        Debug.Assert(User is GenericPrincipal);
    }
    private static async Task AuthenticateAsync()
    {
        // Save the current HttpContext because it's null after await.
        var currentHttpContext = System.Web.HttpContext.Current;
        // Asynchronously determine identity.
        await Task.Delay(1000);
        var identity = new GenericIdentity("<name>");
        var roles = new string[] { };
        Thread.CurrentPrincipal = new GenericPrincipal(identity, roles);
        currentHttpContext.User = Thread.CurrentPrincipal;
    }
}

如何在异步函数中设置Thread.CurrentPrincipal,使调用者的await在恢复同步上下文时不会丢弃该突变?

设置线程.CurrentPrincipal异步

您还必须设置HttpContext.Current.User。更多信息请看这个答案和这篇博文。

更新:同时确保你运行的是。net 4.5,并将UserTaskFriendlySynchronizationContext设置为true