做完windows更新後,系統居然發生「'encryptedTicket' 參數的值無效」的錯誤???
最近公司及有些客戶Windows 2008 R2的環境有做Windows Update。
原本有安裝.NET 4.0的AP Server會被新到.NET 4.5。
結果有些程式就會發生「System.Web.Security.FormsAuthentication.Decrypt <System.ArgumentException> 'encryptedTicket' 參數的值無效。」的錯誤,如下,
拿程式來測試,在畫面上放一個TextBox (TextBox1)及2個Button(Button1, Button2), Button1透過FormsAuthentication.Encrypt 建立包含已加密表單驗證票證的字串,Button2將Button1建立的字串,解密回來,如下,
aspx 如下,
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
<br />
<asp:TextBox ID="TextBox1" runat="server" Width="1343px"></asp:TextBox>
<br />
<asp:Button ID="Button2" runat="server" Text="Button" OnClick="Button2_Click" />
</div>
</form>
</body>
</html>
aspx.cs 如下,
//using System.IO;
//using System.Runtime.Serialization.Formatters.Binary;
//using System.Security.Principal;
//using System.Web.Security;
protected void Button1_Click(object sender, EventArgs e)
{
string userName = "Rainmaker";
GenericIdentity MyIdentity = new GenericIdentity(userName, User.Identity.AuthenticationType);
String[] MyStringArray = { };
GenericPrincipal MyPrincipal = new GenericPrincipal(MyIdentity, MyStringArray);
HttpContext.Current.User = MyPrincipal;
BinaryFormatter bf = new BinaryFormatter();
MemoryStream buffer = new MemoryStream();
bf.Serialize(buffer, HttpContext.Current.User);
buffer.Position = 0;
string principalText = Convert.ToBase64String(buffer.GetBuffer());
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, userName
, DateTime.Now, DateTime.Now.AddMinutes(HttpContext.Current.Session.Timeout)
, false, principalText);
string encTicket = FormsAuthentication.Encrypt(ticket);
TextBox1.Text = encTicket;
}
protected void Button2_Click(object sender, EventArgs e)
{
FormsAuthenticationTicket tic = FormsAuthentication.Decrypt(TextBox1.Text);
}
VB的Code,
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim roles() As String
Dim identity As New GenericIdentity("Rainmaker")
Dim principal As New GenericPrincipal(identity, roles)
HttpContext.Current.User = principal
Dim principalText As String, buffer As New IO.MemoryStream
Dim formatter As New Runtime.Serialization.Formatters.Binary.BinaryFormatter
formatter.Serialize(buffer, HttpContext.Current.User)
buffer.Position = 0
principalText = Convert.ToBase64String(buffer.GetBuffer)
Dim ticket As New FormsAuthenticationTicket(1, HttpContext.Current.User.Identity.Name, _
Now, Now.AddMinutes(HttpContext.Current.Session.Timeout), False, principalText)
Dim encTicket As String = FormsAuthentication.Encrypt(ticket)
TextBox1.Text = encTicket
End Sub
在VS.NET中我使用.NET 3.5來測試都不會有任何的錯誤,而切到.NET 4.0 or 4.5 or 4.5.1(實際是使用.NET 4.5的DLL)就會發生錯誤。
查看MSDN中FormsAuthentication.Decrypt 方法,在.NET 4.5版本中多了一個限制,就是「ncryptedTicket 的長度大於 4096 個字元。」。
所以當我在FormsAuthenticationTicket中指定過多的資料,長度就一定會超過 4096 ,所以自然就會發生「'encryptedTicket' 參數的值無效。」的這個錯誤。
而在.NET 4.5(.NET 4.0 ~ .NET 1.1)以前的版本並沒有這個限制。
所以目前的解法就只能放少一點的資料。
參考資料
FormsAuthentication.Decrypt 方法 (.NET 4.5)
FormsAuthentication.Decrypt 方法 (.NET 4.0)
Hi,
亂馬客Blog已移到了 「亂馬客 : Re:從零開始的軟體開發生活」
請大家繼續支持 ^_^