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

Docker化Duende Identity Server时配置获取失败问题求助

问题描述

我正在将一个微服务架构的个人项目Docker化,项目包含多个微服务、客户端和Duende Identity Server。本地环境下,客户端可直接与Duende Identity Server通信:点击登录会跳转至Identity Server完成注册或认证,之后返回客户端并携带授权Cookie。但Docker化后遇到两个矛盾的问题:

  1. 配置客户端连接localhost的Identity Server时,会报错:Unable to obtain configuration from: 'https://localhost:44384/.well-known/openid-configuration'. Connection refused,但手动在浏览器访问该链接能正常获取JSON响应。
  2. 配置成Docker内部地址https://app.service.identity时,浏览器会跳转至仅Docker内部可访问的链接,导致页面找不到。

相关配置文件

docker-compose.yml

x-app-default-env: &app-default-env
  Logging__LogLevel__Default: Information
  Logging__LogLevel__Microsoft.AspNetCore: Warning
  AllowedHosts: "*"

services:
  app:
    restart: unless-stopped
    image: mango.web
    build:
      context: ./Mango.Web
    volumes:
      - ./Mango.Web/wwwroot:/app/wwwroot
    environment:
      <<: *app-default-env
      ServiceUrls__IdentityAPI: https://localhost:44384
      ServiceUrls__ProductAPI: http://app.service.product
      ServiceUrls__CouponAPI: http://app.service.coupon
      ServiceUrls__ShoppingCartAPI: http://app.service.shoppingcart
      ServiceUrls__AzureBlobAPI:
      ConnectionStrings__DefaultConnection: "Host=db;Port=5432;Username=postgres;Password=postgres;Database=MangoWEBAPI"

  app.service.order:
    restart: unless-stopped
    image: mango.services.order
    build:
      context: .
      dockerfile: ./Mango.Services.OrderAPI/Dockerfile
    environment:
      <<: *app-default-env
      ConnectionStrings__DefaultConnection: "Host=db;Port=5432;Username=postgres;Password=postgres;Database=MangoOrderAPI"
      ConnectionStrings__AzureServiceBus: ${AZURE_SERVICE_BUS_CONNECTION_STRING}
      CheckoutMessageTopic: "checkoutmessagetopic"
      CheckoutSubscription: "mangoOrdersSubscription"
      OrderPaymentProcessTopic: "orderpaymentprocesstopic"
      OrderPaymentProcessSubscription: "mangoPayment"
      OrderUpdatePaymentResultTopic: "orderupdatepaymentresulttopic"
      OrderUpdatePaymentResultSubscription": "mangoOrdersSubscription"
      CheckoutMessageQueue: "checkoutqueue"
    
      
  app.service.azureblobservice:
    restart: unless-stopped
    image: mango.services.azureblobservice
    build: Mango.Services.AzureBlobService
    environment:
      <<: *app-default-env
      ServiceUrls__IdentityServer: http://app.service.identity
      ConnectionStrings__BlobStorage: ${CONNECTION_STRINGS_BLOB_STORAGE}
      BlobContainerName: ${BLOB_CONTAINER_NAME}
      
  app.service.product:
    restart: unless-stopped
    image: mango.services.productapi
    build: Mango.Services.ProductAPI
    environment:
      <<: *app-default-env
      ConnectionStrings__DefaultConnection: "Host=db;Port=5432;Username=postgres;Password=postgres;Database=MangoProductAPI"

  app.service.payment:
    restart: unless-stopped
    image: mango.services.payment
    build:
      context: .
      dockerfile: ./Mango.Services.PaymentAPI/Dockerfile
    environment:
      <<: *app-default-env
      ServiceUrls__IdentityServer: http://app.service.identity
      ConnectionStrings__AzureServiceBus: ${AZURE_SERVICE_BUS_CONNECTION_STRING}
      OrderPaymentProcessTopic: "orderpaymentprocesstopic"
      OrderPaymentProcessSubscription: "mangoPayment"
      OrderUpdatePaymentResultTopic: "orderupdatepaymentresulttopic"
      OrderUpdatePaymentResultSubscription: "mangoOrdersSubscription"
      ConnectionStrings__DefaultConnection: "Host=db;Port=5432;Username=postgres;Password=postgres;Database=MangoPaymentAPI"

  app.service.shoppingcart:
    restart: unless-stopped
    image: mango.services.shoppingcart
    build:
      context: .
      dockerfile: ./Mango.Services.ShoppingCartAPI/Dockerfile
    environment:
      <<: *app-default-env
      ServiceUrls__IdentityServer: http://app.service.identity
      ServiceUrls__CouponAPI: http://app.service.coupon
      ConnectionStrings__DefaultConnection: "Host=db;Port=5432;Username=postgres;Password=postgres;Database=MangoShoppingCartAPI"

  app.service.identity:
    restart: unless-stopped
    image: mango.services.identity
    build: Mango.Services.Identity
    volumes:
      - ./Mango.Services.Identity/wwwroot:/app/wwwroot
    environment:
      <<: *app-default-env
      ConnectionStrings__DefaultConnection: "Host=db;Port=5432;Username=postgres;Password=postgres;Database=MangoIdentityAPI"

  app.service.email:
    restart: unless-stopped
    image: mango.services.email
    build:
      context: .
      dockerfile: ./Mango.Services.Email/Dockerfile
    environment:
      <<: *app-default-env
      ConnectionStrings__AzureServiceBus: ${AZURE_SERVICE_BUS_CONNECTION_STRING}
      OrderUpdatePaymentResultTopic: "orderupdatepaymentresulttopic"
      EmailSubscription: "emailSubscription"
      ConnectionStrings__DefaultConnection: "Host=db;Port=5432;Username=postgres;Password=postgres;Database=MangoEmailAPI"

  app.service.coupon:
    restart: unless-stopped
    image: mango.services.coupon
    build: Mango.Services.CouponAPI
    environment:
      <<: *app-default-env
      ServiceUrls__IdentityServer:
      ConnectionStrings__DefaultConnection: "Host=db;Port=5432;Username=postgres;Password=postgres;Database=MangoCouponAPI"

