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

.NET Aspire使用WithVolume()后PostgreSQL密码认证失败求助

解决.NET Aspire中PostgreSQL添加卷后密码认证失败问题

问题描述

我在.NET Aspire中尝试创建带卷的PostgreSQL数据库以实现数据持久化。连接字符串配置看似正确,但调用WithVolume()方法后出现postgres用户密码认证失败的错误,未添加该方法前一切正常。数据库容器的用户和密码与连接字符串完全一致,数据库端口设为58967,但TCP目标端口会动态变化,官方文档中未找到相关解决方案。

错误信息

Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
      An unhandled exception has occurred while executing the request.
      Npgsql.PostgresException (0x80004005): 28P01: password authentication failed for user "postgres"
         at Npgsql.Internal.NpgsqlConnector.ReadMessageLong(Boolean async, DataRowLoadingMode dataRowLoadingMode, Boolean readingNotifications, Boolean isReadingPrependedMessage)
         at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
         at Npgsql.Internal.NpgsqlConnector.AuthenticateSASL(List`1 mechanisms, String username, Boolean async, CancellationToken cancellationToken)
         at Npgsql.Internal.NpgsqlConnector.Authenticate(String username, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
         at Npgsql.Internal.NpgsqlConnector.<Open>g__OpenCore|213_1(NpgsqlConnector conn, SslMode sslMode, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken, Boolean isFirstAttempt)
         at Npgsql.Internal.NpgsqlConnector.Open(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
         at Npgsql.PoolingDataSource.OpenNewConnector(NpgsqlConnection conn, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
         at Npgsql.PoolingDataSource.<Get>g__RentAsync|34_0(NpgsqlConnection conn, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
         at Npgsql.NpgsqlConnection.<Open>g__OpenAsync|42_0(Boolean async, CancellationToken cancellationToken)
         at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternalAsync(Boolean errorsExpected, CancellationToken cancellationToken)
         at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternalAsync(Boolean errorsExpected, CancellationToken cancellationToken)
         at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenAsync(CancellationToken cancellationToken, Boolean errorsExpected)
         at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
         at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.InitializeReaderAsync(AsyncEnumerator enumerator, CancellationToken cancellationToken)
         at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.<>c__DisplayClass30_0`2.<ExecuteAsync>b__0>d.MoveNext()
      --- End of stack trace from previous location ---
         at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteImplementationAsync[TState,TResult](Func`4 operation, Func`4 verifySucceeded, TState state, CancellationToken cancellationToken)
         at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteImplementationAsync[TState,TResult](Func`4 operation, Func`4 verifySucceeded, TState state, CancellationToken cancellationToken)
         at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
         at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
         at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
         at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
         at Ardalis.Specification.EntityFrameworkCore.RepositoryBase`1.ListAsync(CancellationToken cancellationToken)
         at AspireSample.ApiService.Features.Templates.GetList.GetListQueryHandler.HandleInternal(GetListQuery request, CancellationToken cancellationToken) in C:\Users\user\Desktop\Projects\AspireSample\AspireSample\AspireSample.ApiService\Features\Templates\GetList\GetListQueryHandler.cs:line 23
         at AspireSample.ApiService.Features.BaseHandlers.QueryHandlerBase`2.Handle(TRequest request, CancellationToken cancellationToken) in C:\Users\user\Desktop\Projects\AspireSample\AspireSample\AspireSample.ApiService\Features\BaseHandlers\QueryHandlerBase.cs:line 20
         at AspireSample.ApiService.Features.Templates.TemplateModule.<>c.<AddRoutes>b__0_5>d.MoveNext() in C:\Users\user\Desktop\Projects\AspireSample\AspireSample\AspireSample.ApiService\Features\Templates\TemplateModule.cs:line 47
      --- End of stack trace from previous location ---
         at Microsoft.AspNetCore.Http.RequestDelegateFactory.<ExecuteTaskOfT>g__ExecuteAwaited|133_0[T](Task`1 task, HttpContext httpContext, JsonTypeInfo`1 jsonTypeInfo)
         at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddlewareImpl.<Invoke>g__Awaited|10_0(ExceptionHandlerMiddlewareImpl middleware, HttpContext context, Task task)
        Exception data:
          Severity: FATAL
          SqlState: 28P01
          MessageText: password authentication failed for user "postgres"
          File: auth.c
          Line: 323
          Routine: auth_failed

相关代码

AppHost中的数据库定义

var postgresPassword = builder.AddParameter("postgresql-password", true);
var db = builder.AddPostgres("db", password: postgresPassword).WithDataVolume().WithPgAdmin();
var templateApiDb = db.AddDatabase("templateApiDb");

var apiService = builder.AddProject<Projects.AspireSample_ApiService>("apiservice")
    .WithReference(templateApiDb);

ApiService中的DbContext配置

builder.AddNpgsqlDbContext<AppDbContext>("templateApiDb");

Api项目中硬编码的连接字符串

ConnectionStrings__templateApiDb: Host=localhost;Port=58967;Username=postgres;Password=postgres;Database=templateApiDb

解决方案

  • 清理旧Docker卷:添加WithVolume()后,PostgreSQL会复用卷中存储的旧认证数据(即使密码已修改)。执行以下步骤:

    1. 运行docker volume ls列出所有卷,找到与当前Aspire项目关联的PostgreSQL卷(名称通常包含项目标识和postgres关键字)
    2. 运行docker volume rm [目标卷名称]删除该卷
    3. 重启Aspire应用,容器会重新初始化卷并使用新的密码配置
  • 移除硬编码连接字符串:Aspire通过WithReference(templateApiDb)会自动为Api服务注入正确的连接字符串,包括动态端口和认证信息。删除Api项目中手动配置的ConnectionStrings__templateApiDb,依赖自动注入即可避免端口和密码不匹配问题

  • 验证参数配置:检查Aspire Dashboard中的postgresql-password参数值是否正确,测试阶段可直接指定密码确认配置:

    var db = builder.AddPostgres("db", password: "postgres").WithDataVolume().WithPgAdmin();
    

内容的提问来源于stack exchange,提问作者Kristián Masár

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 13:13:11