【问题标题】:Authentication state in ASP.NET MVC ActionFiltersASP.NET MVC 操作筛选器中的身份验证状态
【发布时间】:2017-08-20 13:03:28
【问题描述】:

我有一个名为 Log 的 ActionFilter 名称,当用户登录网站时它会记录用户 ip 和其他详细信息,所以为了完成这项工作,我编写了以下代码:

public class Log : ActionFilterAttribute
{
    public IAppUserManager UserManager { get; set; }
    
    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        var status = filterContext.Controller.TempData.Any(pair => pair.Key == "status" && (int)pair.Value == 200);

        if (filterContext.HttpContext.User != null && filterContext.HttpContext.User.Identity.IsAuthenticated && status)
        {
            var logIp = new AddIpAddressDto()
            {
                Browser = filterContext.HttpContext.Request.GetBrowser(),
                Ip = filterContext.HttpContext.Request.GetIp(),
                Os = filterContext.HttpContext.Request.UserAgent.GetOs(),
                UrlReferrer = filterContext.HttpContext.Request.UrlReferrer?.ToString(),
                UserId = Guid.Parse(filterContext.HttpContext.User.Identity.GetUserId()),
                UserName = filterContext.HttpContext.User.Identity.GetUserName(),
            };
            UserManager.Log(logIp);
        }
        base.OnResultExecuted(filterContext);
    }
}

filterContext.HttpContext.User.Identity.IsAuthenticatedture时,此代码有效。

Log 过滤器声明登录操作:

[AllowAnonymous]
[Route("sign-in", Name = "signInRoute")]
[HttpPost, ValidateAntiForgeryToken]
[Log]
public virtual async Task<ActionResult> Login(LoginDto login, string returnTo)
{
     var signInStatus = await _signInManager
         .PasswordSignInAsync(user.UserName, login.Password, login.RememberMe, true)
            .ConfigureAwait(false);

     switch (signInStatus) // is Success
     {
         case SignInStatus.Success:
              TempData["status"] = 200;
              return RedirectToLocal(returnTo);
         case SignInStatus.LockedOut:
                // todo return time of louckout
              break;
         case SignInStatus.RequiresVerification:
              return RedirectToAction("ConfirmEmail");
         case SignInStatus.Failure:
              return View(CleanPassWordInLogin(login));
            default:
                throw new ArgumentOutOfRangeException();
     }
}

登录操作正常,signInStatus 成功,但在执行操作后IsAuthenticatedfalse

为了解决这个问题,我尝试了以下方法:

  • 使用HttpContext.Current.GetOwinContext();

  • 在 IoC 中定义了以下代码(StructureMap 4.5.2

    config.For&lt;HttpContextBase&gt;().Use(() =&gt; new HttpContextWrapper(HttpContext.Current));

  • 试过OnActionExecuted,OnActionExecuting,OnResultExecuting

  • 在 Identity 2.0 中使用 IAuthenticationManager

我该如何解决这个问题?

【问题讨论】:

    标签: c# asp.net-mvc authentication httpcontext action-filter


    【解决方案1】:

    SignInManager.PasswordSignInAsync 执行后,将创建包含用户信息的身份验证 cookie。因此,User.Identity info 将由身份验证 cookie 中的声明填充,这些声明尚未解析(此 cookie 将在对服务器的第二个请求中解析,而不是在同一个登录请求中)。这就是为什么你不能在PasswordSignInAsync 之后使用User.Identity。此时,您只有一个选择来查找 userId:

     string userId = UserManager.FindByName(model.Email)?.Id;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多