OpenIddict中options.DisableScopeValidation()未禁用范围验证
我无法让options.DisableScopeValidation()生效。以下是我的代码:
// OpenIddict builder.Services.AddOpenIddict() .AddCore(options => { options.UseEntityFrameworkCore().UseDbContext<ApplicationDbContext>(); }) .AddServer(options => { // Flow options .AllowAuthorizationCodeFlow().RequireProofKeyForCodeExchange() .AllowClientCredentialsFlow() .AllowRefreshTokenFlow(); options.SetAuthorizationEndpointUris("/connect/authorize"); // 用户在VentureAuth登录的流程 options.SetTokenEndpointUris("/connect/token"); // Token端点:客户端在此请求令牌 options.SetUserinfoEndpointUris("/connect/userinfo"); // 如果需要读取access token,可以禁用其加密 options .AddEphemeralEncryptionKey() .AddEphemeralSigningKey() .DisableAccessTokenEncryption(); //options.RegisterScopes("api"); options .UseAspNetCore() .EnableTokenEndpointPassthrough() .EnableAuthorizationEndpointPassthrough() .EnableUserinfoEndpointPassthrough(); options.DisableScopeValidation(); });
当我不发送任何scope时可以获取令牌,但发送未定义的scope时,会收到错误:
error:invalid_request error_description:This client application is not allowed to use the specified scope. error_uri:https://documentation.openiddict.com/errors/ID2051
解决方案
问题根源是你启用了**端点直通(Passthrough)**功能:EnableTokenEndpointPassthrough()、EnableAuthorizationEndpointPassthrough()这类方法会让OpenIddict将请求转交给自定义控制器处理,此时全局配置的DisableScopeValidation()不会生效——因为直通模式会跳过OpenIddict默认的验证逻辑,需要你手动控制验证规则。
你有两种解决方式:
1. 移除端点直通配置
如果不需要自行处理令牌/授权端点的业务逻辑,直接删除.EnableTokenEndpointPassthrough()、.EnableAuthorizationEndpointPassthrough()、.EnableUserinfoEndpointPassthrough()这几行代码。此时DisableScopeValidation()会正常生效,OpenIddict会用自身逻辑处理请求,不再校验scope的合法性。
2. 在直通控制器中手动禁用scope验证
如果必须保留直通模式,需要在对应端点的控制器中,针对当前请求禁用scope验证:
[HttpPost("connect/token")] [Produces("application/json")] public async Task<IActionResult> Exchange() { var request = HttpContext.GetOpenIddictServerRequest() ?? throw new InvalidOperationException("无法获取OpenIddict请求"); // 禁用当前请求的scope验证 request.DisableScopeValidation(); // 你的其他令牌处理逻辑... }
额外注意:如果你的客户端在数据库(如OpenIddictApplications表)中配置了允许的scope列表(Permissions字段),即使启用DisableScopeValidation(),仍会触发ID2051错误。这种情况下,需要移除客户端的scope权限限制,或者确保客户端配置允许所有需要的scope。
内容的提问来源于stack exchange,提问作者Purr Miaw

