2

我正在使用一种有点自制的用户身份验证方法。在对用户进行身份验证后,在 C# 中设置身份验证票证是这样的。

FormsAuthenticationTicket authenticationTicket = new FormsAuthenticationTicket(1, viewModel.Email, DateTime.Now, DateTime.Now.AddHours(48), true, String.Join("|", roles));
string encryptedTicket = FormsAuthentication.Encrypt(authenticationTicket);
HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
Response.Cookies.Add(authCookie);

需要注意的是,角色是由该用户的可用角色构建的字符串列表(角色不在同一个用户表中 - 例如,有一组条件定义用户“角色”)。

接下来在 Global.asax 的 Application_BeginRequest 方法中,我有以下内容:

// Extract the forms authentication cookie
string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = Context.Request.Cookies[cookieName];

if (null == authCookie)
{
    return;
}

FormsAuthenticationTicket authTicket = null;
try
{
    authTicket = FormsAuthentication.Decrypt(authCookie.Value);
}
catch (Exception ex)
{
    return;
}

if (null == authTicket)
{
    return;
}
string[] roles = authTicket.UserData.Split(new char[] { '|' });

FormsIdentity id = new FormsIdentity(authTicket);

GenericPrincipal principal = new GenericPrincipal(id, roles);
HttpContext.Current.User = principal;

基本上是从 authticket 与用户一起设置当前上下文。但是,当我为 MVC 类执行自定义 Authorize 属性时,我首先遇到了一个问题,我注意到 HTTPContext 的用户未设置。

然后我注意到在每个操作中,用户也没有设置。但是,通过单步执行我的代码,我可以清楚地看到,在身份验证票证中找到了用户,并且被解密并存储在上下文变量中。但是当我在任何控制器中执行操作时,用户已经从上下文中消失了。

编辑:还应该注意的是,在 HTTPContext 上设置的其他值确实会传递给控制器​​。例如这条线

HttpContext.Current.AllowAsyncDuringSyncStages = false; // Or true

将携带我设置的任何内容到控制器操作中。似乎只有用户被空白。

4

1 回答 1

1

Application_BeginRequest 不是设置 HttpContext.Current.User 的有效位置,因为它将在授权期间被覆盖。

您需要在Application_AuthorizeRequest中实现上述代码。例如参考下面的代码。然后它将在控制器中可用。

 public MvcApplication()
    {
        this.AuthorizeRequest += MvcApplication_AuthorizeRequest;
    }

    void MvcApplication_AuthorizeRequest(object sender, EventArgs e)
    {
        FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket("test", true, 30);
        FormsIdentity id = new FormsIdentity(authTicket);

        GenericPrincipal principal = new GenericPrincipal(id, new string[] { });
        HttpContext.Current.User = principal;
    }
于 2013-05-12T03:11:46.283 回答