Monthly Archives: December 2020

Add certificate into WSL

I’ve recently been playing with WSL2, and one of the things that quickly bites you, is trying to move between your Linux distribution, and the main Windows system. In this particular instance, I had a certificate that I needed to apply to the WSL system.

The process turns out to be as follows

Copy cert to /usr/local/share/ca-certificates

For example, say your certificate was here:

c:\tmp\mycert.cer

You can copy this inside the WSL:

cp /mnt/c/tmp/mycert.cer /usr/local/share/ca-certificates

Once you’ve copied it here, run the update-ca-certificates command:

sudo update-ca-certificates

If it works, your certificate will be here:

/etc/ssl/certs

Notes

This was done on an Ubuntu distribution, but I’m not aware it would change based on that.

References

https://github.com/microsoft/WSL/issues/3161

Receiving Messages in Azure Service Bus

In this post I covered the basics of setting up a queue and sending a message to it. Here, I’m going to cover the options around receiving that message.

Essentially, there are two possibilities here: you can either set-up an event listener, or you can poll the queue directly, and receive the messages one at a time.

Option 1 – Events

The events option seems to be the one that Microsoft now prefer – essentially, you register a handler and then as the messages come in, you simply handle them inside an event. The code here looks something like this:

            var queueClient = new QueueClient(connectionString, "test-queue");

            var messageHandlerOptions = new MessageHandlerOptions(ExceptionHandler);
            queueClient.RegisterMessageHandler(handleMessage, messageHandlerOptions);

The event handlers:

        private static Task ExceptionHandler(ExceptionReceivedEventArgs arg)
        {
            Console.WriteLine("Something bad happened!");
            return Task.CompletedTask;
        }

        private static Task handleMessage(Message message, CancellationToken cancellation)
        {
            string messageBody = Encoding.UTF8.GetString(message.Body);
            Console.WriteLine("Message received: {0}", messageBody);

            return Task.CompletedTask;
        }

Option 2 – Polling

With this option, you simply ask for a message. You’ll need to use the approach for things like deferred messages (which I hope to cover in a future post):

            var messageReceiver = new MessageReceiver(connectionString, "test-queue", ReceiveMode.ReceiveAndDelete);            
            var message = await messageReceiver.ReceiveAsync();

            string messageBody = Encoding.UTF8.GetString(message.Body);            
            Console.WriteLine("Message received: {0}", messageBody);

Option 3 – Option 1, but cruelly force it into option 2

I thought I’d include this, although I would strongly advise against using it in most cases. If you wish, you can register an event, but force the event into a procedural call, so that you can await it finishing. You can do this by using the TaskCompletionSource. First, declare a TaskCompletionSource in your code (somewhere accessible):

private static TaskCompletionSource<bool> _taskCompletionSource;

Then, in handleMessage (see above), when you’ve received the message you want, set the result:

            if (message.CorrelationId == correlationId)
            {
                await client.CompleteAsync(message.SystemProperties.LockToken);

                _taskCompletionSource.SetResult(true);
            }

Finally, after you’ve registered the message handler, just await this task:

queueClient.RegisterMessageHandler(
                (message, cancellationToken) => handleMessage(correlationId, queueClient, message, cancellationToken), 
                messageHandlerOptions);

await _taskCompletionSource.Task;

References

Advanced Features with Azure Service Bus

Partial HTML

In Asp.Net Core server-side rendered HTML, you have the ability to use something called Partial Views. Essentially, these give you the ability to separate your View into, what some JS frameworks may call, components.

The way it works is incredibly simple. In your main page, you define some HTML, and reference the partial view – like so:

<div class="text-center">
    <div>
        <p>Merry Christmas - here's my partial view:</p>
    </div>
    <div>
        @await Html.PartialAsync("_MyPartial", Model.MyData)
    </div>
</div>

In your partial view, which is simply another cshtml file, you define the HTML fragment, along with the model; for example:

@model IEnumerable<MyDataType>

@foreach (var item in Model)
{
    <p>item.Data</p>
    <br />
}

References

https://docs.microsoft.com/en-us/aspnet/core/mvc/views/partial?view=aspnetcore-5.0

