10

認証中に ASP.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がその突然変異を破棄しないように、非同期関数をどのように設定しますか?

4

1 に答える 1