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

.NET6 Isolated Azure Functions自定义认证中间件返回204而非401求助

问题根源与解决方案

你的代码核心问题是:仅创建了401响应对象,但没有将其关联到FunctionContext的执行结果中。在Isolated模式的Azure Functions中,中间件需要明确将自定义响应赋值给FunctionContext的InvocationResult,否则函数运行时会默认返回204 No Content(因为没有检测到有效的响应输出)。

修复步骤

在所有需要返回未授权响应的分支中,添加以下代码,将创建好的response设置为当前上下文的执行结果:

context.GetInvocationResult().Value = response;

修改后的完整代码

public class TokenValidationMiddleware : IFunctionsWorkerMiddleware
{
    private readonly ILogger _logger;
    private readonly List<string> _userIds = new() { "user1" };

    public TokenValidationMiddleware(ILoggerFactory loggerFactory)
    {
        _logger = loggerFactory.CreateLogger<TokenValidationMiddleware>();
    }

    public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next)
    {
        var request = await context.GetHttpRequestDataAsync();
        if (request == null)
        {
            // 处理非HTTP请求的情况
            return;
        }

        var response = request.CreateResponse(HttpStatusCode.Unauthorized);
        response.Headers.Add("Content-Type", "text/plain; charset=utf-8");

        if (request.Headers.TryGetValues("Authorization", out var headers))
        {
            foreach (var header in headers)
            {
                if (!header.StartsWith("Bearer ")) continue;
                var token = header["Bearer ".Length..];
                if (string.IsNullOrEmpty(token))
                {
                    _logger.LogWarning("Token is empty");
                    await response.WriteStringAsync("Authorization token is empty");
                    context.GetInvocationResult().Value = response;
                    return;
                }
                var tokenHandler = new JwtSecurityTokenHandler();
                try
                {
                    var jwtToken = tokenHandler.ReadJwtToken(token);
                    var userId = jwtToken.Claims.First(x => x.Type == "sub").Value;
                    if (_userIds.Contains(userId))
                    {
                        await next(context);
                        break;
                    }
                    else
                    {
                        await response.WriteStringAsync("User is not authorized");
                        context.GetInvocationResult().Value = response;
                        return;
                    }
                }
                catch (Exception e)
                {
                    _logger.LogWarning(e, "Token is invalid");
                    await response.WriteStringAsync("Token is invalid");
                    context.GetInvocationResult().Value = response;
                    return;
                }
            }
        }
        else
        {
            await response.WriteStringAsync("Unauthorized request");
            context.GetInvocationResult().Value = response;
        }
    }
}

额外优化点

  • 将response?.WriteString替换为await response.WriteStringAsync,遵循异步编程最佳实践
  • 增加了request == null的判断,避免空引用异常
  • 确保所有未授权分支都设置了context.GetInvocationResult().Value = response

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 00:50:29