【问题标题】:Application_AuthenticateRequest fires to lateApplication_AuthenticateRequest 触发到晚
【发布时间】:2016-11-28 23:40:20
【问题描述】:

当我创建我的 formsauthenticationticket 时,Application_AuthenticateRequest(在 global.asax 中)不会立即被触发。当我检查 user.isrole 它是空的。但后来当我尝试另一个操作时,Application_AuthenticateRequest 被触发,并且用户的角色被设置。

登录功能:

      if (loggedIn)
            {
                ViewBag.loginFailed = 1;
                string roles = "Administrator";
                CreateTicket(pharmacist.ID.ToString(), roles);
                LoginRedirect();
            }

方法:

    [Authorize(Roles = "Administrator, User")]
    private void CreateTicket(string id, string role)
    {

        var ticket = new FormsAuthenticationTicket(
                version: 1,
                name: id,
                issueDate: DateTime.Now,
                expiration: DateTime.Now.AddHours(1),
                isPersistent: false,
                userData: role);

        var encryptedTicket = FormsAuthentication.Encrypt(ticket);
        var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
        HttpContext.Response.Cookies.Add(cookie);
    }

   [Authorize(Roles = "Administrator, User")]
    private ActionResult LoginRedirect() {
        if (User.IsInRole("Administrator"))
        {
            return RedirectToAction("Index", "Pharmacist");
        }
        else if (User.IsInRole("User"))
        {
            return RedirectToAction("Index", "Patient");
        }
        else {
            return RedirectToAction("Logout", "Authentication");
        }
    }

Application_AuthenticateRequest

  protected void Application_AuthenticateRequest(Object sender, EventArgs e)
    {
        if (HttpContext.Current.User != null)
        {
            if (HttpContext.Current.User.Identity.IsAuthenticated)
            {
                if (HttpContext.Current.User.Identity is FormsIdentity)
                {
                    FormsIdentity id =
                        (FormsIdentity)HttpContext.Current.User.Identity;
                    FormsAuthenticationTicket ticket = id.Ticket;

                    // Get the stored user-data, in this case, our roles
                    string userData = ticket.UserData;
                    string[] roles = userData.Split(',');
                    HttpContext.Current.User = new GenericPrincipal(id, roles);
                }
            }
        }
    }

【问题讨论】:

    标签: asp.net asp.net-mvc-5 forms-authentication


    【解决方案1】:

    Application_AuthenticateRequest 仅在您请求新资源时调用。

    在您的情况下,您仍在创建 FormsAuthenticationTicket 的请求中。结果,主体对象尚未分配给当前线程。

    如果要从当前线程中检索 IPrincipal,则需要显式分配它。

    var encryptedTicket = FormsAuthentication.Encrypt(ticket);
    var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
    // You need this two lines.
    HttpContext.Current.User = new GenericPrincipal(id, roles); 
    Thread.CurrentPrincipal = HttpContext.Current.User;
    ....
    

    还要确保您在 Application_AuthenticateRequest 中有这两行。

    protected void Application_AuthenticateRequest(Object sender, EventArgs e)
    {
       ...
       HttpContext.Current.User = new GenericPrincipal(id, roles);
       Thread.CurrentPrincipal = HttpContext.Current.User; <-- Do not forget this.
       ...
    }
    

    仅供参考:私有方法上不需要 AuthorizeAttribute。您只希望在 Controller 或 Action 方法上使用它。

    [Authorize(Roles = "Administrator, User")] <-- This is not needed.
    private void CreateTicket(string id, string role)
    {
       ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-26
      • 1970-01-01
      • 2015-08-21
      相关资源
      最近更新 更多