无法在HttpContext中保留CustomPrincipal类型

时间:2015-04-30 17:03:53

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

我有一个MVC应用程序,我在为自己的观点提出自定义主体方面遇到了麻烦。它有以下类可以帮助我管理身份验证cookie。

public class AuthenticationManager
{
    public void SetAuthCookie(UserViewModel user)
    {
        var serializeModel = new CustomPrincipalSerializeModel
        {
            Id = user.UserId,
            Email = user.Email,
            Name = user.Name
        };
        var serializer = new JavaScriptSerializer();
        var customPrincipal = customPrincipalMapper.Convert(serializeModel);
        var httpContext = ContextHelper.GetHttpContextBase();
        httpContext.User = customPrincipal;
        var userData = serializer.Serialize(serializeModel);
        var authTicket = new FormsAuthenticationTicket(1, serializeModel.Email, DateTime.Now, DateTime.Now.AddYears(5), false, userData);
        var encTicket = FormsAuthentication.Encrypt(authTicket);
        var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
        httpContext.Response.Cookies.Add(authCookie);
    }
}

public static class ContextHelper
{
    public static HttpContextBase GetHttpContextBase()
    {
        return new HttpContextWrapper(HttpContext.Current);
    }
}

我还有以下BaseViewPage类,这些类允许我将当前用户公开给我的观点:

public abstract class BaseViewPage : WebViewPage
{
    public virtual new CustomPrincipal User
    {
        get { return base.User as CustomPrincipal; }
    }
}

public abstract class BaseViewPage<TModel> : WebViewPage<TModel>
{
    public virtual new CustomPrincipal User
    {
        get { return base.User as CustomPrincipal; }
    }
}

FWIW,这需要<pages pageBaseType="Giftster.Web.Views.BaseViewPage">在我的View的Web.config文件中。

httpContext.User = customPrincipal;AuthenticationManager.SetAuthCookie()行后,ContextHelper.GetHttpContextBase().User返回的对象类型为CustomPrincipal。但是,如果我刷新页面,并在BaseViewPage中设置了一个断点,base.User as CustomPrincipal(和ContextHelper.GetHttpContextBase().User as CustomPrincipal就此而言)等于null。 base.User不是null:它的类型为GenericPrincipal,因此存在转换问题或存储/检索正确类型的问题。

为什么base.User BaseViewPage不属于CustomPrincipal类型?

提前致谢。

1 个答案:

答案 0 :(得分:1)

您需要在每个请求中从Cookie中创建CustomPrincipal并将其添加到当前上下文中。将以下内容添加到Global.asax.cs文件

protected void Application_PostAuthenticateRequest(object sender, EventArgs e)
{
  // Get the authentication cookie
  HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
  // If the cookie can't be found, don't issue the ticket
  if (authCookie == null)
  {
    return;
  }
  // Extract the forms authentication cookie
  FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
  // Deserialise user data
  JavaScriptSerializer serializer = new JavaScriptSerializer();
  CustomPrincipalSerializeModel data = serializer.Deserialize<CustomPrincipalSerializeModel>(authTicket.UserData);
  // Create principal
  CustomPrincipal principal = new CustomPrincipal(authTicket.Name);
  // Set the properties of CustomPrincipal
  principal.Email = data.Email;
  .... // etc
  // Assign to current context
  HttpContext.Current.User = principal;
}

另请注意,SetAuthCookie()方法

中不需要以下行
httpContext.User = customPrincipal;

您还可以考虑将以下内容添加到BaseController(所有其他控制器从中派生),以便在每个控制器方法中轻松访问CustomPrincipal属性

public new CustomPrincipalSerializeModel User
{
  get { return (CustomPrincipal)HttpContext.User; }
}