You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ASP.NET层为类库中的EF Core实体添加HotChocolate授权特性

解决方案:在ASP.NET层为EF Core模型添加HotChocolate授权

方案1:使用HotChocolate类型扩展(推荐)

这是最贴合HotChocolate设计理念的方案,完全不需要在EF类库中引入HotChocolate依赖。你可以在ASP.NET项目中创建类型扩展类,为EF模型补加授权规则:

using HotChocolate.Authorization;
using YourClassLibrary.Models; // 引用EF模型所在的类库

public class OrganisationTypeExtension : ObjectTypeExtension<Organisation>
{
    protected override void Configure(IObjectTypeDescriptor<Organisation> descriptor)
    {
        // 为整个实体类添加授权策略
        descriptor.Authorize("some-policy-name");

        // 若需单独为某个字段设置授权,可单独配置
        descriptor.Field(o => o.Name)
                  .Authorize("another-policy");
    }
}

随后在Program.cs中注册这个扩展:

builder.Services.AddGraphQLServer()
    .AddQueryType(q => q.Name("Query"))
    .AddTypeExtension<OrganisationTypeExtension>() // 注册类型扩展
    .AddAuthorization();

方案2:自定义元数据+授权拦截器

如果需要更灵活的跨层授权标记,可以先在EF类库中用自定义特性标记需要授权的类型/字段,再在ASP.NET层通过拦截器读取元数据并应用授权规则:

  1. 在EF类库中定义自定义标记特性:
// EF类库内代码,无HotChocolate依赖
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property)]
public class RequirePolicyAttribute : Attribute
{
    public string PolicyName { get; }

    public RequirePolicyAttribute(string policyName)
    {
        PolicyName = policyName;
    }
}

// 用自定义特性标记EF模型
[RequirePolicy("some-policy-name")]
public class Organisation
{
    public int Id { get; set; }

    [RequirePolicy("another-policy")]
    public string Name { get; set; } = null!;
}
  1. 在ASP.NET项目中创建授权拦截器:
using HotChocolate.Authorization;
using HotChocolate.Types;
using System.Reflection;
using YourClassLibrary.Models;
using YourClassLibrary.Attributes;

public class CustomAuthorizationInterceptor : IAuthorizationInterceptor
{
    public void OnBeforeAuthorization(AuthorizationContext context)
    {
        // 处理类型级授权
        if (context.Type is ObjectType objectType)
        {
            var policyAttr = objectType.RuntimeType.GetCustomAttribute<RequirePolicyAttribute>();
            if (policyAttr != null)
            {
                context.RequirePolicy(policyAttr.PolicyName);
            }
        }

        // 处理字段级授权
        if (context.Field is IObjectField field)
        {
            var property = field.Member as PropertyInfo;
            if (property != null)
            {
                var policyAttr = property.GetCustomAttribute<RequirePolicyAttribute>();
                if (policyAttr != null)
                {
                    context.RequirePolicy(policyAttr.PolicyName);
                }
            }
        }
    }

    public void AfterAuthorization(AuthorizationContext context)
    {
        // 无额外逻辑可留空
    }
}
  1. 在Program.cs中注册拦截器:
builder.Services.AddGraphQLServer()
    .AddQueryType(q => q.Name("Query"))
    .AddAuthorization(options =>
    {
        options.Interceptors.Add<CustomAuthorizationInterceptor>();
    })
    .AddType<Organisation>();

方案3:手动映射GraphQL类型(不推荐)

你也可以在ASP.NET项目中手动创建对应EF模型的GraphQL类型,并在映射时直接添加授权特性,但这种方式需要手动维护字段映射,后续模型变更时容易遗漏:

using HotChocolate.Authorization;
using YourClassLibrary.Models;

public class OrganisationType : ObjectType<Organisation>
{
    protected override void Configure(IObjectTypeDescriptor<Organisation> descriptor)
    {
        descriptor.Authorize("some-policy-name");
        
        descriptor.Field(o => o.Id).Type<IntType>();
        descriptor.Field(o => o.Name).Type<StringType>().Authorize("another-policy");
    }
}

注册这个类型:

builder.Services.AddGraphQLServer()
    .AddQueryType(q => q.Name("Query"))
    .AddType<OrganisationType>()
    .AddAuthorization();

内容的提问来源于stack exchange,提问作者baouss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 13:02:28