如何在 Azure Function 的 HttpTrigger 中使用 Authorize 属性

我们的系统是基于角色的,并且大量使用了 Authorize 属性

在我们的应用服务中,我们使用下面的代码进行设置

    public void ConfigureAuth(IApplicationBuilder app)
    {
        if (Configuration.GetValue<bool>("UseLoadTest"))
        {
            app.UseMiddleware<ByPassAuthMiddleware>();
        }

        app.UseAuthentication();
    }

如何使用 Azure 函数 Http Trigger 执行此操作?

IFunctionsHostBuilder 上没有 UseAuthentication() 方法

public override void Configure(IFunctionsHostBuilder builder)
{
}

我正在使用 .NET Core 3.1

stack overflow How can I use Authorize attributes in HttpTrigger of Azure Function
原文答案

答案:

作者头像

AFAIK Functions 目前没有这样的属性。 This issue 跟踪支持 Filters for Functions 的工作,但这仍处于预览阶段。

基于上述预览功能,看起来这是一个库 - dark-loop/functions-authorize - 添加了对此的支持。

作者头像

为此,我开始使用中间件:从这篇文章中获得灵感: https://jinalkumarpatel.hashnode.dev/azure-functions-middleware-part-2-authentication-middleware

创建中间件:

public class BearerAuthenticationMiddleware
    : IFunctionsWorkerMiddleware
{
    private readonly ILogger<BearerAuthenticationMiddleware> logger;

    public BearerAuthenticationMiddleware(ILogger<BearerAuthenticationMiddleware> logger)
    {
        this.logger = logger;
    }
    public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next)
    {
        if (context.IsHttpTriggerFunction())
        {
            var headers = context.BindingContext.BindingData["Headers"]?.ToString();
            var httpHeaders = System.Text.Json.JsonSerializer.Deserialize<HttpHeaders>(headers);
            if (httpHeaders?.Authorization != null &&
                httpHeaders.Authorization.StartsWith("Bearer"))
            {
                //Validation logic for your token. Here If Bearer present I consider as Valid.
                if (httpHeaders.Authorization.Contains("admin"))
                {
                    // Originally based on token get user role.
                    // Put into context.Items so it will be used by next middleware.
                    context.Items.Add("UserRole", "Admin");
                }
                await next(context);
            }
            else
            {
                await context.CreateJsonResponse(System.Net.HttpStatusCode.Unauthorized, new { Message = "Token is not valid." });
            }
        }
        else
        {
            await next(context);
        }
    }
}

注册中间件:

public class Program
{
    public static void Main()
    {
        var host = new HostBuilder()
            .ConfigureFunctionsWorkerDefaults(configure=>
            {
                // other middleware also configure following way.
                // It will execute in same order it is configured over here.
                configure.UseMiddleware<SimpleMiddleware>();
            })
            .Build();

        host.Run();
    }
}