为什么此自定义身份用户上下文不保留在 MVC 中?
Why is this custom identity user context not persisting in MVC?
我创建了 CustomPrincipal、CustomIdentity、CustomMembershipProvider 等,并在用户登录时全部填充:
public class CustomIdentity : IIdentity
{
private IIdentity _identity;
// in the future maybe use a dictionary instead
//private Dictionary<string, object> _customValues
private int _userId;
private bool _IsAuthenticated;
private string _name;
private string _displayName;
private string _role;
private Website _currentProject;
public Website CurrentProject
{
get { return _currentProject; }
set { _currentProject = value; }
}
private string _userName;
public string UserName
{
get { return _userName; }
set { _userName = value; }
}
...
所有这些都有效,我可以在 UserContext.Identity
.
中看到值
然而,当我尝试设置 UserContext.Identity.CurrentProject = website;
并稍后再次查看(页面重新加载)时,CurrentProject
对象为空。
我正在尝试使用自定义 UserContext
来保留用户特定的值,而不是使用会话 objects/variables。
关于为什么这不保留价值的任何想法?
--更新--
我已经有一段时间没看过这个项目了,在 Global.asax
我发现了以下内容:
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
//var user = HttpContext.Current.User; // as IPrincipal
//if (user.Identity.IsAuthenticated)
//{
// // same thing as below
//}
//if (Request.IsAuthenticated)
//{
// //get the username which we previously set in
// //forms authentication ticket in our login1_authenticate event
// string username = HttpContext.Current.User.Identity.Name;
// // Retrieves the cookie that contains your custom FormsAuthenticationTicket.
// HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
// // Decrypts the FormsAuthenticationTicket that is held in the cookie's .Value property.
// FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
// var fromsIdentity = new FormsIdentity(authTicket);
// //build a custom identity and custom principal object based on this username
// var identity = new CustomIdentity(authTicket);
// var principal = new CustomPrincipal(identity);
// //set the principal to the current context
// HttpContext.Current.User = principal;
//}
if (Request.IsAuthenticated)
{
// Retrieves the cookie that contains your custom FormsAuthenticationTicket.
// HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
// Decrypts the FormsAuthenticationTicket that is held in the cookie's .Value property.
//FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
// var fromsIdentity = new FormsIdentity(authTicket);
//build a custom identity and custom principal object based on this username
//var identity = new CustomIdentity(authTicket);
//var principal = new CustomPrincipal(identity);
// TODO: Add checks so we only do the following once per login.
// Get the GenericPrincipal identity
IIdentity ui = HttpContext.Current.User.Identity;
/* Extract Name, isAuthenticated, AuthenticationType from
the identity of the GenericPrincipal and add them including
any custom properties to the custom identity. I added a
few extra properties to my custom identity. */
//CustomIdentity customIdentity = new CustomIdentity(ui.Name);
CustomPrincipal customPrincipal = new CustomPrincipal(ui.Name);
// Set custom principal
HttpContext.Current.User = customPrincipal;
}
其中一些是否正确 - 其中大部分已被注释掉。
你必须在每个 post 后面更换用户,就像这样 post:http://www.codeproject.com/Tips/574576/How-to-implement-a-custom-IPrincipal-in-ASP-NET-MV
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
JavaScriptSerializer serializer = new JavaScriptSerializer();
if (authTicket.UserData == "OAuth") return;
CustomPrincipalSerializedModel serializeModel =
serializer.Deserialize<CustomPrincipalSerializedModel>(authTicket.UserData);
CustomPrincipal newUser = new CustomPrincipal(authTicket.Name);
newUser.Id = serializeModel.Id;
newUser.FirstName = serializeModel.FirstName;
newUser.LastName = serializeModel.LastName;
HttpContext.Current.User = newUser;
}
}
它在每个 postback 上运行,因此您每次都必须重建自定义标识。为方便起见,您可以将对象保存在会话中,而不是从票证或数据库中重新加载。
您必须在客户端浏览器上设置 cookie。在 cookie 中,您将放置一些东西(可能是用户 ID),您可以从中再次填充 customIdentity
。现在在你的 Global.asax
中,对于 AuthenticationRequest
事件,你将检查 cookie 是否存在,如果是,你将不得不通过解密 cookie 的值从 cookie 中取出那个(以前存储的 Id)东西并填充您的 customIdentity
并将其添加到当前线程上下文。
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
HttpContext.Current.User = new GenericPrincipal(customIdentity, null);
}
我创建了 CustomPrincipal、CustomIdentity、CustomMembershipProvider 等,并在用户登录时全部填充:
public class CustomIdentity : IIdentity
{
private IIdentity _identity;
// in the future maybe use a dictionary instead
//private Dictionary<string, object> _customValues
private int _userId;
private bool _IsAuthenticated;
private string _name;
private string _displayName;
private string _role;
private Website _currentProject;
public Website CurrentProject
{
get { return _currentProject; }
set { _currentProject = value; }
}
private string _userName;
public string UserName
{
get { return _userName; }
set { _userName = value; }
}
...
所有这些都有效,我可以在 UserContext.Identity
.
然而,当我尝试设置 UserContext.Identity.CurrentProject = website;
并稍后再次查看(页面重新加载)时,CurrentProject
对象为空。
我正在尝试使用自定义 UserContext
来保留用户特定的值,而不是使用会话 objects/variables。
关于为什么这不保留价值的任何想法?
--更新--
我已经有一段时间没看过这个项目了,在 Global.asax
我发现了以下内容:
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
//var user = HttpContext.Current.User; // as IPrincipal
//if (user.Identity.IsAuthenticated)
//{
// // same thing as below
//}
//if (Request.IsAuthenticated)
//{
// //get the username which we previously set in
// //forms authentication ticket in our login1_authenticate event
// string username = HttpContext.Current.User.Identity.Name;
// // Retrieves the cookie that contains your custom FormsAuthenticationTicket.
// HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
// // Decrypts the FormsAuthenticationTicket that is held in the cookie's .Value property.
// FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
// var fromsIdentity = new FormsIdentity(authTicket);
// //build a custom identity and custom principal object based on this username
// var identity = new CustomIdentity(authTicket);
// var principal = new CustomPrincipal(identity);
// //set the principal to the current context
// HttpContext.Current.User = principal;
//}
if (Request.IsAuthenticated)
{
// Retrieves the cookie that contains your custom FormsAuthenticationTicket.
// HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
// Decrypts the FormsAuthenticationTicket that is held in the cookie's .Value property.
//FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
// var fromsIdentity = new FormsIdentity(authTicket);
//build a custom identity and custom principal object based on this username
//var identity = new CustomIdentity(authTicket);
//var principal = new CustomPrincipal(identity);
// TODO: Add checks so we only do the following once per login.
// Get the GenericPrincipal identity
IIdentity ui = HttpContext.Current.User.Identity;
/* Extract Name, isAuthenticated, AuthenticationType from
the identity of the GenericPrincipal and add them including
any custom properties to the custom identity. I added a
few extra properties to my custom identity. */
//CustomIdentity customIdentity = new CustomIdentity(ui.Name);
CustomPrincipal customPrincipal = new CustomPrincipal(ui.Name);
// Set custom principal
HttpContext.Current.User = customPrincipal;
}
其中一些是否正确 - 其中大部分已被注释掉。
你必须在每个 post 后面更换用户,就像这样 post:http://www.codeproject.com/Tips/574576/How-to-implement-a-custom-IPrincipal-in-ASP-NET-MV
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
JavaScriptSerializer serializer = new JavaScriptSerializer();
if (authTicket.UserData == "OAuth") return;
CustomPrincipalSerializedModel serializeModel =
serializer.Deserialize<CustomPrincipalSerializedModel>(authTicket.UserData);
CustomPrincipal newUser = new CustomPrincipal(authTicket.Name);
newUser.Id = serializeModel.Id;
newUser.FirstName = serializeModel.FirstName;
newUser.LastName = serializeModel.LastName;
HttpContext.Current.User = newUser;
}
}
它在每个 postback 上运行,因此您每次都必须重建自定义标识。为方便起见,您可以将对象保存在会话中,而不是从票证或数据库中重新加载。
您必须在客户端浏览器上设置 cookie。在 cookie 中,您将放置一些东西(可能是用户 ID),您可以从中再次填充 customIdentity
。现在在你的 Global.asax
中,对于 AuthenticationRequest
事件,你将检查 cookie 是否存在,如果是,你将不得不通过解密 cookie 的值从 cookie 中取出那个(以前存储的 Id)东西并填充您的 customIdentity
并将其添加到当前线程上下文。
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
HttpContext.Current.User = new GenericPrincipal(customIdentity, null);
}