问题
We've built a Relying Party application based on the Windows Identity Foundation. We followed the advice in Vittorio's book and created a custom set of cookie transforms to use RSA to encrypt/sign the token.
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 );
}
We configured a in the web.config.
<microsoft.identityModel>
<service>
<serviceCertificate>
<certificateReference x509FindType="FindByThumbprint" findValue="C7FD338059CCB374798923A915BC91B718814A8E" storeLocation="LocalMachine" storeName="TrustedPeople" />
</serviceCertificate>
</service>
</microsoft.identityModel>
I know the code in the OnServiceConfigurationCreated is executing because if I put a garbage thumbprint value into the config file the OnServiceConfigurationCreated throws an exception.
Unfortunately we are frequently getting the following exception showing up in our logs.
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)
We believe this exception is causing other problems in the system but can't figure out why it's occurring. We have three web servers and we've triple-checked that they are all configured to use the same certificate thumbprint and that the certificate is installed in the same place on all three servers.
We are also using a custom SessionAuthenticationModule to handle sliding session expiration. I thought that maybe when that code (below) was reissuing the cookie it might be using a different encryption/signing approach but I'm pretty sure I've tested it and that doesn't seem to be the case. I'm including it only in the interest of full disclosure.
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;
}
}
From what we can tell we've done everything the docs/blogs/etc have said but we're still getting this exception. Any tips/pointers/educated guesses would be helpful at this point.
回答1:
You might want to check the total size of cookie data your application sets. If you include lots of claims, the cookies grow accordingly unless you use session mode. E.g. Safari has a 4K limit on total cookie data size. If you break this limit you'd start losing cookies, which could mean you'd lose a cookie with part of the signature.
As a side note, if you can move to WIF 4.5 you have the option of using the MachineKeySessionSecurityTokenHandler instead of doing the certficate based cookie encryption.
来源:https://stackoverflow.com/questions/15252663/wif-id1014-the-signature-is-not-valid-the-data-may-have-been-tampered-with