Open sherlock1982 opened 4 months ago
I agree with you and have some additional thoughts on this matter.
This component was created to handle JWT in high availability scenarios. One of the reasons for not encrypting data before persisting it in other stores is that we cannot guarantee developers will configure DataProtection properly. In high availability scenarios, where multiple instances may exist, some of them might be unable to decrypt the content, leading to exceptions in the component.
However, the DefaultStore (added in more recent versions) uses DataProtection.Repositories
, which minimizes this risk. This ensures that in high availability scenarios, DataProtection must be configured, thus maintaining data integrity across instances.
Although I have explained the reasons, I no longer hold a strong opinion on this matter. What are your thoughts on this?
Well first of all thanks for the lib! I was playing with it a lot and found it very nice.
In my final approach I decided to change implementation of JwtService and KeyMaterial. I added extra column to KeyMaterial called PublicKey and store there public key unencrypted. While parameters go encrypted. Revoke simply cleans up Parameters column.
This solved the following things for me:
kid
DataProtector
. For example key is lost it's ok - I just generate a new key but still can have old keys for verificationI also noticed that I can't really make a key invalid so a new key will be generated if I can't Unprotect
the key. This is why I also adjusted it and moved data protection to JwtService layer.
And yes I added a semaphore for GetCurrentCredentials
function because it will generate multiple keys at the same time.
And one more thing - you remember the issue with casing in the key. The problem here is the lib doesn't behave well if for some reason such issue happens. Becuase it simply throws the exception from GetSecurityKey
.
You can of course catch it and generate a new key but in this case GetLastKeys() will throw an exception in the token handler.
So another reason for me to change implementation here.
We can close this discussion - just wanted to share my findings on this :-)
Recently switch from
DataProtectionStore
toDatabaseJsonWebKeyStore
and noticed that no DataProtection is present. It looks to me that mentioned stores are generally less secure than default one.Note that for example
MsalDistributedTokenCacheAdapterOptions
has an option to Encrypt (default false):I added protection to
DatabaseJsonWebKeyStore
like this:With:
But I think would be nice to have it in the stores out of the box.
The other option will be to add protection at a higher level for
KeyMaterial
but that won't work good for some scenarios. For example I'd like to store a public key separately so I can access it from other services but keep private key only to the specific service.