2012-06-29 78 views
2

我試圖將保存的FormsAuthenticationTicket使用下面的代碼(在AccountController.cs)一個cookie:FormsAuthentication餅乾不是持久

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket 
      (1, user.UserEmail, DateTime.Now, 
      DateTime.Now.AddMinutes(FormsAuthentication.Timeout.TotalMinutes), 
      false, null); 

string encTicket = FormsAuthentication.Encrypt(ticket); 
HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, 
ticket.ToString()); 
HttpContext.Response.Cookies.Add(faCookie); 

if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/") 
      && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\")) 
      { 
      return Redirect(returnUrl); 
      } 
      else 
      { 
      return RedirectToAction("Index", "Home"); 
      } 

當我通過調試步驟,一切似乎就好了。直到我去Application_AuthenticateRequest,在那裏我嘗試檢索該cookie:

HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName]; 

     if (authCookie != null) 
     { 
     //do stuff here 
     } 

當我看到Cookies集合中,但只是什麼都沒有。我可以在AccountController代碼中添加另一個正常的cookie,它顯示得很好。無論我是否包含UserData,問題依然存在,所以我不認爲這是一個尺寸問題。

感謝您提供的任何見解。

回答

1

您正在將Cookie添加到響應中。一旦你完成了,確保你立即重定向。只有在隨後的請求中,您才能希望從Request.Cookies集合中讀取它。

+0

感謝您的建議。我實際上是重定向,在此之後,正常的cookie可用,票不是。 – acullen72

2

Cookie的最大大小爲4096字節。如果超過這個,cookie不會被保存。

使用以下檢查Cookie尺寸:

int cookieSize = System.Text.UTF8Encoding.UTF8.GetByteCount(faCookie.Values.ToString()); 
0

您設置isPersistent參數設置爲false,當你創建你的FormsAuthenticationTicket。該參數應該設置爲true。

1

儘管您的身份驗證票據設置爲永久性的並且具有過期日期,但實際的Cookie不會。

創建cookie時添加這樣的事情:

var faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket) 
        { 
         Expires = ticket.Expiration 
        }; 
+1

拯救了我的一天@Ted Nyberg! – EdsonF

1

在你的代碼寫的cookie,你不能傳遞一個空的用戶數據參數與加密的Cookie。 IsPersistent爲false是好的。

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket 
      (1, user.UserEmail, DateTime.Now, 
      DateTime.Now.AddMinutes(FormsAuthentication.Timeout.TotalMinutes), 
      false, null); 

做這樣的事情如下: 在我的例子,你可以用一個空字符串替換userData.ToString()。只是不要將它傳遞給null!這應該能解決你的問題。

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
      1,        // version 
      userId.UserEmail,      // a unique value that identifies the user 
      DateTime.Now,     // created 
      DateTime.Now.AddMinutes(FormsAuthentication.Timeout.TotalMinutes), // expires 
      false,     // persistent? 
      userData.ToString(), // user specific data (optional) //NOTE: DO NOT pass NULL as encrypted string value will become NULL (argh) 
      FormsAuthentication.FormsCookiePath // the path for the cookie 
      ); 

然後在你的global.asax.cs 您將檢查在FormsAuthentication_OnAuthenticate事件 您的代碼將在這裏有所不同的是餅乾,我寫了一個自定義表單認證和正在使用用戶ID,而不是電子郵件中你的情況。

如果您在編寫auth cookie時爲您的UserData參數傳遞null,請注意以下邏輯失敗。

if (authCookie == null || authCookie.Value == "") 
    { 
     return; 
    } 

這裏是在globalasax.cs文件的完整事件:

protected void FormsAuthentication_OnAuthenticate(Object sender, FormsAuthenticationEventArgs e) 
{ 
    //STEP #1 of Authentication/Authorization flow 
    //Reference: http://msdn.microsoft.com/en-us/library/ff649337.aspx 
    //================================================================== 
    if (FormsAuthentication.CookiesSupported == true) 
    { 

     //Look for an existing authorization cookie when challenged via [Authorize] 
     HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName]; 
     if (authCookie == null || authCookie.Value == "") 
     { 
      return; 
     } 
     FormsAuthenticationTicket authTicket = null; 
     try 
     { 
      //Reading from the ticket 
      authTicket = FormsAuthentication.Decrypt(authCookie.Value); 
      //Check the Cookiename (which in this case is UserId). If it is null, then we have an issue 
      if (authTicket.Name == null) 
      { 
       FormsAuthentication.SignOut(); 
       authCookie.Value = null; 
      } 

     } 
     catch (Exception ex) 
     { 
      //Unable to decrypt the auth ticket 
      return; 
     } 

     //get userId from ticket 
     string userId = authTicket.Name; 


     Context.User = new GenericPrincipal(
        new System.Security.Principal.GenericIdentity(userId, "MyCustomAuthTypeName"), authTicket.UserData.Split(',')); 

     //We are officially 'authenticated' at this point but not neccessarily 'authorized' 
    } 
    else 
    { 
     throw new HttpException("Cookieless Forms Authentication is not supported for this application."); 

    } 
} 
+0

嗨非常感謝你我有一個類似的問題,我解決它基於你的答案。我的代碼非常好,除了我已將「FormsAuthenticationTicket」設置爲持久化,並且僅有的原因不起作用。如果你知道,請解釋爲什麼會發生這種情況?謝謝! – CodeArtist