Using Managed Identity With Azure KeyVault

One of the things that’s always irked me about Azure KeyVault is that, whilst it may indeed be a super secure store of information, ultimately, you need some way to access it – which means that you’ve essentially moved the security problem, rather than solved it.

However, after speaking to a colleague at work, I’ve been playing with the concept of using a Managed Identity for authentication. This does go some way to alleviate my concerns for interactive security. To be clear, my concerns are less that the system is less secure, but that because you’ve simply moved the keys to the castle, that you’re just not getting sufficient benefit for the added complexity.

Anyway, this post covers using Managed Identity to authenticate KeyVault locally with Visual Studio.

Install the config package

The first step is to install the NuGet package. This post is based on .Net Core 3.1; however, I believe that it’s the same for 5.0.

Install-Package Microsoft.Extensions.Configuration.AzureKeyVault

Change the CreateHostBuilder

In Program.cs, edit CreateHostBuilder:

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                })
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    var configRoot = config.Build();

                    config.AddUserSecrets<Program>();

                    var azureServiceTokenProvider = new AzureServiceTokenProvider();
                    var keyVaultClient = new KeyVaultClient(
                        new KeyVaultClient.AuthenticationCallback(
                            azureServiceTokenProvider.KeyVaultTokenCallback));

                    config.AddAzureKeyVault(
                        $"https://{configRoot["KeyVaultName"]}.vault.azure.net/",
                        keyVaultClient,
                        new DefaultKeyVaultSecretManager());
                });

You’ll need to add the key vault name either in your appsettings.json, or you could keep it in a secrets file (although I don’t see why you would want to hide this). For example:

  "KeyVaultName": "my-keyvault"

Visual Studio Credentials

Finally, set your local credentials in Visual Studio:

Now you can simply read from the config, and it will pull the value from the KeyVault where it needs to:

myValue = Configuration.GetValue<string>("key-vault-secret");

References

https://docs.microsoft.com/en-us/aspnet/core/security/key-vault-configuration?view=aspnetcore-5.0

Sending a Service Bus Message Failed

While playing around with Azure Service Bus in .Net Core, I came across this error, and it had me stumped for a while:

Microsoft.Azure.ServiceBus.UnauthorizedException: ‘Put token failed. status-code: 401, status-description: InvalidSignature: The token has an invalid signature..’

Having had a look on the internet, everyone seemed to be of the opinion that such errors were caused by an invalid connection string. I checked my connection string a number of times and it seemed correct.

However, the sentiment is, in fact, the correct one. The actual cause of this was that I was using the connection string from a specific queue, while trying to connect to a topic. I’d copied the queue connection code, and for some reason, the connection string being different didn’t twig with me. Connection strings work in a hierarchical fashion. For example:

You can use the connection string from a namespace for all the queues and topics within that namespace; but you can only use the connection string for a queue only for that queue.

Add Configuration to a .Net Core Console Application

This is another of those blog posts that’s probably been done before, but I keep having to collate a few pieces of information.

What we’re going to do here is create a .Net Core Console application, that reads an appsettings.json file, and a local secrets file. I covered some of this in an earlier post around creating a test harness in a .Net Core application.

If you’re using the console, then start with a new console app:

dotnet new console

We’ll need a few NuGet packages, too:

Install-Package Microsoft.Extensions.Configuration
Install-Package Microsoft.Extensions.Configuration.Json
Install-Package Microsoft.Extensions.Configuration.UserSecrets

Wherever you’re reading the config, add the following snippet:

IConfiguration configuration = new ConfigurationBuilder()
               .AddJsonFile("appsettings.json", true, true)       
               .AddUserSecrets<Program>()
               .Build();

Since you’re bog standard console app doesn’t have an appsettings.json, you’ll need to add that; make sure you set the build action to “Copy if newer”:

And that’s it. To access the config, you can simply call:

Configuration.GetSection

If you wish to use GetValue then you’ll need the following package:

Install-Package microsoft.Extensions.Configuration.Binder

For example:

string connectionString = configuration.GetValue<string>("ServiceBusConnectionString");

References

https://www.twilio.com/blog/2018/05/user-secrets-in-a-net-core-console-app.html