You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Azure隔离式函数中获取HttpClient传递的NetworkCredential认证信息

解决Azure隔离式函数处理Basic Auth凭证的方案

核心思路

Azure隔离式函数不会自动解析NetworkCredential对应的Basic Auth凭证,需要手动从请求头中提取并校验,无需额外安装NuGet包,只需调整函数配置并编写自定义校验逻辑。


步骤1:调整函数授权级别

将函数的授权级别设为Anonymous,避免Azure函数自带的授权拦截请求,让请求能进入自定义校验流程:

  • 在函数代码的HttpTrigger属性中指定:
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")]
    
  • 或在function.json中配置(如果用文件驱动的函数):
    {
      "authLevel": "anonymous",
      // 其他配置...
    }
    

步骤2:解析并校验Basic Auth凭证

从HttpRequestData的Authorization请求头中提取用户名和密码,完成校验后再处理业务逻辑:

[Function("MyApiFunction")]
public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequestData req)
{
    // 1. 检查Authorization头是否存在
    if (!req.Headers.TryGetValues("Authorization", out var authHeaders) || !authHeaders.Any())
    {
        var unauthorizedResp = req.CreateResponse(HttpStatusCode.Unauthorized);
        unauthorizedResp.Headers.Add("WWW-Authenticate", "Basic realm=\"MyFunctionRealm\"");
        return unauthorizedResp;
    }

    var authHeader = authHeaders.First();
    // 2. 验证是否为Basic Auth scheme
    if (!authHeader.StartsWith("Basic ", StringComparison.OrdinalIgnoreCase))
    {
        var badResp = req.CreateResponse(HttpStatusCode.BadRequest);
        await badResp.WriteStringAsync("仅支持Basic认证方案");
        return badResp;
    }

    // 3. 解码凭证
    var base64Credentials = authHeader["Basic ".Length..].Trim();
    var credentialsBytes = Convert.FromBase64String(base64Credentials);
    var credentials = Encoding.UTF8.GetString(credentialsBytes).Split(':', 2);
    if (credentials.Length != 2)
    {
        var badResp = req.CreateResponse(HttpStatusCode.BadRequest);
        await badResp.WriteStringAsync("凭证格式无效");
        return badResp;
    }

    var username = credentials[0];
    var password = credentials[1];

    // 4. 校验凭证(从环境变量/Key Vault读取合法凭证,避免硬编码)
    var validUsername = Environment.GetEnvironmentVariable("VALID_USERNAME");
    var validPassword = Environment.GetEnvironmentVariable("VALID_PASSWORD");
    if (username != validUsername || password != validPassword)
    {
        var unauthorizedResp = req.CreateResponse(HttpStatusCode.Unauthorized);
        unauthorizedResp.Headers.Add("WWW-Authenticate", "Basic realm=\"MyFunctionRealm\"");
        return unauthorizedResp;
    }

    // 5. 校验通过,执行业务逻辑
    var response = req.CreateResponse(HttpStatusCode.OK);
    await response.WriteStringAsync("认证通过,业务处理完成");
    return response;
}

步骤3:安全存储合法凭证

将合法的用户名和密码存储在Azure函数的应用程序设置中(避免硬编码),如果需要更高安全性,可将凭证存入Azure Key Vault,通过函数的系统托管身份访问Key Vault,再通过应用程序设置引用Key Vault秘密。


可选:用中间件统一处理多函数认证

如果多个函数都需要Basic Auth校验,可编写自定义中间件实现统一处理:

public class BasicAuthMiddleware : IFunctionsWorkerMiddleware
{
    public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next)
    {
        var req = await context.GetHttpRequestDataAsync();
        if (req == null)
        {
            await next(context);
            return;
        }

        bool isAuthorized = false;
        try
        {
            if (req.Headers.TryGetValues("Authorization", out var authHeaders) && authHeaders.Any())
            {
                var authHeader = authHeaders.First();
                if (authHeader.StartsWith("Basic ", StringComparison.OrdinalIgnoreCase))
                {
                    var base64Credentials = authHeader["Basic ".Length..].Trim();
                    var credentialsBytes = Convert.FromBase64String(base64Credentials);
                    var credentials = Encoding.UTF8.GetString(credentialsBytes).Split(':', 2);
                    if (credentials.Length == 2)
                    {
                        var validUsername = Environment.GetEnvironmentVariable("VALID_USERNAME");
                        var validPassword = Environment.GetEnvironmentVariable("VALID_PASSWORD");
                        isAuthorized = credentials[0] == validUsername && credentials[1] == validPassword;
                    }
                }
            }
        }
        catch
        {
            isAuthorized = false;
        }

        if (!isAuthorized)
        {
            var unauthorizedResp = req.CreateResponse(HttpStatusCode.Unauthorized);
            unauthorizedResp.Headers.Add("WWW-Authenticate", "Basic realm=\"MyFunctionRealm\"");
            await context.GetInvocationResultAsync().SetResult(unauthorizedResp);
            return;
        }

        await next(context);
    }
}

在Program.cs中注册中间件:

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults(builder =>
    {
        builder.UseMiddleware<BasicAuthMiddleware>();
    })
    .Build();

host.Run();

内容的提问来源于stack exchange,提问作者Marcos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 17:10:32