Docker环境下.NET 6 API集成Keycloak认证始终失败求助
.NET 6 API容器化后Keycloak认证401问题解决
核心问题分析
非容器环境正常、容器化后401的核心原因:
- 容器网络访问不匹配:API容器内使用
host.docker.internal访问Keycloak,但Keycloak同属一个Docker网络,应使用服务名keycloak进行内部访问 - JWT Issuer验证不通过:Keycloak生成的Token Issuer是外部访问地址(
http://localhost:8080/realms/test),而API容器内配置的Authority是内部地址,两者不匹配触发验证失败 - Keycloak前端URL配置错误:
KEYCLOAK_FRONTEND_URL设为test.orderapi,导致前端登录跳转地址异常 - 端口配置无效:
docker-compose.override.yml中API的端口配置- "8"格式错误,无法正常映射外部访问端口
分步修正方案
1. 修正Program.cs的认证配置
调整Authority为Docker网络内的Keycloak服务名,添加多Issuer支持并增加调试日志:
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using Test.OrderApi.Settings; var builder = WebApplication.CreateBuilder(args); var config = builder.Configuration; builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, o => { // 改用Docker网络内的Keycloak服务名访问 o.Authority = "http://keycloak:8080/realms/test"; o.TokenValidationParameters = new TokenValidationParameters { ValidateAudience = false, // 同时支持外部和内部Issuer,匹配Token中的Issuer值 ValidIssuers = new[] { "http://localhost:8080/realms/test", "http://keycloak:8080/realms/test" } }; o.RequireHttpsMetadata = false; // 添加认证失败日志,方便调试问题 o.Events = new JwtBearerEvents { OnAuthenticationFailed = context => { Console.WriteLine($"认证失败详情: {context.Exception.Message}"); if (context.Exception is SecurityTokenInvalidIssuerException issuerEx) { Console.WriteLine($"无效Issuer: {issuerEx.InvalidIssuer}, 允许的Issuer列表: {string.Join(", ", issuerEx.ValidIssuers)}"); } return Task.CompletedTask; } }; }); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } // 开发环境注释HTTPS重定向,避免容器内HTTP访问被强制跳转 // app.UseHttpsRedirection(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();
2. 修正docker-compose.yml的Keycloak配置
调整KEYCLOAK_FRONTEND_URL为外部可访问地址,修复PostgreSQL配置错误:
version: '3.4' services: test.orderapi: container_name: order-api image: ${DOCKER_REGISTRY-}testorderapi build: context: . dockerfile: tests/TestDummyMicroservices/Test.Order.Api/Dockerfile networks: - keycloak_network postgres_keycloak: container_name: postgres-keycloak image: postgres:14.6 command: postgres -c 'max_connections=200' volumes: - pgdata_keycloak:/var/lib/postgresql/data # 修正拼写错误:postgressql -> postgresql environment: POSTGRES_DB: keycloak POSTGRES_USER: keycloak POSTGRES_PASSWORD: password healthcheck: test: ["CMD-SHELL", "pg_isready -U keycloak -d keycloak"] # 替换为真实的PostgreSQL健康检查 interval: 10s timeout: 5s retries: 5 ports: - "5436:5432" networks: - keycloak_network keycloak: container_name: keycloak image: quay.io/keycloak/keycloak:20.0.3 command: start-dev environment: KC_DB: postgres KC_DB_URL_HOST: postgres_keycloak KC_DB_URL_DATABASE: keycloak KC_DB_PASSWORD: password KC_DB_USERNAME: keycloak KC_DB_SCHEMA: public KEYCLOAK_ADMIN: admin KEYCLOAK_ADMIN_PASSWORD: admin # 修正前端访问URL为外部可访问地址 KEYCLOAK_FRONTEND_URL: http://localhost:8080 KC_HTTP_ENABLED: true KC_HTTP_PORT: 8080 depends_on: postgres_keycloak: condition: service_healthy ports: - "8080:8080" networks: - keycloak_network volumes: pgdata_keycloak: networks: keycloak_network: driver: bridge
3. 修正docker-compose.override.yml的API端口配置
调整为有效的端口映射格式,方便外部访问API:
version: '3.4' services: test.orderapi: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://+:80 ports: # 外部端口5000映射到容器80端口,外部可通过http://localhost:5000访问API - "5000:80" # 若test.gateway未在主docker-compose.yml中定义,可暂时移除该配置 # test.gateway: # environment: # - ASPNETCORE_ENVIRONMENT=Development # ports: # - "80:80"
验证步骤
- 重新启动容器:
docker-compose down && docker-compose up --build - 测试API容器与Keycloak的网络连通性:
返回JSON格式的OpenID配置则说明网络连通正常docker exec -it order-api curl http://keycloak:8080/realms/test/.well-known/openid-configuration - 查看API容器日志,确认无认证相关错误:
docker logs order-api - 使用Postman或Swagger访问
http://localhost:5000,携带Keycloak生成的Token请求API,验证是否返回200正常响应
内容的提问来源于stack exchange,提问作者Getraj
相关产品推荐
相关产品推荐

