MVC4 Custom Forms Authentication - 无法将 System.Web.HttpContex
本文关键字:System Web HttpContex Custom Forms Authentication MVC4 | 更新日期: 2023-09-27 18:31:48
我正在.Net MVC4中构建一个网站,并尝试使用CustomPrincipal对象实现我自己的表单身份验证。
这是我的登录方法...
public void Login(string email)
{
var user = _userManager.GetUserByEmail(email);
var encryptedCookieContent = FormsAuthentication.Encrypt(new FormsAuthenticationTicket(1, user.Email, DateTime.Now, DateTime.Now.AddMinutes(FormsAuthentication.Timeout.TotalMinutes),
false, user.Id + "|" + user.AccountId + "|" + user.RoleId + "|" + user.Role.Name, FormsAuthentication.FormsCookiePath));
var formsAuthenticationTicketCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedCookieContent)
{
Domain = FormsAuthentication.CookieDomain,
Path = FormsAuthentication.FormsCookiePath,
HttpOnly = true,
Secure = FormsAuthentication.RequireSSL
};
HttpContext.Current.Response.Cookies.Add(formsAuthenticationTicketCookie);
}
这是我的自定义主体
public class CustomPrincipal : IPrincipal
{
public CustomPrincipal(IIdentity identity, int userId, int accountId, string role, int roleId)
{
Identity = identity;
Role = role;
RoleId = roleId;
UserId = userId;
AccountId = accountId;
}
public bool IsInRole(string role)
{
return Role == role;
}
public bool IsInRole(int roleId)
{
return RoleId == roleId;
}
public IIdentity Identity { get; private set; }
public string Role { get; private set; }
public int RoleId { get; private set; }
public int UserId { get; private set; }
public int AccountId { get; private set; }
}
我没有实现 Identity 的自定义实例,我只是重用 GenericIdentity。在我的 Global.asax 文件中,我像这样操纵了我的Application_AuthenticateRequest方法......
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
if (Request.IsAuthenticated)
{
var formsCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
if (formsCookie != null)
{
var ticket = FormsAuthentication.Decrypt(formsCookie.Value);
var principal = PrincipalConfig.CreatePrincipal(ticket);
System.Web.HttpContext.Current.User = Thread.CurrentPrincipal = principal;
}
}
}
PrincipalConfig.CreatePrincipal 是将我的自定义主体对象组合在一起的方法。 这基本上只是填写用户数据...喜欢这个。。。
public static CustomPrincipal CreatePrincipal(FormsAuthenticationTicket ticket)
{
var userData = ticket.UserData.Split('|');
var principal = new CustomPrincipal(new GenericIdentity(ticket.Name), Convert.ToInt32(userData[0]), Convert.ToInt32(userData[1]), userData[3], Convert.ToInt32(userData[2]));
return principal;
}
所以现在,回到global.asax文件中的Application_AuthenticateRequest,你可以看到我正在获取我新创建的CustomPrincipal对象并将其分配给System.Web.HttpContext.Current.User。
这样做之后,如果我在Application_AuthenticateRequest方法中将以下内容放在即时窗口中......
System.Web.HttpContext.Current.User as CustomPrincipal
正如我所期望的那样,向我显示了 CustomPrincipal 对象中的所有数据。
但是,如果我稍后(在其他一些控制器操作中)尝试访问System.Web.HttpContext.Current.User并将其转换为CustomPrincipal,它将返回一个null。
同样,对于应用程序中发出的每个请求,我能够从Application_AuthenticateRequest方法内的FormsAuthentication cookie解密FormsAuthenticationTicket,并找到我的所有用户数据。 因此,似乎正在创建和正确读取cookie。 但是,当新的 CustomPrincipal 分配给 System.Web.HttpContext.Current.User 时,从那个时间到我尝试在另一个控制器中再次访问它时,似乎存在某种断开连接。
谁能看到我可能在这里做错了什么?
如果我需要澄清任何事情,请告诉我。
谢谢
我不确定你是否在使用
Request.IsAuthenticated
正确。
属性实质上返回与 Context.User.Identity.IsAuthenticated 属性相同的值。 在代码中,它应始终返回 false,因此分配了自定义主体的代码永远不会触发。
可以通过在控制器方法中设置断点并检查代码中的 Context.Current.User 类型来对此进行一些调试。 是通用身份吗? 如果是这样,您的校长从未被分配过。