1台のサーバーを除いて、正常に機能しているWindows IdentityFoundationを使用したクレーム対応Webアプリケーションがあります。イベントログに以下のエラーメッセージが表示されます。
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)
このアプリケーションは、ADFSv2でのWIFの非常に標準的な実装を使用しています。 RsaEncryptionCookieTransformを使用していません。私はこれを診断する方法についての提案を探しています。私がこれまでに試したこと:
何かアドバイスをいただければ幸いです。
これは通常、アプリケーションが認証トークンCookieを復号化できないことが原因で発生します。アプリプールを所有するIDに、証明書ストアにアクセスするための十分な権限があることを確認してください。 IdentityをNetworkService
に変更してみて、それが役立つかどうかを確認してください。
また、ブラウザのCookieをクリアして、別のアプリケーションからのCookieがキャッシュされていないことを確認する必要があります。
問題は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オブジェクトに渡さず、ユーザーの顔にスローするため、何も見つかりませんでした。)したがって、2つのバグがあると思います:1)セキュリティトークンハンドラーは、スローされたID1073(サーバー側の復号化エラーまたは間違った(古い)Cookieエラー)の理由をより具体的にする必要があります2)開発者がこのエラーを処理し、発生した場合はユーザーをサインアウトする方法が必要です。私はこれについて何か助けを借ります...このエラーが発生したときにユーザーが自動的にサインアウトできるように、この例外をインターセプトする方法を示すサンプルコードを誰かが作成できますか?繰り返しになりますが、Application.Errorイベントはこのモジュールから発生していないようです。独自のSessionAuthenticationModuleを作成する以外に、それを処理するために他に何ができるかわかりません。どんな助けでもIS非常に感謝しています!!!ありがとう!アレックス
2つのアプリケーションで同じCookie名「FedAuth」を使用しているため、ケースを解決します(これはデフォルトの名前です)。別の名前を付けるだけで解決します:
<system.identityModel.services>
<federationConfiguration>
<cookieHandler name="ACookieName" />
</federationConfiguration>
以下は私のために働いた:
System.identityModel/identityConfigurationにセクションを追加する必要があります
参照: SessionSecurityTokenHandlerがDPAPIを使用してRSA暗号化CookieのSessionSecurityTokenを復号化しようとしています;なぜですか?
<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>
FedAuth
Cookieを削除すると機能する場合があります。例外が発生した場合は、Application_Error
ファイルのGlobal.asax
メソッドでこれを試してください。
Microsoft.IdentityModel.Web.FederatedAuthentication.SessionAuthenticationModule.SignOut();
このエラーはhttpアプリケーションでは検出されないようです。代わりに http://social.technet.Microsoft.com/wiki/contents/articles/1898.aspx#Q1 をチェックしてください。
この問題は、許可が不十分なために発生します。アプリプールは、それを機能させるためにApplicationPoolIdentity IDを持っている必要があります。アプリプール-> [詳細設定]-> [組み込みアカウント]に移動して、設定を変更します