我有一个aspnet核心应用程序,该应用程序使用带有Redis的数据保护来保留密钥。
已按照Microsoft文档中显示的示例添加了它: https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/implementation/key-storage-providers?view=aspnetcore-2.1&tabs=visual-studio#azure-and-redis
我已经创建了一个扩展方法,该方法调用PersistKeysToRedis方法并且不传递键值,因为它应该默认为'DataProtection-Keys'。
public static IDataProtectionBuilder PersistKeysToConfiguredRedis(this IDataProtectionBuilder builder, RedisConnection redisConnection)
{
redisConnection.ThrowIfNull(nameof(redisConnection));
var connection = redisConnection.GetConnection();
if (connection == null)
{
// No database configured
return builder;
}
return builder.PersistKeysToRedis(connection);
}
当我运行使用单个Redis实例的应用程序的多个实例时,在调用该应用程序时收到以下错误:
2019-05-24 10:06:22.2339|ERROR|An exception was thrown while deserializing the token.|__id=3c9b1ba6-01f1-43e7-b1d3-e995cf6b1007|__categories=Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgery|__source=GV.Platform.IdentityService|EventId=7|EventIdName=<NULL>|ExceptionMessage=The antiforgery token could not be decrypted.|ExceptionDetail=System.InvalidOperationException: The antiforgery token could not be decrypted. ---> System.Security.Cryptography.CryptographicException: The key {ad9b2e25-5a04-4f5e-ba51-72977b6bb561} was not found in the key ring.
at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus& status)
at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.DangerousUnprotect(Byte[] protectedData, Boolean ignoreRevocationErrors, Boolean& requiresMigration, Boolean& wasRevoked)
at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(Byte[] protectedData)
at Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgeryTokenSerializer.Deserialize(String serializedToken)
--- End of inner exception stack trace ---
at Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgeryTokenSerializer.Deserialize(String serializedToken)
at Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgery.GetCookieTokenDoesNotThrow(HttpContext httpContext)|__account=<NULL>|
防伪令牌无法解密。 ---> System.Security.Cryptography.CryptographicException:在密钥环中找不到密钥{ad9b2e25-5a04-4f5e-ba51-72977b6bb561}。
然后我查看redis,并期望在键“ DataProtection-Keys”中仅存储一个值,但是我看到了两个:
127.0.0.1:6379> lrange DataProtection-Keys 0 -1
1) "<key id=\"1157f02e-33c2-4a7f-a488-d7fa3ad5befe\" version=\"1\"><creationDate>2019-05-24T09:49:50.4691713Z</creationDate><activationDate>2019-05-24T09:49:50.4167109Z</activationDate><expirationDate>2019-08-22T09:49:50.4167109Z</expirationDate><descriptor deserializerType=\"Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection, Version=2.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60\"><descriptor><encryption algorithm=\"AES_256_CBC\" /><validation algorithm=\"HMACSHA256\" /><masterKey p4:requiresEncryption=\"true\" xmlns:p4=\"http://schemas.asp.net/2015/03/dataProtection\"><!-- Warning: the key below is in an unencrypted form. --><value>PLsIsUHvPL0uY6lmxenwTDAVUamS9eaqJQyeuRCIB9UqSSaDcAJCjUTSRVp1NKRqnGS0k1U3QPxj8ss7dKo7Zw==</value></masterKey></descriptor></descriptor></key>"
2) "<key id=\"ad9b2e25-5a04-4f5e-ba51-72977b6bb561\" version=\"1\"><creationDate>2019-05-24T09:49:50.5062286Z</creationDate><activationDate>2019-05-24T09:49:50.4478435Z</activationDate><expirationDate>2019-08-22T09:49:50.4478435Z</expirationDate><descriptor deserializerType=\"Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection, Version=2.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60\"><descriptor><encryption algorithm=\"AES_256_CBC\" /><validation algorithm=\"HMACSHA256\" /><masterKey p4:requiresEncryption=\"true\" xmlns:p4=\"http://schemas.asp.net/2015/03/dataProtection\"><!-- Warning: the key below is in an unencrypted form. --><value>CjJ/6HN8DuU5JxggW46JJWSF82DfINJeUg69fKGC3vyE8hpWuiIxcRdtq97A/NtOBaM43tMvwoZm+VlyLfIlRA==</value></masterKey></descriptor></descriptor></key>"
这说明了为什么我在应用程序中看到错误,因为该应用程序从Redis检索一个或另一个DataProtection-Key。为什么会这样?