2011-11-22 80 views
11

我有一個使用Windows Identity Foundation的聲明感知Web應用程序,一直運行良好,除了在一臺服務器上。我在事件日誌中看到下面顯示的錯誤消息。Microsoft.IdentityModel:密鑰在指定狀態下無效

Exception information: 
    Exception type: CryptographicException 
    Exception message: Key not valid for use in specified state. 

    at System.Security.Cryptography.ProtectedData.Unprotect(Byte[] encryptedData, Byte[] optionalEntropy, DataProtectionScope scope) 
    at Microsoft.IdentityModel.Web.ProtectedDataCookieTransform.Decode(Byte[] encoded) 

此應用程序使用非常標準的WIF與ADFS v2實現。它沒有使用RsaEncryptionCookieTransform。我正在尋找有關如何診斷此問題的任何建議。我已嘗試到目前爲止的事情:

  1. 應用程序池使用的ASP.NET v4.0身份的「加載用戶配置文件」設置設置爲true。
  2. 我刪除了C:\ Users \ ASP.NET v4.0 \ AppData文件夾,並看到這已成功重新創建。
  3. 我檢查了證書私鑰的權限,這很好。我也嘗試禁用令牌加密,這沒有任何區別。

任何意見,將不勝感激。

回答

15

這通常是由應用程序無法解密身份驗證令牌cookie引起的。確保擁有App Pool的身份擁有足夠的權限訪問您的證書存儲。嘗試將身份更改爲NetworkService,看看是否有幫助。

您還應該清除瀏覽器的Cookie,以確保您沒有緩存來自其他應用程序的Cookie。

+1

謝謝。您確認我懷疑這是Cookie相關的,因此我做了大量的試驗和錯誤,並發現這是由另一個WIF安全的Web應用程序(在另一臺服務器上)創建了WIF cookie,其路徑顯然正試圖解密通過這個Web應用程序。我通過調整兩個應用程序使用的路徑值來解決這個問題。奇怪的是,我只在IE瀏覽器中看到這個錯誤,而不是Firefox/Chrome瀏覽器。我將不得不花更多時間來更好地理解這個問題。 –

+0

我遇到了同樣的事情。很高興你能解決問題。我不知道爲什麼你只能在IE中看到這個,但改變cookie路徑應該是修復。 –

+0

我在意外刪除本地網站後遇到同樣的問題。刪除wif和asp.net cookies的確有竅門。 –

7

的問題是100%可重複:

事實上,應用程序被重新部署後,老驗證cookie留在客戶端計算機上(客戶端沒有註銷) - 這種錯誤出現在客戶端上的任何按照要求。 要解決此錯誤,客戶必須刪除cookie和/或登錄,然後從STS註銷。一旦完成 - 錯誤消失,一切都很好,直到下次升級....

經過一番研究,我認爲這是SessionAuthenticationModule中需要修復的一個錯誤。如果仔細查看上面的堆棧跟蹤,有一個有趣的方法稱爲TryReadSessionTokenFromCookie,它設置期望認證模塊將「嘗試」從cookie中讀取令牌,並且如果這種方式失敗將返回false - 代碼是這裏(感謝ReSharper的):

public bool TryReadSessionTokenFromCookie(out SessionSecurityToken sessionToken) 
{ 
    byte[] sessionCookie = this.CookieHandler.Read(); 
    if (sessionCookie == null) 
    { 
     sessionToken = null; 
     return false; 
    } 
    sessionToken = this.ReadSessionTokenFromCookie(sessionCookie); 
    if (DiagnosticUtil.TraceUtil.ShouldTrace(TraceEventType.Verbose)) 
    { 
     DiagnosticUtil.TraceUtil.Trace(TraceEventType.Verbose, TraceCode.Diagnostics, SR.GetString("TraceValidateToken", new object[0]), new TokenTraceRecord(sessionToken), null); 
    } 
    return true; 
} 

顯然,代碼這種方法與未處理的錯誤和失敗,開發商沒有任何選項來處理錯誤或多或少合理的方式離開。 (...或者至少我找不到任何東西,因爲這個HTTP模塊不會將這個錯誤傳遞給HttpApplication對象進行處理,並將其拋入用戶的臉部。) 所以,我認爲有兩個錯誤: 1)安全令牌處理程序需要針對拋出的ID1073(服務器端解密錯誤或錯誤(舊)cookie錯誤)的推理更具體。 2)開發人員必須有一種方法來處理此錯誤並註銷用戶,如果它發生。我會採取任何幫助,在這一個... 任何人都可以請創建一個示例代碼,顯示如何攔截此異常,以便用戶可以自動註銷時,此錯誤發生?同樣,Application.Error事件似乎並沒有從這個模塊中被觸發 - 不知道除了編寫我自己的SessionAuthenticationModule之外還有什麼可以處理它。 任何幫助高度讚賞! 謝謝! 亞歷克斯

+1

Application_Error全局處理程序似乎是適當的地方。 'var exc = Server.GetLastError();' 'if(exc是CryptographicException || exc.InnerException是CryptographicException)' '{Server.ClearError(); ResetAuthentication(); }' 爲我工作。 – achekh

+1

我面臨同樣的問題,雖然這種情況發生在我更頻繁的基礎上;我看到的行爲表明某種過期正在發生,導致應用程序無法讀取令牌cookie。我不明白爲什麼你或我看到了我們所看到的行爲。 –

+5

@achekh我很currious如何實現ResetAuthentication?你可以請分享一下這個實現!謝謝! – Fore

1

刪除FedAuth cookies可能會起作用。當異常發生時,試試這個在Global.asax文件的Application_Error方法:

Microsoft.IdentityModel.Web.FederatedAuthentication.SessionAuthenticationModule.SignOut(); 
2

我解決我的情況,因爲我有同樣的cookie名稱「FedAuth」兩個應用程序(這是默認的名稱)。只要把不同的名稱和它的決心:

<system.identityModel.services> 
<federationConfiguration> 
    <cookieHandler name="ACookieName" /> 
</federationConfiguration> 

2

以下爲我工作:

您需要添加部分system.identityModel/identityConfiguration

參考: SessionSecurityTokenHandler trying to decrypt SessionSecurityToken in RSA-encrypted cookie using DPAPI; why?

<system.identityModel> 
    <identityConfiguration saveBootstrapContext="true"> 
     <audienceUris> 
     <add value="yoursite.com" /> 
     </audienceUris> 
     <issuerNameRegistry type="Thinktecture.IdentityModel.Tokens.MetadataBasedIssuerNameRegistry, Thinktecture.IdentityModel"> 
     <trustedIssuerMetadata issuerName="urn:federation:company:stage" metadataAddress="https://federation-sts-stage.company.com/FederationMetadata/2007-06/FederationMetadata.xml"></trustedIssuerMetadata> 
     </issuerNameRegistry> 
     <certificateValidation certificateValidationMode="None" /> 
<securityTokenHandlers> 
    <add type="System.IdentityModel.Services.Tokens.MachineKeySessionSecurityTokenHandler, 
      System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> 

     <remove type="System.IdentityModel.Tokens.SessionSecurityTokenHandler, 
      System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> 
    </securityTokenHandlers> 
    </identityConfiguration> 
    </system.identityModel> 
相關問題