2016-03-03 1 views
0

J'ai accidentellement sauté dans le monde des cookies et j'essaie de comprendre ce qui se passe. J'ai une application Web développée dans Visual Studio 20120/C# en utilisant FormsAuthentication. Lorsque j'ai développé l'application pour la première fois, j'ai créé quelques champs à stocker dans le cookie d'authentification: personID, firstName et admin, la chaîne ressemble à ceci: 777 | Jimmy | 1. Tout a bien fonctionné depuis. Maintenant, j'ai ajouté un quatrième champ à la fin du flou appelé "secBlur". Lorsque je fais cela et que j'essaie de récupérer la valeur de secBlur, il me dit que la plage du tableau est hors limites parce que la version antérieure du cookie ne contenait pas ce champ ... est logique. J'ai passé ces derniers jours à essayer de réécrire le contrôle de validité de mon cookie, et j'ai pensé que j'avais tout compris. Cependant, quand je vais écrire la nouvelle chaîne userData dans le cookie, il ne semble pas le faire. Mon code est ci-dessous, je vais essayer de marcher à travers ce que je fais ...Le cookie FormsAuthentication ne définit pas les valeurs UserData

Dans la page_load de ma page maître, la première chose que je fais est de faire un appel à une classe de cookie que j'ai créé pour vérifier que le cookie est la bonne version:

protected void Page_Load(object sender, EventArgs e) 
    { 
     if (Request.IsAuthenticated) 
     { 
      authCookie ac = new authCookie(); 

      ac.validate(); 

      LoginName ct = (LoginName)loginStatus.FindControl("HeadLoginName"); 

      if (ct != null) 
      { 
       formValues fv = new formValues(); 

       ct.FormatString = fv.firstName; 
      } 
     } 
    } 

Toute ma classe de cookies est ci-dessous. Dans la méthode Validate, je vérifie l'existence du cookie, puis je vérifie que c'est la bonne version et que userData existe. Si ce n'est pas la bonne version ou si userData n'existe pas, j'appelle la méthode getUserData pour récupérer les informations les plus récentes pour cette année, créer un nouveau ticket, stocker le ticket dans le cookie, puis enregistrer le cookie. Je pense la ligne sauver le cookie est le problème, mais je ne suis pas sûr.

using System; 
using System.Data.SqlClient; 
using System.Runtime.Remoting.Contexts; 
using System.Web; 
using System.Web.Security; 
using System.Web.UI.WebControls; 

namespace DMC.Classes 
{ 
    public class authCookie 
    { 
     public void cookiePrep(Login LoginUser) 
     { 
      string userData = "unknown|unknown"; 

      // Concat the values into a single string to pass into the cookie 
      userData = getUserData(LoginUser.UserName); 

      // Create the cookie that contains the forms authentication ticket 
      HttpCookie authCookie = FormsAuthentication.GetAuthCookie(LoginUser.UserName, LoginUser.RememberMeSet); 

      // Get the FormsAuthenticationTicket out of the encrypted cookie 
      FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value); 
      FormsAuthenticationTicket newTicket = new FormsAuthenticationTicket(3, 
                       ticket.Name, 
                       ticket.IssueDate, 
                       ticket.Expiration, 
                       LoginUser.RememberMeSet, 
                       userData, 
                       ticket.CookiePath); 

      // Manually add the authCookie to the Cookies collection 
      authCookie.Value = FormsAuthentication.Encrypt(newTicket); 
      HttpContext.Current.Response.Cookies.Add(authCookie); 

      string redirUrl = FormsAuthentication.GetRedirectUrl(LoginUser.UserName, LoginUser.RememberMeSet); 

      if (redirUrl == null) 
       redirUrl = "../default.aspx"; 

      HttpContext.Current.Response.Redirect(redirUrl); 
     } 

     public string getUserData(string userID) 
     { 
      string userData = ""; 

      // Grab this user's firstname, personID, and Admin status 
      string mySQL = "exec get_adBasicInfo @userName"; 
      string cf = System.Configuration.ConfigurationManager.ConnectionStrings["DistrictAssessmentDWConnectionString"].ConnectionString; 

      SqlConnection connection = new SqlConnection(cf); 
      SqlCommand command = new SqlCommand(mySQL, connection); 

      command.Parameters.AddWithValue("@userName", userID); 

      connection.Open(); 

      SqlDataReader dr = command.ExecuteReader(); 

      if (dr.HasRows) 
      { 
       while (dr.Read()) 
        userData = string.Concat(dr["personID"], "|", dr["firstName"], "|", dr["secBlur"]); 
      } 

      dr.Close(); 

      return userData; 
     } 

     public void validate() 
     { 
      HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName]; 

      if (authCookie != null) 
      { 
       FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value); 

       /********************************************************************************************************************** 
       * Version 3: Added the secBlur field onto the userData string to see if logged in user needs to have sensitive  * 
       *    data blurred out (0: Normal; 1: Blur Sensitive Data             * 
       **********************************************************************************************************************/ 
       if ((ticket.Version != 3) || (ticket.UserData == "")) 
       { 
        string userData = getUserData(ticket.Name); 

        FormsAuthenticationTicket newAuthTicket = new FormsAuthenticationTicket(3, 
                          ticket.Name, 
                          ticket.IssueDate, 
                          ticket.Expiration, 
                          ticket.IsPersistent, 
                          userData, 
                          ticket.CookiePath); 
        authCookie.Value = FormsAuthentication.Encrypt(newAuthTicket); 
        HttpContext.Current.Response.SetCookie(authCookie); 
       } 
      } 
     } 
    } 
} 

A ce contrôle du point passe en arrière vers la fonction load_page de ma page principale et tente de récupérer le prenom de l'utilisateur à partir du cookie en appelant ma classe formValues, ci-dessous:

using DMC.Classes; 
using System.Web; 
using System.Web.Security; 

namespace DMC.Classes 
{ 
    public class formValues : System.Web.Services.WebService 
    { 
     public string firstName = getFirstName(); 
     public string personID = getPersonID(); 
     public string secBlur = getSecBlur(); 

     private static string getUserDataString(int ix) 
     { 
      string retValue = ""; 

      if (HttpContext.Current.Request.IsAuthenticated) 
      { 
       HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName]; 

       if (authCookie != null) 
       { 
        FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value); 

        if (ticket != null) 
        { 
         string[] userData = { "" }; 

         char[] delimiterChar = { '|' }; 
         userData = ticket.UserData.Split(delimiterChar); 

         retValue = userData[ix]; 
        } 
       } 
      } 

      return retValue; 
     } 

     private static string getFirstName() 
     { 
      string firstName = getUserDataString(1); 

      return firstName; 
     } 

     private static string getPersonID() 
     { 
      string personID = getUserDataString(0); 

      return personID; 
     } 

     private static string getSecBlur() 
     { 
      string secBlur = getUserDataString(2); 

      return secBlur; 
     } 
    } 
} 

sur En essayant de getFirstName, j'obtiens une erreur dans la méthode getUserDataString lorsque j'essaie de définir la valeur retValue car le tableau userData est vide. Alors, quelqu'un peut-il me dire où je me trompe?

Répondre

0

Dans ma classe de authcookie, j'ai changé de:

HttpContext.Current.Response.SetCookie(authCookie); 

à

HttpContext.Current.Response.Add(authCookie); 

Je ne suis pas fan de ce bien, parce que d'après ce que je lis, si le cookie existe déjà, cela n'écrase pas le cookie, il va juste créer un doublon. Mais j'ai joué et c'est la seule chose qui semble fonctionner. Si quelqu'un a une meilleure solution, s'il vous plaît partager !!