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

Aspire中.NET 8独立Azure Functions连App配置模拟器报401未授权

问题描述

我有一个目标框架为.NET 8.0的独立模式Azure Functions应用,已添加Aspire主机项目和ServiceDefaults项目,部署了以下容器:SQL Server、存储账户模拟器、Service Bus模拟器、Azure App配置模拟器。

AppHost.cs 配置

var database = builder.AddSqlServer("AspireSqlServer", port: 54321)
    .WithEndpointProxySupport(false)
    .WithLifetime(ContainerLifetime.Persistent)
    .AddDatabase("AspireDatabase");

var storage = builder
    .AddAzureStorage("AspireStorage")
    .RunAsEmulator(emulator =>
    {
        emulator.WithLifetime(ContainerLifetime.Persistent);
        emulator.WithEndpointProxySupport(false);
        emulator.WithBlobPort(5555);
        emulator.WithQueuePort(5556);
        emulator.WithTablePort(5557);
    });

var serviceBus = builder
    .AddAzureServiceBus("AspireServiceBus")
    .RunAsEmulator(emulator =>
    {
        emulator.WithLifetime(ContainerLifetime.Persistent);
        emulator.WithEndpointProxySupport(false);
        emulator.WithHostPort(5674);
        emulator.WithConfigurationFile("sbemulator.json");
    });

var appConfig = builder
    .AddAzureAppConfiguration("appConfig")
    .RunAsEmulator(emulator =>
    {
        emulator.WithLifetime(ContainerLifetime.Persistent);
        emulator.WithHostPort(56788);
    });

builder.AddAzureFunctionsProject<Projects.FunctionApp1>("FunctionApp")
    .WithReference(database)
    .WithReference(serviceBus)
    .WithReference(appConfig)
    .WithHostStorage(storage)
    .WithRoleAssignments(storage, StorageBuiltInRole.StorageAccountContributor)
    .WithEnvironment("ASPNETCORE_ENVIRONMENT", "Development")
    .WithEnvironment("DOTNET_ENVIRONMENT", "Development")
    .WaitFor(database)
    .WaitFor(storage)
    .WaitFor(serviceBus)
    .WaitFor(appConfig)
    ;

函数应用 Program.cs 配置

var builder = FunctionsApplication.CreateBuilder(args);

builder.AddServiceDefaults();
builder.ConfigureFunctionsWebApplication();
builder.Logging.AddConsole();

var dbConnectionString = builder.Configuration.GetConnectionString("AspireDatabase");
var configConnectionString = builder.Configuration.GetConnectionString("appConfig");

builder.Configuration.AddAzureAppConfiguration(
    options =>
    {
        options.Connect(configConnectionString);
    }
    );

builder.Services.AddAzureAppConfiguration();
builder.Services.AddDbContext<MyDbContext>(o =>
{
    o.UseSqlServer(dbConnectionString);
});

var app = builder.Build();

// Run EF Core migrations at startup
using (var scope = app.Services.CreateScope())
{
    var db = scope.ServiceProvider.GetRequiredService<MyDbContext>();
    await db.Database.MigrateAsync();
}

await app.RunAsync();

异常情况

启动Aspire后,所有容器成功启动,函数应用也正确等待依赖项就绪。数据库可正常工作,EF迁移执行无误,也能访问App配置并添加设置。但函数应用最终启动失败,无法连接App配置资源,报错401(未授权)。禁用App配置资源后,函数应用可正常启动,定时器触发器能正常运行并向数据库存储数据。

异常信息

Service request failed.
Status: 401 (Unauthorized)

Headers:
Date: Wed, 07 Jan 2026 16:14:18 GMT
Server: Kestrel
WWW-Authenticate: HMAC-SHA256 error="forbidden", error_description="Authentication scheme disabled",Bearer,Anonymous
x-ms-request-id: aab11441-f6d5-4bc0-8b8b-98971f40da57
x-ms-client-request-id: d3784930-5e64-4b41-b917-5a23ff0c8b88
x-ms-correlation-request-id: aab11441-f6d5-4bc0-8b8b-98971f40da57
Content-Length: 0

堆栈跟踪

at Azure.Data.AppConfiguration.ConditionalPageableImplementation.GetResponse(HttpMessage message)
   at Azure.Data.AppConfiguration.ConditionalPageableImplementation.<GetNextResponseAsync>d__14.MoveNext()
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at Azure.Data.AppConfiguration.ConditionalPageableImplementation.<AsPagesAsync>d__10.MoveNext()
   at Azure.Data.AppConfiguration.ConditionalPageableImplementation.<AsPagesAsync>d__10.System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult(Int16 token)
   at Microsoft.Extensions.Configuration.AzureAppConfiguration.AzureAppConfigurationProvider.<>c__DisplayClass42_1.<LoadSelected>b__0.MoveNext()
   at Microsoft.Extensions.Configuration.AzureAppConfiguration.AzureAppConfigurationProvider.<>c__DisplayClass42_1.<LoadSelected>b__0.MoveNext()
   at Microsoft.Extensions.Configuration.AzureAppConfiguration.TracingUtils.<CallWithRequestTracing>d__3.MoveNext()
   at Microsoft.Extensions.Configuration.AzureAppConfiguration.AzureAppConfigurationProvider.<LoadSelected>d__42.MoveNext()
   at Microsoft.Extensions.Configuration.AzureAppConfiguration.AzureAppConfigurationProvider.<>c__DisplayClass41_0.<InitializeAsync>b__0.MoveNext()
   at Microsoft.Extensions.Configuration.AzureAppConfiguration.AzureAppConfigurationProvider.<>c__DisplayClass54_0.<ExecuteWithFailOverPolicyAsync>b__0.MoveNext()
   at Microsoft.Extensions.Configuration.AzureAppConfiguration.AzureAppConfigurationProvider.<ExecuteWithFailOverPolicyAsync>d__53`1.MoveNext()
   at Microsoft.Extensions.Configuration.AzureAppConfiguration.AzureAppConfigurationProvider.<ExecuteWithFailOverPolicyAsync>d__54.MoveNext()
   at Microsoft.Extensions.Configuration.AzureAppConfiguration.AzureAppConfigurationProvider.<InitializeAsync>d__41.MoveNext()
   at Microsoft.Extensions.Configuration.AzureAppConfiguration.AzureAppConfigurationProvider.<TryInitializeAsync>d__40.MoveNext()
解决方案

这个401错误的核心原因是Azure App配置模拟器默认禁用了HMAC认证方案,而函数应用默认使用HMAC方式尝试连接,导致认证失败。需要在连接配置中明确允许匿名访问以适配模拟器:

修改函数应用的Program.cs配置

在AddAzureAppConfiguration的配置项中添加AllowAnonymous(),允许模拟器的匿名访问模式:

builder.Configuration.AddAzureAppConfiguration(
    options =>
    {
        options.Connect(configConnectionString)
               // 添加该行配置,适配模拟器的匿名认证要求
               .AllowAnonymous();
    }
);

额外验证项

  • 确认连接字符串:Aspire自动注入的App配置模拟器连接字符串应为Endpoint=http://localhost:56788,无需包含密钥等认证参数。
  • 检查模拟器配置:当前Aspire中appConfig的RunAsEmulator配置已默认启用匿名模式,无需额外调整。
  • ServiceDefaults兼容性:builder.AddServiceDefaults()不会覆盖App配置的认证逻辑,无需修改该部分代码。

修改完成后重新启动Aspire,函数应用即可正常连接Azure App配置模拟器,不会再出现401未授权错误。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.11 18:05:13