SessionSecurityTokenHandler 嘗試使用 DPAPI 解密 RSA 加密 cookie 中的 SessionSecurityToken;為什麼?
我在 MSDN 論壇、Dominic Baier 的部落格和其他來源中讀到 DPAPI 在 Azure 中無法開箱即用,並且在任何類型的網路場場景中處理聯合身份驗證的一種方法是替換 DPAPI 轉換一個使用整個場中可用的私鑰,例如使用 X509 證書的 RSA 加密。我在我的 Azure MVC 應用程序中採用了這種方法並配置
SessionSecurityTokenHandler如下:FederatedAuthentication.ServiceConfigurationCreated += (sender, args) => { var sessionTransforms = new List<CookieTransform>(new CookieTransform[] { new DeflateCookieTransform(), new RsaEncryptionCookieTransform(args.ServiceConfiguration.ServiceCertificate), new RsaSignatureCookieTransform(args.ServiceConfiguration.ServiceCertificate) }); var sessionHandler = new SessionSecurityTokenHandler(sessionTransforms.AsReadOnly()); args.ServiceConfiguration.SecurityTokenHandlers.AddOrReplace(sessionHandler); };使用此配置,我們能夠從身份提供者接收令牌並發布使用這些轉換加密的安全 cookie。在 Azure 模擬器中執行,一切正常。但是,在 Azure 環境中,我們在瀏覽器中間歇性地看到以下錯誤:
Key not valid for use in specified state. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: System.Security.Cryptography.CryptographicException: Key not valid for use in specified state. Source Error: An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below. Stack Trace: [CryptographicException: Key not valid for use in specified state. ] System.Security.Cryptography.ProtectedData.Unprotect(Byte[] encryptedData, Byte[] optionalEntropy, DataProtectionScope scope) +577 Microsoft.IdentityModel.Web.ProtectedDataCookieTransform.Decode(Byte[] encoded) +80 [InvalidOperationException: ID1073: A CryptographicException occurred when attempting to decrypt the cookie using the ProtectedData API (see inner exception for details). If you are using IIS 7.5, this could be due to the loadUserProfile setting on the Application Pool being set to false. ] Microsoft.IdentityModel.Web.ProtectedDataCookieTransform.Decode(Byte[] encoded) +433 Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ApplyTransforms(Byte[] cookie, Boolean outbound) +189 Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver) +862 Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(Byte[] token, SecurityTokenResolver tokenResolver) +109 Microsoft.IdentityModel.Web.SessionAuthenticationModule.ReadSessionTokenFromCookie(Byte[] sessionCookie) +356 Microsoft.IdentityModel.Web.SessionAuthenticationModule.TryReadSessionTokenFromCookie(SessionSecurityToken& sessionToken) +123 Microsoft.IdentityModel.Web.SessionAuthenticationModule.OnAuthenticateRequest(Object sender, EventArgs eventArgs) +61 System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +80 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +270這似乎表明
SessionSecurityTokenHandler正在嘗試使用 DPAPI 解密 cookie,但為什麼呢?我不是將它配置為使用上面的 RSA 嗎?
好吧,經過大量搜尋,我已經弄清楚我的問題是什麼。
ServiceConfigurationCreated在我設置FederatedAuthentication.ServiceConfiguration. 根據 MSDN,“當 Web 應用程序中的第一個 HTTP 模組引用 ServiceConfiguration 時,會引發 ServiceConfigurationCreated 事件”。我將事件處理程序設置移動到頂部,Application_Start並且一切正常,這意味著該事件(僅觸發一次)在我設置事件處理程序之前觸發。希望這可以節省我將其執行到地面所花費的 4 個多小時。
請注意,您現在可以使用
MachineKeySessionSecurityTokenHandler跨網路場簽署和加密會話令牌。要使用它,您需要刪除預設值
SessionSecurityTokenHandler並添加MachineKeySessionSecurityTokenHandlerinWeb.config:<system.identityModel> <identityConfiguration> <securityTokenHandlers> <remove type="System.IdentityModel.Tokens.SessionSecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <add type="System.IdentityModel.Services.Tokens.MachineKeySessionSecurityTokenHandler, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> </securityTokenHandlers> </identityConfiguration> </system.identityModel>使用
MachineKeySessionSecurityTokenHandler配置的機器密鑰,Web.config因此您也需要添加:<system.web> <machineKey validationKey="..." decryptionKey="..." validation="SHA1" decryption="AES" /> </system.web>在BrainThud上看到這個問題