测试项目中HotChocolate授权异常:缺失UserState状态
问题场景
测试项目执行GraphQL查询时触发上述错误,已在TestExecutorHelper中调用.AddAuthorization()和.AddAuthorizePermissions(),但问题未解决。相关代码如下:
IRequestExecutorBuilder requestExecutor = serviceCollection .AddAuthorization() .AddLogging() .AddGraphQL() .AddAuthorization() .AddAuthorizePermissions() .AddErrorFilter<ErrorFilter>() .AddQueryType<QueryType>(); var serviceProvider = requestExecutor.Services.BuildServiceProvider(); var request = QueryRequestBuilder.New() .SetQuery(query) .SetServices(serviceProvider) .Create(); var executor = await requestExecutor.BuildRequestExecutorAsync(); return await executor.ExecuteAsync(request);
问题根源
HotChocolate的授权功能依赖UserState存储用户身份与权限数据,但当前测试代码仅构建了服务提供者,未在GraphQL请求上下文中注入有效的用户身份(ClaimsPrincipal),导致授权模块无法找到所需的状态数据。
修复方案
1. 注入模拟用户身份到请求上下文
在构建QueryRequest时,添加模拟的ClaimsPrincipal到请求上下文数据中,示例代码如下:
IRequestExecutorBuilder requestExecutor = serviceCollection .AddAuthorization() .AddLogging() .AddGraphQL() .AddAuthorization() .AddAuthorizePermissions() .AddErrorFilter<ErrorFilter>() .AddQueryType<QueryType>(); var serviceProvider = requestExecutor.Services.BuildServiceProvider(); // 构建模拟用户身份,按需添加权限声明 var testClaims = new List<Claim> { new Claim(ClaimTypes.NameIdentifier, "1"), new Claim(ClaimTypes.Name, "test-user"), new Claim("permissions", "query:data") // 替换为你的权限标识 }; var testUser = new ClaimsPrincipal(new ClaimsIdentity(testClaims, "test-auth-scheme")); var request = QueryRequestBuilder.New() .SetQuery(query) .SetServices(serviceProvider) // 将用户身份注入请求上下文 .SetContextData(nameof(ClaimsPrincipal), testUser) .Create(); var executor = await requestExecutor.BuildRequestExecutorAsync(); return await executor.ExecuteAsync(request);
2. (可选)使用HotChocolate测试扩展简化配置
如果项目引用了HotChocolate.Testing包,可以直接使用AddUser方法快速注入用户身份:
// 替换原请求构建代码 var request = QueryRequestBuilder.New() .SetQuery(query) .SetServices(serviceProvider) .AddUser(testUser) // 直接添加用户身份 .Create();
3. 清理冗余配置
代码中重复调用了.AddAuthorization()(ASP.NET Core授权与GraphQL授权各一次),可以保留其中一个即可,避免冗余配置。
核心说明
测试场景下,HotChocolate无法自动获取用户身份,必须显式为每个GraphQL请求注入有效的ClaimsPrincipal,授权模块才能基于此填充UserState,完成权限校验。
内容的提问来源于stack exchange,提问作者Miguel Morgado
相关产品推荐
相关产品推荐

