Windows Identity Foundation に基づいて Relying Party アプリケーションを構築しました。Vittorio の本のアドバイスに従い、RSA を使用してトークンを暗号化/署名するための Cookie 変換のカスタム セットを作成しました。
private void OnServiceConfigurationCreated( object sender, ServiceConfigurationCreatedEventArgs e )
{
List<CookieTransform> sessionTransforms = new List<CookieTransform>( new CookieTransform[]
{
new DeflateCookieTransform(),
new RsaEncryptionCookieTransform( e.ServiceConfiguration.ServiceCertificate ),
new RsaSignatureCookieTransform( e.ServiceConfiguration.ServiceCertificate )
} );
SessionSecurityTokenHandler sessionHandler =
new SessionSecurityTokenHandler( sessionTransforms.AsReadOnly() );
e.ServiceConfiguration.SecurityTokenHandlers.AddOrReplace( sessionHandler );
}
web.config で構成しました。
<microsoft.identityModel>
<service>
<serviceCertificate>
<certificateReference x509FindType="FindByThumbprint" findValue="C7FD338059CCB374798923A915BC91B718814A8E" storeLocation="LocalMachine" storeName="TrustedPeople" />
</serviceCertificate>
</service>
</microsoft.identityModel>
OnServiceConfigurationCreated のコードが実行されていることはわかっています。構成ファイルにガベージ サムプリントの値を入れると、OnServiceConfigurationCreated が例外をスローするからです。
残念ながら、ログに次の例外が頻繁に表示されます。
System.Security.Cryptography.CryptographicException: ID1014: The signature is not valid. The data may have been tampered with.
at Microsoft.IdentityModel.Web.RsaSignatureCookieTransform.Decode(Byte[] encoded)
at Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ApplyTransforms(Byte[] cookie, Boolean outbound)
at Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver)
at Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(Byte[] token, SecurityTokenResolver tokenResolver)
at Microsoft.IdentityModel.Web.SessionAuthenticationModule.ReadSessionTokenFromCookie(Byte[] sessionCookie)
at Microsoft.IdentityModel.Web.SessionAuthenticationModule.TryReadSessionTokenFromCookie(SessionSecurityToken& sessionToken)
at Microsoft.IdentityModel.Web.SessionAuthenticationModule.OnAuthenticateRequest(Object sender, EventArgs eventArgs)
at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
この例外がシステム内で他の問題を引き起こしていると考えていますが、なぜそれが発生しているのかを突き止めることはできません。3 つの Web サーバーがあり、それらがすべて同じ証明書の拇印を使用するように構成されていること、および証明書が 3 つのサーバーすべての同じ場所にインストールされていることをトリプルチェックしました。
また、カスタム SessionAuthenticationModule を使用して、スライド セッションの有効期限を処理しています。そのコード (以下) がCookieを再発行しているときに、別の暗号化/署名アプローチを使用している可能性があると思いましたが、テストしたことは確かであり、そうではないようです。私はそれを完全な開示のためにのみ含めています。
void CustomSessionAuthenticationModule_SessionSecurityTokenReceived( object sender, SessionSecurityTokenReceivedEventArgs e )
{
DateTime now = DateTime.UtcNow;
DateTime validFrom = e.SessionToken.ValidFrom;
DateTime validTo = e.SessionToken.ValidTo;
double tokenLifetime = (validTo - validFrom).TotalMinutes;
SessionAuthenticationModule sam = sender as SessionAuthenticationModule;
if( now < validTo && now > validFrom.AddMinutes( tokenLifetime / 2 ) )
{
e.SessionToken = sam.CreateSessionSecurityToken(
e.SessionToken.ClaimsPrincipal, e.SessionToken.Context,
now, now.AddMinutes( tokenLifetime ), e.SessionToken.IsPersistent );
e.ReissueCookie = true;
}
}
docs/blogs/etc に記載されていることはすべて実行しましたが、まだこの例外が発生しています。この時点で、ヒント/ポインター/知識に基づいた推測が役立ちます。