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

使用Keycloak与.NET Core集成时出现签名密钥未找到错误

解决Docker环境下.NET Core WebAPI对接Keycloak时的签名密钥找不到问题

你的配置与错误信息

认证配置代码

services
    .AddAuthentication(options =>
    {
        options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultSignInScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultForbidScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(options =>
    {
        options.MetadataAddress = "http://localhost:8080/auth/realms/{my_realm}/.well-known/openid-configuration";
        options.Authority = "http://localhost:8080/auth/realms/{my_realm}";
        options.Audience = "{my_audience}";
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidAudience = "{my_audience}",
            ValidIssuers = ["http://localhost:8080/auth/realms/{my_realm}", "https://localhost:8080/auth/realms/{my_realm}"]
        };
        options.RequireHttpsMetadata = false;
        options.SaveToken = true;
    });

错误提示

  • 响应头错误:
    www-authenticate: Bearer error="invalid_token",error_description="The signature key was not found"
    
  • DEBUG日志错误:
    Microsoft.IdentityModel.Tokens.SecurityTokenSignatureKeyNotFoundException: IDX10500: Signature validation failed. No security keys were provided to validate the signature.
    

问题根源

你用了localhost:8080作为Keycloak的访问地址,但Docker容器内部的localhost指向容器自身,而非宿主机。这导致WebAPI容器无法访问到Keycloak容器,自然拉取不到OIDC元数据(包含验证签名所需的公钥),最终触发签名验证失败。

修复方案

1. 改用Docker容器名称/服务名访问Keycloak

Docker容器在同一个网络内可以通过容器名称互相访问,步骤如下:

  • 确保WebAPI和Keycloak容器处于同一个Docker网络(如果没有,先创建:docker network create keycloak-net)
  • 把配置中的localhost替换成Keycloak的容器名称(假设Keycloak容器名为keycloak)

2. 同步Token验证的Issuer配置

Keycloak生成的Token中iss字段是它自身的访问地址,需要和ValidIssuers保持一致,否则也会验证失败。

修改后的完整配置

services
    .AddAuthentication(options =>
    {
        options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultSignInScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultForbidScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(options =>
    {
        // 替换为你的Keycloak容器名称
        var keycloakContainerName = "keycloak";
        options.MetadataAddress = $"http://{keycloakContainerName}:8080/auth/realms/{my_realm}/.well-known/openid-configuration";
        options.Authority = $"http://{keycloakContainerName}:8080/auth/realms/{my_realm}";
        options.Audience = "{my_audience}";
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidAudience = "{my_audience}",
            // 与Keycloak生成Token的issuer保持一致
            ValidIssuers = new[] { $"http://{keycloakContainerName}:8080/auth/realms/{my_realm}" }
        };
        options.RequireHttpsMetadata = false;
        options.SaveToken = true;
    });

额外注意事项

  • 如果用Docker Compose管理容器,直接在docker-compose.yml中定义同一个网络,服务之间可以用服务名(比如keycloak)互相访问,无需手动创建网络。
  • 若需要从宿主机访问Keycloak,仍可以用localhost:8080,但容器间通信必须用容器名称/服务名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 13:34:50