表单身份验证票已使用先前的登录数据解密

时间:2019-11-10 08:11:50

标签: authentication cookies asp.net-mvc

我有一个使用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;
    }

}

1 个答案:

答案 0 :(得分:1)

问题根源:我使用了急切的加载方式,因此用户数据的长度更大,因此无法解密票证,这就是为什么global.asax中的cookie为空的原因