ASP.NET应用接入自建OIDC服务报invalid_client错误如何解决?
ASP.NET接入自研OIDC服务端invalid_client错误解决方案
错误信息
System.Exception: An error was encountered while handling the remote login.
---> Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectProtocolException: Message contains error: 'invalid_client', error_description: 'Invalid authentication method for accessing this endpoint.', error_uri: 'error_uri is null'
问题根因与修复步骤
该错误是客户端向OIDC服务端发起请求时身份认证校验失败导致,现有代码存在多处错误,按优先级修复如下:
1. 删除错误的Authorization头注入代码
你在OnRedirectToIdentityProvider事件中手动加Authorization头的逻辑完全错误:
- 该事件触发在跳转到授权端点阶段,是服务端返回302给浏览器跳转,你注入的服务端请求头无法传递到浏览器发起的授权请求中
- 你构造的Authorization头格式完全不符合Basic认证规范,错误的头会导致后续请求异常
直接删除以下代码即可:
var byteArray = Encoding.ASCII.GetBytes(options.ClientId + ":" + options.ClientSecret); context.Request.Headers.Add("Authorization", "Post " + byteArray);
同时将事件返回值修改为标准的return Task.CompletedTask; 替换原有return Task.FromResult(0);
2. 修正配置项错误
- 补全
JwksUri的https前缀,确保是完整可访问的公钥地址:
JwksUri = "https://ourOIDCServer/ourOIDCServer/oauth2/multiauth/connect/jwk_uri"
- 显式指定和自研OIDC服务端匹配的客户端认证方式,和你服务端上客户端配置的认证方法保持一致即可:
// 服务端用client_secret_basic认证(默认推荐) options.TokenEndpointAuthenticationMethod = OpenIdConnectClientAuthenticationMethod.Basic.ToString(); // 服务端用client_secret_post认证则替换为下面这行 // options.TokenEndpointAuthenticationMethod = OpenIdConnectClientAuthenticationMethod.Post.ToString();
- 如果你手动指定了完整
OpenIdConnectConfiguration,可以关闭元数据自动拉取校验,避免冲突:
options.RequireHttpsMetadata = true; // 生产环境保持true,开发环境如果是http可临时设为false options.MetadataAddress = null;
3. 可选优化(推荐)
不需要手动填写所有OIDC端点,直接删除手动定义的OpenIdConnectConfiguration配置块,配置正确的元数据地址让中间件自动拉取配置,避免端点写错:
options.Authority = "https://ourOIDCServer/ourOIDCServerwebsso/oauth2/multiauth"; options.MetadataAddress = "https://ourOIDCServer/ourOIDCServerwebsso/oauth2/multiauth/.well-known/openid-configuration";
4. 服务端配置校验
确认自研OIDC服务端上的客户端配置:
- ClientId、ClientSecret和代码中配置完全一致
- 已开启authorization_code授权模式
- 回调地址和你应用的回调地址完全匹配
- 已开放你申请的
openid uid isMemberOf权限范围
修复后核心配置示例
.AddOpenIdConnect(options => { options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.ResponseType = "code"; options.ClientId = "你的实际ClientId"; options.ClientSecret = "你的实际ClientSecret"; options.Authority = "https://ourOIDCServer/ourOIDCServerwebsso/oauth2/multiauth"; options.GetClaimsFromUserInfoEndpoint = true; options.RequireHttpsMetadata = true; options.TokenEndpointAuthenticationMethod = OpenIdConnectClientAuthenticationMethod.Basic.ToString(); options.Scope.Clear(); options.Scope.Add("openid"); options.Scope.Add("uid"); options.Scope.Add("isMemberOf"); options.SaveTokens = true; options.Events = new OpenIdConnectEvents { OnRedirectToIdentityProvider = context => { context.ProtocolMessage.SetParameter("acr_values","ourACR"); context.ProtocolMessage.SetParameter("authlevel", "3"); return Task.CompletedTask; } }; });
内容的提问来源于stack exchange,提问作者Guillaume Carpentier
相关产品推荐
相关产品推荐

