2

We have code that uses default ASP.NET Identity logic for issuing reset tokens and this was working fine through our test environments until we hit a load-balanced multi-instance environment. Here we found that the reset token issued was tied to the instance it was generated on.

Our assumption is that this is related to the data protection wiring. There's an SO post here suggesting as much, and recommending we roll our own data protection provider. This is something I'm very keen to avoid.

I'd (presumably mistakenly) assumed that data protection used machine keys by default to ensure encryption is applied consistently across multiple instances (didn't I even read this somewhere once?). Anyway we do have machine keys shared across these instances.

I'm now (not) surprised to find the documentation around this is pretty vague given it must be an extremely common challenge. There is some suggestion that using services.AddDataProtection().SetApplicationName("unique-value"); would solve this but this doesn't appear to help.

It'd be great if anyone could explain this behaviour (why doesn't the default support a load-balanced environment) and suggest a solution that doesn't involve rolling our own encrpytion logic...

By the way, this is an old .NET 4.7.2 app.

Tom Troughton
  • 3,941
  • 2
  • 37
  • 77

1 Answers1

0

Well it seems that the only way to solve this is to manage your own data protection keys. Our solution was to use an Azure blob to store the key, and an Azure key vault key to encrypt it. The wiring looks like this:

services.AddDataProtection()
    .PersistKeysToAzureBlobStorage(dataProtectionSettings.KeyBlobIdentifier, tokenCredential)
    .ProtectKeysWithAzureKeyVault(dataProtectionSettings.EncryptionKeyIdentifier, tokenCredential)
    .SetApplicationName("SomeAppName");
  • These extensions are from the following packages (note there are two versions of both packages and these are the latest, maintained ones):
    • Azure.Extensions.AspNetCore.DataProtection.Blobs
    • Azure.Extensions.AspNetCore.DataProtection.Keys
  • dataProtectionSettings.KeyBlobIdentifier is a full path to a blob eg. https://mystorageaccount.blob.core.windows.net/data-protection/key-blob
  • dataProtectionSettings.EncryptionKeyIdentifier is a fully qualified identifier of a key e.g. https://myvault.vault.azure.net/keys/DataProtection/
  • Obviously tokenCredential is the credentials for some identity with access to both these resources (needs Key Vault Crypto User on the key vault and we used Storage Blob Data Owner at container level for the blob).
Tom Troughton
  • 3,941
  • 2
  • 37
  • 77