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

.NET Core 3.1 替换OpenIdConnectOptions发现文档端点不破坏授权流的方法

问题根因

你手动构造OpenIdConnectConfiguration并赋值给options.Configuration后,OIDC中间件会直接跳过自动元数据拉取流程,不会主动请求你配置的JwksUri地址加载签名公钥,导致SigningKeys集合为空,自然匹配不到对应kid的密钥,触发签名验证失败的报错。使用选项1、2时,中间件会自动完成发现文档拉取、JWKS公钥加载、元数据定时刷新的逻辑,所以运行正常。

解决方案

分两种场景选择适配的方案:

场景1:完全不使用自动发现,全手动配置

你需要手动加载JWKS中的签名密钥,填充到配置对象的SigningKeys属性中,修改后的选项3代码如下:

// 手动构造配置对象设置各URL
var issuer = Configuration["AuthorityAddress"]; // 注意配置Key大小写和你配置文件保持一致
var authorization_endpoint = issuer + "/someidentityserver/authorize";
var token_endpoint = issuer + "/someidentityserver/token";
var userinfo_endpoint = issuer + "/someidentityserver/userinfo";
var jwks_uri = issuer + "/someidentityserver/jwks";

// 手动拉取JWKS并解析密钥
var httpClient = new HttpClient();
var jwksJson = httpClient.GetStringAsync(jwks_uri).GetAwaiter().GetResult();
var jwks = new JsonWebKeySet(jwksJson);

options.Configuration = new OpenIdConnectConfiguration()
{
    AuthorizationEndpoint = authorization_endpoint,
    JwksUri = jwks_uri,
    TokenEndpoint = token_endpoint,
    UserInfoEndpoint = userinfo_endpoint,
    Issuer = issuer,
    // 新增:填充签名密钥,可按需添加单个密钥或全部密钥
    SigningKeys = { jwks.Keys }
};

注意:该方案不会自动刷新签名密钥,如果身份服务更换了签名密钥,你需要重启应用才能加载新密钥,适合完全离线的部署场景。

场景2:仅替换自定义端点,保留自动发现能力(更推荐)

不需要完全手动构造配置对象,保留原有自动发现配置,通过OnMetadataReceived事件修改加载完成的元数据端点即可,既可以自定义端点,又能保留中间件自动加载JWKS、自动刷新元数据和密钥的原生能力,不会破坏原有授权流程:

private void SetOpenIdConnectOptions(OpenIdConnectOptions options)
{
    options.ClientId = Configuration["ClientId"];
    options.ClientSecret = Configuration["ClientSecret"];
    options.ResponseType = "code";
    options.ResponseMode = "query";

    // 保留原有自动发现配置,选选项1或选项2都可以
    options.Authority = Configuration["AuthorityAddress"];

    // 新增元数据接收事件,修改自定义端点
    options.Events.OnMetadataReceived = context =>
    {
        var metadata = context.Metadata;
        var issuer = options.Authority.TrimEnd('/');
        metadata.AuthorizationEndpoint = $"{issuer}/someidentityserver/authorize";
        metadata.TokenEndpoint = $"{issuer}/someidentityserver/token";
        metadata.UserInfoEndpoint = $"{issuer}/someidentityserver/userinfo";
        metadata.JwksUri = $"{issuer}/someidentityserver/jwks";
        return Task.CompletedTask;
    };
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 22:09:04