web-dev-qa-db-ja.com

Microsoft.IdentityModel:指定された状態での使用にはキーが無効です

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を使用していません。私はこれを診断する方法についての提案を探しています。私がこれまでに試したこと:

  1. アプリケーションプールは、「ユーザープロファイルの読み込み」設定がtrueに設定されているASP.NET v4.0IDを使用しています。
  2. C:\ Users\ASP.NET v4.0\AppDataフォルダーを削除したところ、これが正常に再作成されたことがわかりました。
  3. 証明書の秘密鍵のアクセス許可を確認しましたが、これは問題ありませんでした。また、トークンの暗号化を無効にしてみましたが、違いはありませんでした。

何かアドバイスをいただければ幸いです。

11
Brice Williams

これは通常、アプリケーションが認証トークンCookieを復号化できないことが原因で発生します。アプリプールを所有するIDに、証明書ストアにアクセスするための十分な権限があることを確認してください。 IdentityをNetworkServiceに変更してみて、それが役立つかどうかを確認してください。

また、ブラウザのCookieをクリアして、別のアプリケーションからのCookieがキャッシュされていないことを確認する必要があります。

16
Garrett Vlieger

問題は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非常に感謝しています!!!ありがとう!アレックス

7
Alex Cherkasov

2つのアプリケーションで同じCookie名「FedAuth」を使用しているため、ケースを解決します(これはデフォルトの名前です)。別の名前を付けるだけで解決します:

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

以下は私のために働いた:

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>
2

FedAuthCookieを削除すると機能する場合があります。例外が発生した場合は、Application_ErrorファイルのGlobal.asaxメソッドでこれを試してください。

Microsoft.IdentityModel.Web.FederatedAuthentication.SessionAuthenticationModule.SignOut();
1
God Inez

このエラーはhttpアプリケーションでは検出されないようです。代わりに http://social.technet.Microsoft.com/wiki/contents/articles/1898.aspx#Q1 をチェックしてください。

0
user1431276

この問題は、許可が不十分なために発生します。アプリプールは、それを機能させるためにApplicationPoolIdentity IDを持っている必要があります。アプリプール-> [詳細設定]-> [組み込みアカウント]に移動して、設定を変更します

0
Nikhil Dinesh