[ASP.NET]'encryptedTicket' 參數的值無效。

做完windows更新後,系統居然發生「'encryptedTicket' 參數的值無效」的錯誤???

最近公司及有些客戶Windows 2008 R2的環境有做Windows Update。

原本有安裝.NET 4.0的AP Server會被新到.NET 4.5。

結果有些程式就會發生「System.Web.Security.FormsAuthentication.Decrypt  <System.ArgumentException> 'encryptedTicket' 參數的值無效。」的錯誤,如下,

image

 

拿程式來測試,在畫面上放一個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 個字元。」。

image

所以當我在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:從零開始的軟體開發生活

請大家繼續支持 ^_^