集成测试中处理HotChocolate授权异常问题
解决HotChocolate测试项目中的授权状态缺失错误
问题描述
测试项目执行GraphQL查询时,触发错误:
"The feature Authorization is missing the state with the key HotChocolate.Authorization.UserState"
根本原因是测试环境中没有可用的ClaimsPrincipal实例,而HotChocolate默认的DefaultAuthorizationHandler依赖用户状态完成授权逻辑。
解决方案
提供两种实用方案,可根据测试场景选择:
方案1:单测请求中注入模拟用户
无需修改服务全局配置,直接在测试请求里添加模拟的用户上下文,适合需要灵活控制不同权限用户的测试场景:
[Fact] public async void FetchProjectAuditMasterActionsAllFields() { // 构造模拟的ClaimsPrincipal var testUser = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, "TestUser"), new Claim(ClaimTypes.Role, "Admin") }, "TestAuthScheme")); var result = await TestServices.ExecuteRequestAsync(b => b.SetQuery("query{...}") .SetContextData(nameof(ClaimsPrincipal), testUser)); result.MatchSnapshot(); }
方案2:全局替换测试用授权处理器
注册自定义授权处理器,在测试环境中自动为所有请求补充默认用户,适合需要统一处理授权的场景:
- 编写自定义授权处理器:
public class TestAuthorizationHandler : DefaultAuthorizationHandler { protected override ValueTask OnBeforeAuthorizeAsync(AuthorizationContext context) { // 若上下文无用户,自动注入模拟用户 if (!context.ContextData.ContainsKey(nameof(ClaimsPrincipal))) { var defaultTestUser = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, "DefaultTestUser") })); context.ContextData.Add(nameof(ClaimsPrincipal), defaultTestUser); } return base.OnBeforeAuthorizeAsync(context); } }
- 修改服务注册代码,替换默认处理器:
Services = new ServiceCollection() .AddGraphQLServer() .AddQueryType<Query>() .AddAuthorization(options => { // 替换默认授权处理器为测试专用版本 options.AddAuthorizationHandler<TestAuthorizationHandler>(); }) // 保留原有的MongoDB相关配置 .AddMongoDbFiltering() .AddMongoDbSorting() .AddMongoDbProjections() .AddMongoDbPagingProviders(); Executor = Services.GetRequiredService<RequestExecutorProxy>();
方案说明
- 方案1的优势是灵活,每个测试可以注入不同权限的用户实例,便于测试多角色场景。
- 方案2的优势是全局统一,无需在每个测试中重复编写用户注入逻辑,适合多数测试只需要基础用户身份的场景。
内容的提问来源于stack exchange,提问作者Claudiu Cojocaru
相关产品推荐
相关产品推荐

