Efficiently handling secrets as a Blazor .NET 6.0 developer

Posted by Azure Readiness starts here... on Tuesday, August 23, 2022

Hello readers,

As some of you might remember, I’ve been taking my first steps into the development/coding world with .NET Blazor since end of 2021. While I didn’t blog about my coding adventures as much as I hoped for, I actually made pretty good progress, developing an app that is actually running in production within our MTT Trainer team:). I might blog more details about all the different pieces at some point…

If you missed my initial introductory posts on Blazor, have a look here:

In this article, I’m taking it a bit further, and walking you through one of the biggest challenges as a developer, how to securely use secrets from the coding cycle (think of Visual Studio / VSCode work), all the way up to running the app in Azure.

The example scenario I use is a rather common one, where I’ll be connecting my Blazor front-end application to an API back-end, pulling up information to display. To be able to connect to the API-back-end, it requires a Personal Access Token / Secret. In the first part of the article, I’ll guide you through storing this component secretly in Visual Studio during the development phase, where the second part touches on using Azure Key Vault as an integration with the Azure App Service, hosting the application source code itself. Without exposing the secret.

Prerequisites

To make sure you are ready to go and follow-along, let me list up some prereqs:

Prereq No 1 - for the actual creation part, would be the .NET RunTime:

  • .NET 6.0 RunTime In order to run C# and .NET applications, one needs to have the necessary .NET RunTime installed on the development workstation. I would recommend going for .NET 6.0 RunTime, assuming you have access to Visual Studio 2022.

Prereq No 2 - Azure Subscription:

  • As the goal is to run our sample app in Azure, which could be Azure App Services or Azure Static Web Apps, you need access to an Azure Subscription. If you don’t have one, you can sign up for a 1 year FREE subscription by following these instructions.

Prereq No 3 - Marvel API access:

  • While you could reuse the concepts outlined in this article for any secret-protected API access, I found an interesting scenario in the https://developer.marvel.com API library. It also helps coming up with the perfect excuse when I’m buying Marvel stuff, I need it for my work (call out to my Manager, if you are reading this, please provide me the correct costcenter code to expense these - I would say educational purposes). All you need to do is browse to https://developer.marvel.com and create a developer account. From there, you get the necessary API Key you need in the app.

Prereq No 4 - Sample Source Code:

  • I posted a final version of the source code used throughout this article in my GitHub repo; feel free to use it as a starting point for your own testing and learning.

Storing Secrets in .NET using Secrets Manager

One way to store secrets in a .NET language application, is using “Secret Manager”, available from within Visual Studio by selecting your project / right-click / Manage User Secrets

Manage User Secrets

which allows you to store your secret in a JSON-file format, similar to what the traditional appsettings.JSON or web.config used to hold. But outside of the appsettings.json or web.config application files.

secrets.json

While this might solve the initial problem of not storing your application secrets as part of the source code, it is only partly solving the core problem. First, the data itself is not encrypted, as it’s just a plain text file. Second, while it is indeed not stored as part of your application code, meaning it won’t get synced to your Version Control repositories, it is stored in your local User Profile directory (%APPDATA%\Microsoft\UserSecrets<user_secrets_id>\secrets.json) on your local development machine. While it will allow you to run the code on your local machine, it won’t work once it gets published. Or in a team-collaboration (DevOps :)) scenario, it would mean that each Dev-member, must store a copy of the exact same secrets.json on their local machine. Which is bypassing the overall control of handling secrets.

Note: While I’m using Visual Studio 2022 in my example, know the secret handling is a feature of .NET Secret Manager, irrelevant from the Development Environment used. Using it from within dotnet commandline is done from dotnet user-secrets

From within your application source code folder, initiate the following command:

dotnet user-secrets init

user-secrets-init.json

which creates the unique folder within the User Profile directory for this project.

Next, create the actual secret string (key/value pair) using the following command:

dotnet user-secrets set “MarvelOptions:ApiKey” “579a41c9eccaf70a”

user-secrets-set.json

retrieving this, as well as other such secrets you have stored on your local machine, is done using the command:

dotnet user-secrets list

Cool, that works. Now, let’s jump over to our Blazor application and define the necessary references to the user-secrets from within the code.

First, add the necessary Nuget Package Microsoft.Extensions.Configuration.UserSecrets to your application:

nuget-package

Next, update the program.cs with the minimal API code snippet required, to add the UserSecrets functionality to the Blazor App:

builder.Configuration.AddUserSecrets(Assembly.GetExecutingAssembly(), true);

minimal-API

deploy a specific Framework version

With different .NET Framework versions available on the same developer station, it might be necessary to specify a specific version of .NET to use; this is possible by adding the -f or –framework parameter to the dotnet new blazorwasm syntax, followed by the version identifier net5.0, net6.0 or netcoreapp3.1

include ASP.NET Core host

We used this parameter in the previous steps, but I didn’t really explain what it did. If you want to build a “client” Web Assembly version, which runs with an ASP.NET Server-backend, you need to specify the -ho or –hosted parameter

Let’s run a similar command as before to create a Blazor Web Assembly app, without specifying the –hosted parameter, to see the difference:

dotnet new blazorwasm 

Once created, check the file structure of this new application folder:

BlazorWasmNoHosted

As you can see, there is no separation for the Client and Server code files, but we only have the Pages and Shared folder.

Integrate Azure AD authentication

It might be required to integrate authentication into your Blazor Web Assembly app, and why not considering Azure Active Directory for this, right? While there is a bit more required than what the commandline parameters give you, it’s a great starting point, deploying a new Blazor app which is pre-authentication ready. To do this, specify the -au or –auth parameter

dotnet new blazorwasm -au individual

BlazorWasmAuth

The creation process is about the same as before; so let’s trigger another dotnet run action and connect to the app from the browser:

BlazorWasmAuth

Nice! There is a prompt here, informing us to customize the Program.cs file, and provide the necessary Azure AD Authentication for our application identity

Let’s have a look at the Program.cs file, which also contains a little snippet and pointer where to add the necessary Azure AD Authentication settings and where to find additional info in the docs.

BlazorWasmAuth

Running Blazor App as Progressive Web App

I won’t drill down on all the details on what a Progressive Web App is about, but in short, it allows you to turn your Web Assembly browser-based app into a “desktop”-mode application, or even using it “offline” (depending on app specifics). This is done by defining the -p or –pwa parameter.

Let’s try it out:

dotnet new blazorwasm -p 

dotnet run

BlazorWasmAuth

and testing it again from the browser by connecting to https://localhost:

From the browser properties, navigate to Apps and select Install this app

BlazorWasmAuth

and confirming the popup prompt Install once more.

BlazorWasmAuth

Once installed, you can set some additional settings by clicking the Allow button.

From here, your app will run in a separate docked window, just like any other Windows Application. You could also add a shortcut to the desktop, taskbar or start Menu.

BlazorWasmAuth

Summary

In this post, I introduced you to creating your First Blazor Web Assembly App, using the dotnet commandline syntax. Starting from the base Blazorwasm template creation, I also covered several interesting creation parameters that could come in handy when creating Blazor Web Assembly apps, directly from the commandline.

In a next Blazor-related post, I’ll walk you through some fundamental layout customization options, changing the look and feel of the navigation bar, the top bar and the actual web app pages themselves by introducing HTML and CSS primarily.

For now, take care of yourself and your family, see you again soon with more Blazor-news.

BuyMeACoffee

Cheers, Peter