Asp.net core IAuthorizationPolicyProvider:我可以使用多个政策提供者,还是必须考虑一个一般政策提供者内部的所有案例?

Asp.net core IAuthorizationPolicyProvider:我可以使用多个政策提供者,还是必须考虑一个一般政策提供者内部的所有案例?,asp.net-core,.net-core,asp.net-core-3.0,.net-core-3.0,Asp.net Core,.net Core,Asp.net Core 3.0,.net Core 3.0,在我的节目里我想 检查用户是否在某个用户表中注册了所有可能的操作 对于某些操作,我还想检查用户是否具有适当的CRUD权限 我用以下代码检查启动中的第一个条件: services.AddAuthorization(options => { // This policy checks if a user is registered in our Users table. options.AddPolicy( "UserIsRegistered",

在我的节目里我想

  • 检查用户是否在某个用户表中注册了所有可能的操作
  • 对于某些操作,我还想检查用户是否具有适当的CRUD权限
  • 我用以下代码检查
    启动
    中的第一个条件

    services.AddAuthorization(options =>
    {
        // This policy checks if a user is registered in our Users table.
        options.AddPolicy(
            "UserIsRegistered",
            new AuthorizationPolicyBuilder()
                .AddRequirements(new RegistrationRequirement())
                .Build());
    });
    
    我还要补充一点

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers().RequireAuthorization("UserIsRegistered");
    });
    
    我相应地定义了
    RegistrationRequirement
    RegistrationAuthorizationHandler

    对于第二个条件,我使用其
    CrudAuthorizationHandler
    创建了一个属性
    crudauthorizationattribute
    。由于每个可能的Crud操作都有一个不同的警察,因此我创建了一个
    CrudPolicyProvider

    然后我在
    启动
    中注册了所有内容:

    services.AddTransient<IAuthorizationHandler, RegistrationAuthorizationHandler>();
    services.AddTransient<IAuthorizationHandler, CrudAuthorizationHandler>();
    services.AddTransient<IAuthorizationPolicyProvider, CrudPolicyProvider>();
    
    并且仅在需要时使用每一个

    • 如果答案是,是否意味着我必须定义一个
      通用政策提供者
      ,并在此提供者中根据我的情况检查每次必须提供哪些政策?(类似于使用
      策略\u前缀
      ?)
    谢谢

    我可以定义两个策略提供程序(就像我可以使用IAuthorizationHandler一样)并仅在需要时使用每一个吗

    你可以。但这两个独立的策略提供程序不会相应地被激活。您可能有多个策略提供程序,但同时只能使用其中一个。使用
    IAuthorizationPolicyProvider
    也没有什么神奇之处

    定义单个GeneralPolicyProvider。。。。根据我的情况,检查每次我必须提供哪些政策?(类似于在此处使用POLICY_前缀?)

    对。但您不必在任何地方都使用Policy_前缀。这样你会重复太多次

    更好的方法是将
    IHttpContextAccessor
    服务注入
    GeneralPolicyProvider
    ,这样您可以在运行时检查当前
    端点
    /
    HttpContext
    ,然后可以动态解析目标策略提供程序

    实现如下所示:

    公共类GenericPolicyProvider:IAAuthorizationPolicyProvider
    {
    专用只读IHttpContextAccessor\u httpContextAccessor;
    私有授权选项_authZOpts{get;}
    public DefaultAuthorizationPolicyProvider FallbackPolicyProvider{get;}
    私有IAuthorizationPolicyProvider_fstpolicProvider{get;set;}
    私有IAuthorizationPolicyProvider\u sndpolicProvider{get;set;}
    公共GenericPolicyProvider(IHttpContextAccessor httpContextAccessor,IOOptions)
    {
    这。httpContextAccessor=httpContextAccessor;
    这._authZOpts=options.Value;
    this.FallbackPolicyProvider=新的DefaultAuthorizationPolicyProvider(选项);
    此.fstpolicProvider=新的FirstPolicyProvider(options.Value);
    此._sndpolicProvider=新的SecondPolicyProvider(options.Value);
    }
    //使用目标提供程序提供策略
    公共任务GetPolicyAsync(字符串policyName)
    {
    var targetPolicyProvider=this.GetPolicyProvider(policyName);
    返回targetPolicyProvider.GetPolicyAsync(policyName);
    }
    //动态获取目标提供程序
    私有IAAuthorizationPolicyProvider GetPolicyProvider(字符串policyName)
    {
    var httpContext=this.\u httpContextAccessor.httpContext;
    如果(httpContext==null)抛出新异常(“httpContext不能为null”);
    //现在您得到了HttpContext
    //检查HttpContext以确定应使用哪个策略提供程序
    // ...
    //或者检查端点,例如,通过endpoint.Metadata.GetMetadata()获取标记过滤器
    var endpoint=httpContext.GetEndpoint();
    var someMarker=endpoint.Metadata.GetMetadata();
    //简而言之,动态解析策略提供程序:
    if(shouldUseFirstPolicyProvider())
    返回此文件。\ fstpolicProvider;
    else if(应使用SecondPolicyProvider())
    把这个还给我;
    其他的
    返回此。FallbackPolicyProvider;
    }
    ...
    }
    
    最后,不要忘记在启动时注册这个GenericPolicyProvider

    services.AddTransient<IAuthorizationPolicyProvider, FirstPolicyProvider>();
    services.AddTransient<IAuthorizationPolicyProvider, SecondPolicyProvider>();