Skip to content

DataProtection: IDataProtector.UnProtect can force refresh the key ring if it fails to unprotect #3975

Closed
@kevinlo

Description

@kevinlo

I have an App1 that will create the cookie and have 20 instances of App2 and 20 instances of App3 that will read the cookie. The data protection key is stored in Couchbase.

When these applications are first deployed without the key in the Couchbase, all 20 instances of App2 and 20 instances of App3 are started. They all CreateNewKey. Because the Couchbase indexes are updated cyclicly, every 20ms, the GetAllKeys call may not see the key added by the CreateNewKey immediately. I finally see 62 keys created.

I think because of that 20ms time lag, the GetAllKeys call in some instances of App2 and/or App3 get more keys than others. The App1 is started last and it will get all the keys and so its default key is newer than some instances of App2 and App3. Therefore, the cookie protected by the newest default key in the App1 cannot be unprotected by some instances of App2 and App3.

Currently, KeyRingBasedDataProtector.UnprotectCore calls the _keyRingProvider.GetCurrentKeyRing to get the CacheableKeyRing. The CacheableKeyRing.IsValid just checks if the keys in the key ring is not revoked and expired. In the above case, the keys are all valid and the CacheableKeyRing will be used, and it does not have the latest key from the DB.

Should the IKeyRingProvider.GetCurrentKeyRing have a forceRefresh parameter default to false so that if the KeyRingBasedDataProtector.UnprotectCore fails, it will call GetCurrentKeyRing(true) to force it to refresh the key rings and try again OR provide another way to tell the IKeyRingProvider to discard the cache? KeyRingBasedDataProtector.UnprotectCore can try to unprotect again with the refreshed key ring. At least it can force it to discard the cache and get the refresh one so next unprotect call would be good.

The current workaround I think of is making the App1 startup first so it will generated the key. When the App2 and App3 are started, they can read that key and App2 and App3 always have the same or newer key as App1.

I think that application dependency is a possible solution but it would be nice if the ASP.NET Core Data Protection can handle this situation magically so I don't need to care about the application dependency.

Metadata

Metadata

Assignees

Labels

DoneThis issue has been fixedarea-dataprotectionIncludes: DataProtection

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions