Установить Thread.CurrentPrincipal асинхронно?
Используя 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
не отбрасывал эту мутацию при восстановлении контекста синхронизации?
Ответы
Ответ 1
Вы также должны установить HttpContext.Current.User
. См. этот ответ и этот пост в блоге для получения дополнительной информации.
Обновление: Также убедитесь, что вы работаете на .NET 4.5 и UserTaskFriendlySynchronizationContext
установлен на true
.