在Controller中使用的BeginConquest中的HTTPContext用户集不可用

时间:2013-05-12 00:15:37

标签: c# asp.net asp.net-mvc-3 forms-authentication

我正在使用一种有点自制的用户身份验证方法。在对用户进行身份验证之后,在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的User。

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

编辑: 还应注意,在HTTPContext上设置的其他值确实会转移到控制器。例如这一行

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

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

1 个答案:

答案 0 :(得分: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;
    }