Используя 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 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
в async-функции, чтобы вызывающий await
не отбрасывал эту мутацию при восстановлении контекста синхронизации?