.NET Core API控制器中如何获取IdentityServer4的OAuth认证流程类型
解决方案
IdentityServer4默认不会将OAuth授权流程类型(grant_type)写入发放的AccessToken,所以需要先在IdentityServer服务端将该值注入为自定义Claim,之后API侧即可从当前用户的Claims中直接读取。
1. IdentityServer端配置自定义Claim注入
实现ICustomTokenRequestValidator接口,在Token发放前将当前请求的授权类型添加到ClientClaims中:
using IdentityServer4.Validation; using System.Security.Claims; public class CustomGrantTypeTokenValidator : ICustomTokenRequestValidator { public Task ValidateAsync(CustomTokenRequestValidationContext context) { context.Result.ValidatedRequest.ClientClaims.Add( new Claim("grant_type", context.Result.ValidatedRequest.GrantType) ); return Task.CompletedTask; } }
在IdentityServer的服务注册逻辑中注入该验证器:
// .NET 6+ Program.cs 示例 builder.Services.AddIdentityServer() // 原有IdentityServer配置(如AddInMemoryClients、AddAspNetIdentity等)保持不变 .AddCustomTokenRequestValidator<CustomGrantTypeTokenValidator>();
2. API端配置JWT认证
确保JWT认证中间件不会过滤自定义Claim,关闭默认的入站Claim映射:
builder.Services.AddAuthentication("Bearer") .AddJwtBearer("Bearer", options => { options.Authority = "你的IdentityServer服务地址"; options.Audience = "你的API资源标识"; // 保留原始Claim类型,避免自定义Claim被重命名或过滤 options.MapInboundClaims = false; });
3. 控制器中读取授权流程类型
直接从ClaimsPrincipal(即User属性)中读取grant_type声明即可:
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using IdentityServer4.Models; [ApiController] [Route("api/[controller]")] [Authorize] public class DemoController : ControllerBase { public IActionResult Get() { var currentGrantType = User.FindFirstValue("grant_type"); if (currentGrantType == GrantType.ClientCredentials) { // 执行客户端凭证流程对应的业务逻辑 return Ok("当前使用客户端凭证流程"); } else if (currentGrantType == GrantType.AuthorizationCode) { // 执行授权码流程对应的业务逻辑 return Ok("当前使用授权码流程"); } // 其他流程(密码模式、设备码流程等)可按相同方式判断 return BadRequest("不支持的授权流程"); } }
补充说明
- 若不方便修改IdentityServer端配置,也可通过当前请求的AccessToken调用IdentityServer的自省端点查询完整授权信息,但该方案会产生额外的跨服务调用,性能较低,不适合高并发接口使用。
- 刷新令牌请求生成的新AccessToken会自动继承原始授权请求的grant_type值,无需额外适配。
- 生产环境可对读取到的grant_type做非空校验,避免异常请求导致逻辑错误。
内容的提问来源于stack exchange,提问作者Alexu
相关产品推荐
相关产品推荐

