我有一个使用Active Directory成员身份进行用户身份验证的MVC应用程序。
用户登录后,将创建FormsAuthenticatedTicket
并对其进行加密。然后,在Application_PostAuthenticateRequest
中,票证被解密,反序列化的用户数据存储在自定义主体对象中。
我将票证的到期日期从AddMinute(30)更改为AddMenute(10)
我的问题是,当用户的cookie过期后登录时,该票证将使用当前的登录数据进行加密,但是在global.asax中,先前的登录票证仍会被解密。调试时,我看到同一用户的上次到期日期(30分钟而不是10分钟之后)的票证数据,票证版本解密为2。
我犯了什么错误?
编辑:
我通过删除FormsAuthentication.SetAuthCookie(userName, rememberMe);
解决了此问题
因为我使用过FormsAuthenticationTicket对象
但是我面临另一个问题: 在全局asax Application_PostAuthenticateRequest中,当尝试读取cookie时,尽管添加了票证的cookie成功加密了,但调试器发现我为null
string encryptedTicket = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
Response.Cookies.Add(cookie);
我有两个用户:其中一个出现此问题,而另一个则没有问题
请如何解决此问题? Web.config:
<authentication mode="Forms">
<forms name=".ADAuthCookie" loginUrl="~/Account/Login">
</forms>
</authentication>
<membership defaultProvider="ADMembershipProvider">
<providers>
<clear/>
<add name="ADMembershipProvider"
type="System.Web.Security.ActiveDirectoryMembershipProvider"
connectionStringName ="ADconnectionString"
attributeMapUsername="sAMAccountName" />
</providers>
</membership>
我的行动后登录方法
[HttpPost]
[AllowAnonymous]
public ActionResult Login(string userName, string password, bool rememberMe, string returnUrl)
{
if (string.IsNullOrWhiteSpace(userName) || string.IsNullOrWhiteSpace(password))
{
ViewBag.Message = FormattedMessage.GetFormattedMessage("Veuillez Entrer l'utilisateur et/ou mot passe", TypeMessage.Danger, true);
return this.View();
}
if (Membership.ValidateUser(userName, password))
{
//FormsAuthentication.SetAuthCookie(userName, rememberMe);
//JavaScriptSerializer js = new JavaScriptSerializer();
PrincipalContext principalContext = new PrincipalContext(ContextType.Domain);
var userAD = UserPrincipal.FindByIdentity(principalContext, userName);
var intervenant = unitOfWorkBll.UserBLL.GetAllFiltered(u => u.Matricule == userAD.EmployeeId, includes: "IntervenantRoles.Role, IntervenantStructures.Structure").SingleOrDefault();
//string userData = js.Serialize(intervenant);
string userData = JsonConvert.SerializeObject(intervenant, Formatting.Indented, new JsonSerializerSettings {
PreserveReferencesHandling = PreserveReferencesHandling.Objects
});
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, userName, DateTime.Now, DateTime.Now.AddMinutes(10),rememberMe, userData);
string encryptedTicket = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
Response.Cookies.Add(cookie);
if (!string.IsNullOrWhiteSpace(returnUrl) )
{
return this.Redirect(returnUrl);
}
return this.RedirectToAction("Index", "Home");
}
ViewBag.Message= FormattedMessage.GetFormattedMessage("l'utilisateur et /ou le mot passe incorrect.", TypeMessage.Danger, true);
return this.View();
}
全局asax
protected void Application_PostAuthenticateRequest(object sender, EventArgs e)
{
HttpCookie autoCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
if (autoCookie != null)
{
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(autoCookie.Value);
Intervenant user = JsonConvert.DeserializeObject<Intervenant>(ticket.UserData/*, new JsonSerializerSettings {
PreserveReferencesHandling = PreserveReferencesHandling.Objects
}*/);
CustomADPrincipal customADPrincipal = new CustomADPrincipal(user); ;
HttpContext.Current.User = customADPrincipal;
}
}
答案 0 :(得分:1)
问题根源:我使用了急切的加载方式,因此用户数据的长度更大,因此无法解密票证,这就是为什么global.asax中的cookie为空的原因