单元测试中Hot Chocolate授权异常排查(OperationRequestBuilder替代)
解决Hot Chocolate最新版本单元测试中的授权异常问题
问题原因分析
- 直接通过
schema.MakeExecutable()创建的执行器未完整加载授权相关服务配置,导致授权逻辑无法正常运行 ClaimsIdentity未指定认证类型,部分授权逻辑会将其判定为未认证身份- 使用
AddGlobalState传递ClaimsPrincipal的方式不符合最新版Hot Chocolate的上下文传递规范
修复后的完整代码
var services = new ServiceCollection(); // 先添加Microsoft授权基础服务,这是Hot Chocolate授权功能的依赖前提 services.AddAuthorization(); // 构建完整的RequestExecutor,确保所有服务(包括授权组件)被正确初始化 var executor = await services .AddGraphQLServer() .ModifyRequestOptions(opt => opt.IncludeExceptionDetails = true) .ModifyCostOptions(x => x.EnforceCostLimits = false) .AddAuthorization() .AddQueryType(q => q.Name("Query")) .AddType<Query>() .AddFiltering() .BuildRequestExecutorAsync(); var query = @"{}"; var request = OperationRequestBuilder.New() .SetDocument(query) // 将ClaimsPrincipal添加到请求上下文数据中,这是授权逻辑读取身份的正确方式 .AddContextData(nameof(ClaimsPrincipal), CreatePrincipal()) .Build(); var result = await executor.ExecuteAsync(request); result.MatchSnapshot(); private static ClaimsPrincipal CreatePrincipal() { // 为ClaimsIdentity指定认证类型,确保身份被标记为已认证状态 var claimIdentity = new ClaimsIdentity( new[] { new Claim("appid", "appid") }, "TestAuthentication" ); return new ClaimsPrincipal(claimIdentity); }
额外优化选项
如果你安装了HotChocolate.Testing NuGet包,可以使用更简洁的扩展方法传递身份:
var principal = CreatePrincipal(); var request = OperationRequestBuilder.New() .SetDocument(query) .WithClaimsPrincipal(principal) // 测试包提供的扩展方法,代码更直观 .Build();
验证要点
- 确认
Query类型或字段上的[Authorize]属性要求的Claim与CreatePrincipal中添加的Claim一致 - 确保服务集合已正确注册授权服务,避免出现授权组件缺失的异常
内容的提问来源于stack exchange,提问作者v-chkulkarni
相关产品推荐
相关产品推荐