docker-compose.override.yml

services:
  app:
    ports:
      - 8080:80
      - 44315:443
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=https://+:443;http://+:80
      - ASPNETCORE_Kestrel__Certificates__Default__Password=password
      - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx
    volumes:
      - ~/.aspnet/https:/https:ro
  
  app.service.identity:
    ports:
      - 44384:443
      - 8081:80
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=https://+:443;http://+:80
      - ASPNETCORE_Kestrel__Certificates__Default__Password=password
      - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx
    volumes:
      - ~/.aspnet/https:/https:ro

  db:
    restart: unless-stopped
    ports:
      - 5433:5432
    image: postgres:16
    user: root
    volumes:
      - ../docker/db/data:/var/lib/pgsql/data
    environment:
      POSTGRES_PASSWORD: postgres
      POSTGRES_USER: postgres

Client Program.cs 授权配置

builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = "Cookies";
    options.DefaultChallengeScheme = "oidc";
}).AddCookie("Cookies", c => c.ExpireTimeSpan=TimeSpan.FromMinutes(10))
    .AddOpenIdConnect("oidc", options =>
    {
        options.Authority = builder.Configuration["ServiceUrls:IdentityAPI"];
        options.GetClaimsFromUserInfoEndpoint = true;
        options.ClientId = "mango";
        options.ClientSecret = "secret";
        options.ResponseType = "code";
        options.ClaimActions.MapJsonKey("role", "role", "role");
        options.ClaimActions.MapJsonKey("sub", "sub", "sub");
        options.TokenValidationParameters.NameClaimType = "name";
        options.TokenValidationParameters.RoleClaimType = "role";
        options.Scope.Add("mango");
        options.SaveTokens = true;
        options.RequireHttpsMetadata = false;
        options.BackchannelHttpHandler = new HttpClientHandler
        {
            ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true
        };
    });

解决方案

核心矛盾是容器内服务和外部浏览器访问Identity Server的地址不一致:容器内的客户端服务需要用Docker内部域名访问,而浏览器必须用宿主机的公开地址访问。按以下步骤调整即可解决:

1. 给Identity Server配置公开访问地址

在docker-compose.override.yml的app.service.identity环境变量中,添加公开地址配置,让Duende Identity Server生成浏览器能访问的跳转地址:

app.service.identity:
    # 原有配置保留
    environment:
      # 新增这一行
      - IdentityServer__PublicOrigin=https://localhost:44384

2. 调整客户端服务的Identity Server地址

把docker-compose.yml中app服务的ServiceUrls__IdentityAPI改成Docker内部域名,让容器内的客户端服务能正常连通Identity Server:

app:
    environment:
      # 把原有的localhost地址改成内部域名
      ServiceUrls__IdentityAPI: https://app.service.identity:443
      # 其他配置保留

3. 修正Identity Server的客户端配置

在Duende Identity Server的客户端注册代码中,确保回调地址、注销地址用宿主机的公开地址,比如:

new Client
{
    ClientId = "mango",
    ClientSecret = "secret",
    // 对应app服务在宿主机的HTTPS端口44315
    RedirectUris = { "https://localhost:44315/signin-oidc" },
    PostLogoutRedirectUris = { "https://localhost:44315/signout-callback-oidc" },
    // 其他配置保留
}

4. 验证容器间连通性(可选)

如果还是有问题,可进入客户端容器测试内部网络:

# 替换成你的app容器ID
docker exec -it <app-container-id> bash
# 测试访问Identity Server内部地址
curl https://app.service.identity:443/.well-known/openid-configuration

能返回JSON说明容器内网络正常。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 18:35:55