我有一个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
类型?
提前致谢。
答案 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; }
}