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

.NET Core 6长时运行函数的异步HTTP API实现及认证等疑问

异步HTTP API + Azure Functions 解决方案

问题1:Azure Functions复用原项目JWT认证规则

完全可以复用,推荐采用Azure Functions隔离进程模型(更贴近ASP.NET Core生态),直接移植原项目的认证配置:

实现步骤

  1. 在Function项目中添加Microsoft.AspNetCore.Authentication.JwtBearer包,版本和原项目保持一致。
  2. 创建Startup.cs,继承FunctionsStartup,复制原项目的认证注册逻辑:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

public class Startup : FunctionsStartup
{
    public override void Configure(IFunctionsHostBuilder builder)
    {
        builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                // 完全复制原项目的JWT配置
                options.Authority = "https://your-auth-provider.com";
                options.Audience = "your-api-audience";
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidateLifetime = true,
                    ValidateIssuerSigningKey = true
                    // 其他参数如IssuerSigningKey等,和原项目完全一致
                };
            });

        builder.Services.AddAuthorization();
    }
}
  1. 在Function方法上添加[Authorize]特性,即可实现和原项目完全相同的认证授权规则:
[Authorize]
[FunctionName("LongRunningTask")]
public async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req,
    ILogger log)
{
    // 仅持有合法JWT令牌的请求可进入
    var userId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
    // 后续逻辑
}

如果使用进程内模型,可手动验证JWT令牌:提取请求头中的Authorization令牌,用原项目的验证逻辑校验,通过后再处理业务。


问题2:主项目控制器代理请求至Azure Functions是否合理?

这种方式可行,但并非最优解,需权衡以下点:

优点

  • 认证逻辑集中在主项目,Function无需暴露给外部,仅接受主项目的调用,安全性更高。
  • 主项目可统一请求入口,便于后续扩展路由、限流等逻辑。

缺点

  • 增加了中间代理层,提升了架构复杂度,多一层网络调用可能带来延迟。
  • 主项目仍需处理请求转发逻辑,无法完全剥离异步任务的负担。

代理实现示例

主项目控制器中通过HttpClient调用Function,用Function访问密钥(或Azure AD服务主体)做身份验证:

[Authorize]
[ApiController]
[Route("api/tasks")]
public class TaskProxyController : ControllerBase
{
    private readonly HttpClient _httpClient;
    private readonly IConfiguration _config;

    public TaskProxyController(HttpClient httpClient, IConfiguration config)
    {
        _httpClient = httpClient;
        _config = config;
    }

    [HttpPost]
    public async Task<IActionResult> SubmitLongRunningTask([FromBody] TaskPayload payload)
    {
        // 主项目已完成JWT认证,现在调用Function
        var functionUrl = _config["AzureFunctions:LongRunningTaskUrl"];
        var functionKey = _config["AzureFunctions:FunctionAccessKey"];

        _httpClient.DefaultRequestHeaders.Add("x-functions-key", functionKey);
        var response = await _httpClient.PostAsJsonAsync(functionUrl, payload);
        
        if (!response.IsSuccessStatusCode)
        {
            return StatusCode((int)response.StatusCode);
        }

        var taskResult = await response.Content.ReadFromJsonAsync<TaskResponse>();
        return Ok(taskResult);
    }
}

更优实现方案

针对5-20分钟的长时间任务,推荐采用Durable Functions + 直接客户端调用的架构:

核心架构

  1. Durable Functions:专门用于处理长时间运行的工作流,自动管理任务状态、重试、超时,无需手动维护队列和状态存储。
  2. 客户端直接调用:Function复用原项目JWT认证,客户端用原令牌直接访问Function,省去代理层。
  3. 状态持久化:Durable Functions自动将任务状态存储在Azure Storage中,可通过内置的状态查询端点让客户端获取进度。

Durable Functions示例

  1. 创建Orchestrator Function(编排任务):
[FunctionName("LongRunningTaskOrchestrator")]
public async Task<TaskResult> RunOrchestrator(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var payload = context.GetInput<TaskPayload>();
    // 调用活动Function处理耗时任务
    var result = await context.CallActivityAsync<string>("LongRunningTaskActivity", payload);
    return new TaskResult { TaskId = context.InstanceId, Result = result, Status = "Completed" };
}
  1. 创建Activity Function(执行实际耗时工作):
[FunctionName("LongRunningTaskActivity")]
public async Task<string> RunActivity(
    [ActivityTrigger] TaskPayload payload,
    ILogger log)
{
    // 执行5-20分钟的耗时操作,比如数据处理、文件生成等
    await DoHeavyWork(payload);
    return "处理完成";
}
  1. 创建HTTP触发的启动端点:
[Authorize]
[FunctionName("StartLongRunningTask")]
public async Task<IActionResult> StartTask(
    [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req,
    [DurableClient] IDurableOrchestrationClient client,
    ILogger log)
{
    var payload = await req.ReadFromJsonAsync<TaskPayload>();
    var instanceId = await client.StartNewAsync("LongRunningTaskOrchestrator", payload);
    
    return client.CreateCheckStatusResponse(req, instanceId);
}

客户端调用StartLongRunningTask后,会立即得到包含任务ID和状态查询URL的响应,后续可通过该URL轮询任务进度,或配置WebHook接收完成通知。


关键注意事项

  • Function超时配置:高级计划/专用计划下,Azure Functions最长超时可设为60分钟;若任务超过60分钟,必须用Durable Functions拆分任务。
  • 安全加固:若采用客户端直接调用,确保Function的JWT配置和原项目完全一致,避免非法访问;若用代理,限制Function的IP访问范围仅允许主项目的App Service IP。
  • 错误处理:为耗时任务添加重试逻辑,Durable Functions支持自动重试,可配置重试策略。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 10:51:11