How to fix authorization errors after upgrading an Azure .NET 4.6 function to .NET 6.0

2 minute read

Okay, one more Azure functions post. After upgrading my .NET 2.0 standard function for AMS HoloATC I discovered the back end function for my HoloLens app Walk the World was on an even older tech stack: .NET4.6. I actually had to upgrade the source project to 4.8 to even be able to open the project at all.

The actual upgrade was actually was fairly easy. This was the function header:

public static class WhateverFunction
{
    [FunctionName("WhateverFunction")]
    public static async Task<HttpResponseMessage> Run(
       [HttpTrigger(AuthorizationLevel.Function, "get", 
          Route = null)]HttpRequestMessage req,
        TraceWriter log, ExecutionContext context, 
        [Table("WhateverTable", "AzureWebJobsStorage")]
        CloudTable whateverTable)

And I only had apply what I learned in my previous post to change that to this:

public static class WhateverFunction
{
    [FunctionName("WhateverFunction")]
    public static async Task<IActionResult> Run(
       [HttpTrigger(AuthorizationLevel.Function, "get",
          Route = null)]HttpRequestMessage req,
        ILogger log, ExecutionContext context, 
        [Table("WhateverTable", Connection = "AzureWebJobsStorage")]
        TableClient whateverTable)

And I only had to change the end from

return req.CreateResponse(HttpStatusCode.OK, result);

to

return new OkObjectResult(result);

And I was basically done. I tested the function locally - worked fine. Then I deployed it, started up Walk the World - and nothing happened. I then ran some test code calling the deployed function running on Azure - and I got a 401 (Unauthorized) error. Oops. And there are quite some installations of Walk the World out there being used regularly. Fortunately I could quickly revert to the old function, and that still worked.

It took me quite some time to figure out what went wrong. Something peculiar happens in the function configuration in Azure. If you work with Azure functions, I assume you are familiar with the following interface:

And if you click “Get Function URL” you get this piece of UI

To be able to call the function, you have to supply the “code=[some_long_value]” parameter as a kind of security code, to prevent everyone else from calling your function willy-nilly.

Apparently - when I deployed my function as .NET 6.0 function, all available values for codes changed and the old one was no longer valid.

The solution is very simple: you can add the old code as a custom function key. This is pretty easy. First, you click on “Function keys”:

Then, you then click on “New function key”:

And then you add the old code key back by adding a key with name “code”, and for value the code that used to be valid before the upgrade:

If you go back to the “Get Function URL” panel, you will now see five entries in stead of four:

And you can breathe a sigh of relief, like me, for now all your existing clients can call this function using the existing code they have, and they won’t notice a thing of the completely upgraded back end.

I have no idea if behavior this intentional or a bug. It feels like the latter, as this problem did not occur when I upgraded my .NET standard 2.0 function to .NET 6.0. Maybe this was caused by the jump in technology stack being a lot bigger than the previous upgrade, and maybe no-one ever tested this particular aspect of this particular transition. There might be a lesson in that: never put off upgrading for too long, or it might hurt you in unexpected ways.However, should it hit you too, this is how you can mitigate it.

No code this time, as this is about configuring the function and not about writing code.