HttpContext.Current имеет значение null при использовании ASP. Net Идентификационные методы синхронного расширения - PullRequest
0 голосов
/ 10 января 2020

Большинство функций в ASP. Net Идентификация асинхронна. Существуют вспомогательные методы расширения, которые позволяют вам запускать их синхронно (которые использует справочный проект ASP. Net Identity), однако:

  • Если я использую методы синхронного расширения, HttpContext.Current нулевой.
  • Если я вызываю асинхронные c методы напрямую, HttpContext.Current не равен нулю.

Описанная проблема в значительной степени идентична этому вопросу , но пытается понять, почему он так себя ведет, а не просто решить проблему.

Причина, по которой я сталкиваюсь с этой проблемой, заключается в том, что я хочу расширить процесс входа в систему, чтобы проверить IP-адрес запроса на соответствие IP-адреса белого списка пользователя - но он не работает, если я не могу получить доступ к HttpContext.

Пытаясь выяснить, почему возникает эта проблема, я узнал, что ASP. Net делает свое дело с контекстами синхронизации, чтобы убедиться, что HttpContext.Current доступен для асинхронных c вызовов, поэтому он работает, когда я вызываю асин c метод напрямую.

Зачем вам использовать методы расширения, которые позволяют асинхронным c вызовам выполняться синхронно, если это нарушает доступ к HttpContext.Current. Это ошибка?

public class LoginPage : Page
{
    public void Login(string user, string password)
    {
        var signInManager = HttpContext.Current.GetOwinContext().Get<MySignInManager>();
        signInManager.PasswordSignIn(user, password, false, false); // this is a synchronous extension method
    }
}

public class MySignInManager<TUser, TKey> : Microsoft.Aspnet.Identity.Owin.SignInManager<TUser, TKey>
{
    public override async Task<SignInStatus> PasswordSignInAsync(string username, string password, bool isPersistent, bool shouldLockout)
    {
        ...
        string ipAddress = GetIpAddress();
        ...
    }

    private string GetIpAddress()
    {
        // HttpContext.Current is null if using the PasswordSignIn extension method
        var request = HttpContext.Current.GetOwinContext().Request;
        return request.RemoteIpAddress;
    }
}

// namespace Microsoft.AspNet.Identity.Owin
public static class SignInManagerExtensions
{
    public static SignInStatus PasswordSignIn(this SignInManager<TUser, TKey> manager, string username, string password, bool isPersistent, bool shouldLockout)
    {
        return AsyncHelper.RunSync(() => manager.PasswordSignInAsync(userName, password, isPersistent, shouldLockout));
    }
}

// namespace Microsoft.AspNet.Identity
internal static class AsyncHelper
{
    public static TResult RunSync<TResult>(Func<Task<TResult>> func)
    {
        var cultureUi = CultureInfo.CurrentUICulture;
        var culture = CultureInfo.CurrentCulture;
        return _myTaskFactory.StartNew(() =>
        {
            Thread.CurrentThread.CurrentCulture = culture;
            Thread.CurrentThread.CurrentUICulture = cultureUi;
            return func();
        }).Unwrap().GetAwaiter().GetResult();
    }
}
...