Policy Authorization in Azure Functions .net 6

Viewed 1005

I'm attempting to migrate from a REST API that I developed in a Web App to Azure Functions. In the Web App I use the "Authorize" attribute decoration with a Policy like:

[Authorize(Policy = Permissions.Announcements.Edit)]
[HttpPost]
public IActionResult MyFunction([FromBody] MyDTO dto) 
{ 
/* my code */
}

The code uses JWT tokens for Authentication and ASP.NET Core Identity. My question is there any way to accomplish Policies using Azure Functions v4 in .net 6? Maybe a custom middleware?

2 Answers

Firstly, Azure Functions don’t have any concept of middlewares, except for filters which are at the time of writing in preview.

Azure Functions however support regular dependency injection, so you can add your custom services. One of the services for example is AddJwtBearer brought to you by Microsoft.AspNetCore.Authentication.JwtBearer package.

Instead of using playn JwtBearer middleware, we are going to use Microsoft.Identity.Web (MIW). The cool thing about MIW is, that it simplifies most of the common actions and operations you need to do. It also makes usage of Microsoft Graph or calling any other API super simple!

For more references, refer about custom middleware in azure functions and this.

I would recommend you to use this package DarkLoop.Azure.Functions.Authorize

In your startup class initialize authentication:

builder.Services
    .AddFunctionsAuthentication();
    .AddJwtBearer(options => 
     {
        //your JWT configuration here just like in ASPNET Core
     });

builder.Services.AddFunctionsAuthorization();

Then all you need to do is decorate your functions or functions class with FunctionAuthorizeAttribute and you can have the same granular control as in WebAPI:

    [FunctionAuthorize(Policy = Permissions.Announcements.Edit)]
    [FunctionName("MyFunction")]
    public async Task<IActionResult> MyFunction(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "myfunction")] HttpRequest req, ILogger log)
    {
        var user = req.HttpContext.User;
        /* my code */
    }

More information on this blog post.

Related