認証にはWIF(.net 4.5)とAzure Active Directoryを使用しています。 WebサイトはAzureに配置されます。
すべてがローカルで期待どおりに動作しますが、Azureに配置するとエラーが発生します。
データ保護操作は失敗しました。これは、現在のスレッドのユーザーコンテキストに対してユーザープロファイルが読み込まれていないことが原因である可能性があります。これは、スレッドが偽装している場合に発生することがあります。
これはアプリがDAPIを使用できないためであると理解しているため、アプリをMACで保護するように切り替える必要があります。
ローカルでこれを自分のwebconfigに追加しました:
<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>
documentation で推奨されているように、静的なマシンキーを追加しましたが、キーの長さに関するアドバイスが見つからないため、256と想定しています。
ただし、この構成ではこのエラーが発生します。
[CryptographicException:暗号化操作中にエラーが発生しました。] System.Web.Security.Cryptography.HomogenizingCryptoServiceWrapper.HomogenizeErrors(Func`2 func、Byte [] input)+115 System.Web.Security.Cryptography.HomogenizingCryptoServiceWrapper.Unprotect(Byte [] protectedData)+59 System.Web.Security.MachineKey.Unprotect(ICryptoServiceProvider cryptoServiceProvider、Byte [] protectedData、String []目的)+62 System.Web.Security.MachineKey.Unprotect(Byte [] protectedData、String []目的)+ 122 System.IdentityModel.Services.MachineKeyTransform.Decode(Byte [] encoding)+161 System.IdentityModel.Tokens.SessionSecurityTokenHandler.ApplyTransforms(Byte [] cookie、Boolean outbound)+123 System.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(XmlReaderリーダー、SecurityTokenResolver tokenResolver)+575 System.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(Byte [] token、SecurityTokenResolver tokenResolver)+76 System.IdentityModel.Services.SessionAuthenticationMod ule.ReadSessionTokenFromCookie(Byte [] sessionCookie)+833 System.IdentityModel.Services.SessionAuthenticationModule.TryReadSessionTokenFromCookie(SessionSecurityToken&sessionToken)+186 System.IdentityModel.Services.SessionAuthenticationModule.OnAuthenticateRequest(Object sender、EventArgs eventArgs)+210 System.Web.SyncEventExecutionStep。 System.Web.HttpApplication.IExecutionStep.Execute()+136 System.Web.HttpApplication.ExecuteStep(IExecutionStep step、Boolean&completedSynchronously)+69
正しい形式のキーを指定しなかった場合に備えて、machinekeyセクションを削除しましたが、エラーは解消されません。
WIFとの戦いはなんということでしょう。
構成でmachineKeyを指定しない場合、Azureによって追加されます。ただし、アプリケーションの新しいバージョンを作成し、VIPスイッチングを使用してAzureにデプロイすると、Azureはステージングでのデプロイメント用に新しいマシンキーを生成します(最初のデプロイメントが本番環境であると想定)。(VIPスイッチングは、新しいバージョンをデプロイしてから仮想IPアドレスを本番とステージングの間で切り替えるための素晴らしいメカニズムです。
つまり、基本的に1つの解決策は、Azureにキーを生成させることですが、VIPスイッチに切り替えた後に問題が発生します。それを回避するには、Application.ErrorハンドラーのGlobal.asaxのCryptographicExceptionを次のようにキャッチします。
// Be sure to reference System.IdentityModel.Services
// and include using System.IdentityModel.Services;
// at the start of your class
protected void Application_Error(object sender, EventArgs e)
{
var error = Server.GetLastError();
var cryptoEx = error as CryptographicException;
if (cryptoEx != null)
{
FederatedAuthentication.WSFederationAuthenticationModule.SignOut();
Server.ClearError();
}
}
SignOut()メソッドにより、Cookieが削除されます。
Edit:@anjdreasによって記録されたmachineKeyの生成に関する情報を更新しました。
別の解決策はmachineKeyを生成することです。IIS Managerを使用して実行できます。詳細は MachineKeyを生成する最も簡単な方法 を参照してください。同じキーをすべてのAzure Webロール内のWebアプリケーション。Azure展開プロセスはそれを置き換えません。
マシンキーが存在しないようにする必要があります。WindowsAzureがマシンキーを生成し、役割のすべてのインスタンスで同じであることを確認します。
表示されているエラーについて:Cookieをクリアしてみてください。
この場合、単にCookieをクリアするだけで問題全体が解決しました。
フォーム認証を使用している場合。例外をキャッチしたときにサインアウトし、ユーザーがログインして有効なCookieを作成できるようにする
catch (CryptographicException cex)
{
FormsAuthentication.SignOut();
}