@@ -611,7 +611,6 @@ Example:
611611 "ResponseType" : " code" ,
612612 "TenantId" : " aaaabbbb-0000-cccc-1111-dddd2222eeee"
613613},
614- ...
615614"DownstreamApi" : {
616615 "BaseUrl" : " https://localhost:7277" ,
617616 "Scopes" : [ " api://11112222-bbbb-3333-cccc-4444dddd5555/Weather.Get" ]
@@ -763,15 +762,89 @@ The following example shows how to use [Azure Blob Storage and Azure Key Vault](
763762
764763[! INCLUDE [](~ / includes / package - reference .md )]
765764
766- Configure Azure Blob Storage to maintain the encrypted keys and protect them with Azure Key Vault . In the following example , the `{BLOB URI WITH SAS TOKEN }` placeholder is the full URI where the key file should be stored with the SAS token as a query string parameter , and the `{KEY IDENTIFIER }` placeholder is the key vault key identifier used for key encryption :
765+ Configure Azure Blob Storage to maintain the encrypted keys and protect them with Azure Key Vault . The following code is typically implemented at the same time that a [production distributed token cache provider ](xref :performance / caching / distributed ) is implemented . Other options , both within Azure and outside of Azure , are available for managing Data Protection keys across multiple app instances , but the sample app demonstrates how to use Azure services .
766+
767+ The < xref :Microsoft .Extensions .Azure .AzureEventSourceLogForwarder > service in the following example requires the [`Microsoft .Extensions .Azure ` NuGet package ](https :// www.nuget.org/packages/Microsoft.Extensions.Azure) and a `using` statement at the top of the `Program` file for the <xref:Microsoft.Extensions.Azure?displayProperty=fullName> namespace.
768+
769+ [! INCLUDE [](~ / includes / package - reference .md )]
767770
768771```csharp
772+ builder .Services .TryAddSingleton <AzureEventSourceLogForwarder >();
773+
769774builder .Services .AddDataProtection ()
770775 .PersistKeysToAzureBlobStorage (new Uri (" {BLOB URI WITH SAS TOKEN}" ))
771776 .ProtectKeysWithAzureKeyVault (new Uri (" {KEY IDENTIFIER}" ), new DefaultAzureCredential ());
772777```
773778
774- For more information on using a shared Data Protection key ring , see < xref :host - and - deploy / web - farm #data - protection > and < xref :security / data - protection / configuration / overview > .
779+ * `{BLOB URI WITH SAS TOKEN }`: The full URI where the key file should be stored with the SAS (shared access signature ) token as a query string parameter . The URI is generated by Azure Storage when you request a SAS after creating a container. The container name in the following example is `data-protection`, and the storage account name is `contoso`. The key file is named `keys.xml`. When you create the SAS, use the following permissions: `Read`, `Write`, `Delete`, `List`, and `Create`.
780+
781+ Example : ::: no - loc text = " https://contoso.blob.core.windows.net/data-protection/keys.xml?sp={PERMISSIONS}&st={START DATETIME}&se={EXPIRATION DATETIME}&spr=https&sv={STORAGE VERSION DATE}&sr=c&sig={TOKEN}" :::
782+
783+ > [! TIP ]
784+ > If you run the app once without enabling the code that calls < xref : Microsoft .AspNetCore .DataProtection .AzureDataProtectionBuilderExtensions .ProtectKeysWithAzureKeyVault % 2A > , the Data Protection key file (`keys .xml `) is automatically generated in Azure Blob Storage for you . After you 've verified the file 's presence in Azure Blob Storage with the Storage Browser in the Entra or Azure portal , enable the call to < xref :Microsoft .AspNetCore .DataProtection .AzureDataProtectionBuilderExtensions .ProtectKeysWithAzureKeyVault % 2A > .
785+
786+ * `{KEY IDENTIFIER }`: Azure Key Vault key identifier used for key encryption . The key vault name is `contoso ` in the following example , and an access policy allows the application to access the key vault with `Get `, `Wrap Key `, and `Unwrap Key ` permissions . The example key name is `data -protection `. The version of the key for the `{KEY VERSION }` placeholder is obtained from the key in the Entra or Azure Portal after it 's created .
787+
788+ Example : ::: no - loc text = " https://contoso.vault.azure.net/keys/data-protection/{KEY VERSION}" :::
789+
790+ To configure the app with app settings , add the following to the app settings file :
791+
792+ ```json
793+ " DistributedTokenCache" : {
794+ " DisableL1Cache" : false ,
795+ " L1CacheSizeLimit" : 524288000 ,
796+ " Encrypt" : true ,
797+ " SlidingExpirationInHours" : 1
798+ },
799+ " DataProtection" : {
800+ " BlobUriWithSasToken" : " https://contoso.blob.core.windows.net/data-protection/keys.xml?sp={PERMISSIONS}&st={START DATETIME}&se={EXPIRATION DATETIME}&spr=https&sv={STORAGE VERSION DATE}&sr=c&sig={TOKEN}" ,
801+ " KeyIdentifier" : " https://contoso.vault.azure.net/keys/data-protection/{KEY VERSION}"
802+ }
803+ ```
804+
805+ Make the following changes in the `Program ` file :
806+
807+ ```diff
808+ builder .Services .Configure <MsalDistributedTokenCacheAdapterOptions >(
809+ options =>
810+ {
811+ + var config = builder .Configuration .GetSection (" DistributedTokenCache" );
812+
813+ - options .DisableL1Cache = false ;
814+ + options .DisableL1Cache = config .GetValue <bool >(" DisableL1Cache" );
815+
816+ - options .L1CacheOptions .SizeLimit = 500 * 1024 * 1024 ;
817+ + options .L1CacheOptions .SizeLimit = config .GetValue <long >(" L1CacheSizeLimit" );
818+
819+ - options .Encrypt = true ;
820+ + options .Encrypt = config .GetValue <bool >(" Encrypt" );
821+
822+ - options .SlidingExpiration = TimeSpan .FromHours (1 );
823+ + options .SlidingExpiration =
824+ + TimeSpan .FromHours (config .GetValue <int >(" SlidingExpirationInHours" ));
825+ });
826+
827+ - builder .Services .AddDataProtection ()
828+ - .PersistKeysToAzureBlobStorage (new Uri (" {BLOB URI WITH SAS TOKEN}" ))
829+ - .ProtectKeysWithAzureKeyVault (new Uri (" {KEY IDENTIFIER}" ), new DefaultAzureCredential ());
830+
831+ + var config = builder .Configuration .GetSection (" DataProtection" );
832+
833+ + builder .Services .AddDataProtection ()
834+ + .PersistKeysToAzureBlobStorage (
835+ + new Uri (config .GetValue <string >(" BlobUriWithSasToken" ) ??
836+ + throw new Exception (" Missing Blob URI" )))
837+ + .ProtectKeysWithAzureKeyVault (
838+ + new Uri (config .GetValue <string >(" KeyIdentifier" ) ??
839+ + throw new Exception (" Missing Key Identifier" )),
840+ + new DefaultAzureCredential ());
841+ ```
842+
843+ For more information on using a shared Data Protection key ring and key storage providers , see the following resources :
844+
845+ * < xref :host - and - deploy / web - farm #data - protection >
846+ * < xref :security / data - protection / configuration / overview >
847+ * < xref :security / data - protection / implementation / key - storage - providers >
775848
776849## Redirect to the home page on logout
777850
0 commit comments