From 216bb56630b50719a9337d7c34dd4392d39f62b1 Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Wed, 30 Jul 2025 12:36:44 -0400 Subject: [PATCH 1/4] Default to security warning INCLUDE --- .../progressive-web-app/push-notifications.md | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/aspnetcore/blazor/progressive-web-app/push-notifications.md b/aspnetcore/blazor/progressive-web-app/push-notifications.md index 53fd3672a3d8..a3fc79ec81fd 100644 --- a/aspnetcore/blazor/progressive-web-app/push-notifications.md +++ b/aspnetcore/blazor/progressive-web-app/push-notifications.md @@ -5,7 +5,7 @@ description: Learn how to issue push notifications in Blazor Progressive Web App monikerRange: '>= aspnetcore-3.1' ms.author: wpickett ms.custom: mvc -ms.date: 07/07/2025 +ms.date: 07/30/2025 uid: blazor/progressive-web-app/push-notifications --- # Push notifications for ASP.NET Core Blazor Progressive Web Applications (PWAs) @@ -30,17 +30,6 @@ The example in this article uses push notifications to provide order status upda Generate the cryptographic public and private keys for securing push notifications either locally, for example with PowerShell or IIS, or using an online tool. -> [!CAUTION] -> This article's use of a unencrypted, insecure private key in the app's code ***is for demonstration purposes and local testing only.*** We recommend using a secure approach for supplying a private key to an ASP.NET Core app at all stages of development. When working locally in the Development environment, a private key can be provided to the app using the [Secret Manager](xref:security/app-secrets#secret-manager) tool. In Development, Staging, and Production environments, [Azure Key Vault](/azure/key-vault/) with [Azure Managed Identities](/entra/identity/managed-identities-azure-resources/overview) can be used, noting in passing that to obtain a certificate's private key from a key vault that the certificate must have an exportable private key. - - - Placeholders used in this article's example code: * `{PUBLIC KEY}`: The public key. @@ -48,6 +37,8 @@ Placeholders used in this article's example code: For this article's C# examples, update the `someone@example.com` email address to match the address used when creating the custom key pair. +[!INCLUDE[](~/blazor/security/includes/secure-authentication-flows.md)] + ## Create a subscription Before sending push notifications to a user, the app must ask the user for permission. If they grant permission to receive notifications, their browser generates a *subscription*, which includes a set of tokens the app can use to route notifications to the user. @@ -257,8 +248,7 @@ Sending a notification involves performing some complex cryptographic operations The `SendNotificationAsync` method dispatches order notifications using the captured subscription. The following code makes uses of `WebPush` APIs for dispatching the notification. The payload of the notification is JSON serialized and includes a message and a URL. The message is displayed to the user, and the URL allows the user to reach the pizza order associated with the notification. Additional parameters can be serialized as required for other notification scenarios. -> [!CAUTION] -> This article's use of a unencrypted, insecure private key in the app's code ***is for demonstration purposes and local testing only.*** We recommend using a secure approach for supplying a private key to an ASP.NET Core app at all stages of development. When working locally in the Development environment, a private key can be provided to the app using the [Secret Manager](xref:security/app-secrets#secret-manager) tool. In Development, Staging, and Production environments, [Azure Key Vault](/azure/key-vault/) with [Azure Managed Identities](/entra/identity/managed-identities-azure-resources/overview) can be used, noting in passing that to obtain a certificate's private key from a key vault that the certificate must have an exportable private key. +[!INCLUDE[](~/blazor/security/includes/secure-authentication-flows.md)] ```csharp private static async Task SendNotificationAsync(Order order, From b42af11467b7be58658c56cdaf3b2d32d65a0b79 Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Wed, 30 Jul 2025 12:49:52 -0400 Subject: [PATCH 2/4] Update aspnetcore/blazor/progressive-web-app/push-notifications.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../blazor/progressive-web-app/push-notifications.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/aspnetcore/blazor/progressive-web-app/push-notifications.md b/aspnetcore/blazor/progressive-web-app/push-notifications.md index a3fc79ec81fd..6195ed9027fd 100644 --- a/aspnetcore/blazor/progressive-web-app/push-notifications.md +++ b/aspnetcore/blazor/progressive-web-app/push-notifications.md @@ -37,7 +37,14 @@ Placeholders used in this article's example code: For this article's C# examples, update the `someone@example.com` email address to match the address used when creating the custom key pair. -[!INCLUDE[](~/blazor/security/includes/secure-authentication-flows.md)] +> [!IMPORTANT] +> When implementing push notifications, ensure that cryptographic keys are managed securely: +> +> * **Key generation**: Use a trusted library or tool to generate the public and private keys. Avoid using weak or outdated algorithms. +> * **Key storage**: Store private keys securely on the server, using a secure storage mechanism such as a hardware security module (HSM) or encrypted storage. Never expose private keys to the client. +> * **Key usage**: Use the private key only for signing push notification payloads. Ensure that the public key is distributed securely to clients. +> +> For more information on cryptographic best practices, see [Cryptographic Services](/dotnet/standard/security/cryptographic-services). ## Create a subscription From 7fcec4536fdfa557b5d3bd162f45d9b70caddd1e Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Wed, 30 Jul 2025 13:46:05 -0400 Subject: [PATCH 3/4] Updates --- .../progressive-web-app/push-notifications.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/aspnetcore/blazor/progressive-web-app/push-notifications.md b/aspnetcore/blazor/progressive-web-app/push-notifications.md index 6195ed9027fd..8ff316fb4f79 100644 --- a/aspnetcore/blazor/progressive-web-app/push-notifications.md +++ b/aspnetcore/blazor/progressive-web-app/push-notifications.md @@ -1,5 +1,6 @@ --- title: Push notifications for ASP.NET Core Blazor Progressive Web Applications (PWAs) +ai-usage: ai-assisted author: guardrex description: Learn how to issue push notifications in Blazor Progressive Web Applications (PWAs). monikerRange: '>= aspnetcore-3.1' @@ -37,14 +38,13 @@ Placeholders used in this article's example code: For this article's C# examples, update the `someone@example.com` email address to match the address used when creating the custom key pair. -> [!IMPORTANT] -> When implementing push notifications, ensure that cryptographic keys are managed securely: -> -> * **Key generation**: Use a trusted library or tool to generate the public and private keys. Avoid using weak or outdated algorithms. -> * **Key storage**: Store private keys securely on the server, using a secure storage mechanism such as a hardware security module (HSM) or encrypted storage. Never expose private keys to the client. -> * **Key usage**: Use the private key only for signing push notification payloads. Ensure that the public key is distributed securely to clients. -> -> For more information on cryptographic best practices, see [Cryptographic Services](/dotnet/standard/security/cryptographic-services). +When implementing push notifications, ensure that cryptographic keys are managed securely: + +* **Key generation**: Use a trusted library or tool to generate the public and private keys. Avoid using weak or outdated algorithms. +* **Key storage**: Store private keys securely on the server, using a secure storage mechanism such as a hardware security module (HSM) or encrypted storage. Never expose private keys to the client. +* **Key usage**: Use the private key only for signing push notification payloads. Ensure that the public key is distributed securely to clients. + +For more information on cryptographic best practices, see [Cryptographic Services](/dotnet/standard/security/cryptographic-services). ## Create a subscription From 9219cd661648e4343f0ed1c5eb1a6885f104a851 Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Wed, 30 Jul 2025 14:13:22 -0400 Subject: [PATCH 4/4] Updates --- aspnetcore/blazor/progressive-web-app/push-notifications.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/aspnetcore/blazor/progressive-web-app/push-notifications.md b/aspnetcore/blazor/progressive-web-app/push-notifications.md index 8ff316fb4f79..a767e8f0f97f 100644 --- a/aspnetcore/blazor/progressive-web-app/push-notifications.md +++ b/aspnetcore/blazor/progressive-web-app/push-notifications.md @@ -255,7 +255,8 @@ Sending a notification involves performing some complex cryptographic operations The `SendNotificationAsync` method dispatches order notifications using the captured subscription. The following code makes uses of `WebPush` APIs for dispatching the notification. The payload of the notification is JSON serialized and includes a message and a URL. The message is displayed to the user, and the URL allows the user to reach the pizza order associated with the notification. Additional parameters can be serialized as required for other notification scenarios. -[!INCLUDE[](~/blazor/security/includes/secure-authentication-flows.md)] +> [!CAUTION] +> In the following example, we recommend using a secure approach for supplying the private key. When working locally in the Development environment, a private key can be provided to the app using the [Secret Manager](xref:security/app-secrets#secret-manager) tool. In Development, Staging, and Production environments, [Azure Key Vault](/azure/key-vault/) with [Azure Managed Identities](/entra/identity/managed-identities-azure-resources/overview) can be used, noting in passing that to obtain a certificate's private key from a key vault that the certificate must have an exportable private key. ```csharp private static async Task SendNotificationAsync(Order order,