.NET中禁用GraphQL Introspection求助(graphql-dotnet v3)
在graphql-dotnet v3中禁用GraphQL Introspection的解决方案
无需升级v7:v3版本的可行方案
你之前尝试的自定义Schema Filter未生效,大概率是因为实现方式不符合v3版本的API要求。v3的ISchemaFilter接口的Apply方法是无返回值的,无法通过返回false来禁用 introspection,可通过以下两种方式实现:
方案1:通过Schema Filter移除 introspection 相关类型
创建自定义Schema Filter,直接从Schema中删除所有以__开头的 introspection 类型,同时移除根查询类型中的__schema和__type字段:
public class DisableIntrospectionFilter : ISchemaFilter { public void Apply(ISchema schema) { // 移除所有introspection内置类型 var introspectionTypes = schema.AllTypes.Where(t => t.Name.StartsWith("__")).ToList(); foreach (var type in introspectionTypes) { schema.AllTypes.Remove(type.Name); } // 移除根查询类型中的introspection字段 if (schema.QueryType is ObjectGraphType queryType) { queryType.Fields.Remove("__schema"); queryType.Fields.Remove("__type"); } } }
注册该Filter到你的Schema实例:
var schema = new Schema(new FuncDependencyResolver(type => /* 依赖解析逻辑 */)) { Query = /* 你的查询类型 */, Mutation = /* 你的突变类型(如果有) */ }; schema.Filters.Add(new DisableIntrospectionFilter());
方案2:通过验证规则拦截 introspection 查询
创建自定义验证规则,在查询执行前检测并拦截包含__schema或__type字段的请求:
public class DisableIntrospectionValidationRule : IValidationRule { public INodeVisitor Validate(ValidationContext context) { return new EnterLeaveListener(listener => { listener.Match<Field>(fieldAst => { var fieldName = fieldAst.Name.Value; if (fieldName is "__schema" or "__type") { context.ReportError(new ValidationError( context.Document, "introspection-disabled", "Introspection is disabled")); } }); }); } }
执行查询时添加该验证规则:
var executionResult = await new DocumentExecuter().ExecuteAsync(options => { options.Schema = schema; options.Query = requestQuery; // 合并默认验证规则与自定义规则 options.ValidationRules = DocumentValidator.CoreRules.Concat(new[] { new DisableIntrospectionValidationRule() }); });
是否需要升级到v7?
v7版本提供了更简洁的原生支持,无需自定义实现:
- 方式1:在Schema配置中直接禁用
var schema = new Schema(config => { config.IntrospectionEnabled = false; // 其他Schema配置 });
- 方式2:在查询执行器选项中禁用
var executionResult = await new DocumentExecuter().ExecuteAsync(options => { options.Schema = schema; options.Query = requestQuery; options.EnableIntrospection = false; });
如果你的项目架构允许升级,v7的原生方案更简洁可靠,还能获得其他功能更新和bug修复;如果暂时无法升级,使用上述v3的两种方案即可解决问题。
内容的提问来源于stack exchange,提问作者Ariel Serato
相关产品推荐
相关产品推荐

