在 HttpContext 中保留 CustomPrincipal 类型时遇到问题
Trouble retaining CustomPrincipal type in HttpContext
我有一个 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">
在我的视图的 Web.config 文件中。
立即,httpContext.User = customPrincipal;
行在 AuthenticationManager.SetAuthCookie()
中运行后,ContextHelper.GetHttpContextBase().User
returns 的对象类型是 CustomPrincipal
。但是,如果我刷新页面,并在 BaseViewPage
中放置一个断点,base.User as CustomPrincipal
(和 ContextHelper.GetHttpContextBase().User as CustomPrincipal
就此而言)等于 null。但是,base.User
不为空:它属于 GenericPrincipal
类型,因此存在转换问题或 storing/retrieving 正确类型的问题。
为什么我的 BaseViewPage
中的 base.User
不是 CustomPrincipal
类型?
提前致谢。
您需要从每个请求中的 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; }
}
我有一个 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">
在我的视图的 Web.config 文件中。
立即,httpContext.User = customPrincipal;
行在 AuthenticationManager.SetAuthCookie()
中运行后,ContextHelper.GetHttpContextBase().User
returns 的对象类型是 CustomPrincipal
。但是,如果我刷新页面,并在 BaseViewPage
中放置一个断点,base.User as CustomPrincipal
(和 ContextHelper.GetHttpContextBase().User as CustomPrincipal
就此而言)等于 null。但是,base.User
不为空:它属于 GenericPrincipal
类型,因此存在转换问题或 storing/retrieving 正确类型的问题。
为什么我的 BaseViewPage
中的 base.User
不是 CustomPrincipal
类型?
提前致谢。
您需要从每个请求中的 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; }
}