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

.Net Core动态控制器授权策略控制:如何为不同实现指定角色与策略

Alright, let's tackle this problem step by step—since you're working with .NET Core 2 and need to set up differentiated authorization roles/policies for both dynamic controllers and generic controller implementations, here's how you can make it work:

1. Basic Authorization for Non-Generic Dynamic Controllers

If your dynamic controllers are generated explicitly (not via generics), you have two straightforward options:

  • Add the [Authorize] attribute directly when defining or generating the controller type. For example:
    // Dynamically generated controller
    [Authorize(Roles = "InventoryAdmin")]
    public class DynamicInventoryController : ControllerBase
    {
        // Controller actions go here
    }
    
  • Use controller conventions if you want to apply authorization rules across multiple dynamic controllers based on naming or other criteria. You can create a custom IControllerModelConvention to inject authorization filters dynamically.
2. Differentiated Authorization for Generic Controllers

This is where things get nuanced—since you need different rules per generic type parameter, the key is using controller conventions to inspect the generic controller's type and attach the appropriate authorization filter.

Step 1: Define Your Generic Controller

First, set up your base generic controller:

public class GenericCrudController<T> : ControllerBase where T : class
{
    // CRUD actions (Get, Post, Put, Delete) go here
}

Step 2: Register Generic Controller Implementations

In your Startup.cs, register specific generic controller instances (e.g., GenericCrudController<Product>, GenericCrudController<Order>) and configure conventions:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc()
        .AddControllersAsServices()
        .ConfigureApplicationPartManager(apm =>
        {
            // Register your generic controller for target entity types
            var genericControllerType = typeof(GenericCrudController<>);
            
            // Add implementations for Product and Order entities
            foreach (var entityType in new[] { typeof(Product), typeof(Order) })
            {
                var concreteControllerType = genericControllerType.MakeGenericType(entityType);
                apm.ApplicationParts.Add(new AssemblyPart(concreteControllerType.Assembly));
                apm.FeatureProviders.Add(new GenericControllerFeatureProvider(entityType));
            }
        })
        // Attach our custom authorization convention
        .ConfigureConventions(conventions =>
        {
            conventions.Add(new GenericControllerAuthorizationConvention());
        });

    // Optional: Register named authorization policies for reusability
    services.AddAuthorization(options =>
    {
        options.AddPolicy("ProductManagement", policy => policy.RequireRole("ProductAdmin", "Editor"));
        options.AddPolicy("OrderManagement", policy => policy.RequireRole("OrderAdmin", "Manager"));
    });
}

Step 3: Create the Custom Authorization Convention

This convention will inspect each controller, check if it's a generic instance, and apply rules based on the generic type parameter:

public class GenericControllerAuthorizationConvention : IControllerModelConvention
{
    public void Apply(ControllerModel controller)
    {
        // Skip non-generic controllers
        if (!controller.ControllerType.IsGenericType)
            return;

        var genericEntityType = controller.ControllerType.GetGenericArguments()[0];

        // Apply role/policy based on the entity type
        if (genericEntityType == typeof(Product))
        {
            // Option 1: Direct role requirement
            controller.Filters.Add(new AuthorizeFilter(new AuthorizationPolicyBuilder()
                .RequireRole("ProductAdmin")
                .Build()));
            
            // Option 2: Use a pre-defined policy (from Startup.cs)
            // controller.Filters.Add(new AuthorizeFilter("ProductManagement"));
        }
        else if (genericEntityType == typeof(Order))
        {
            controller.Filters.Add(new AuthorizeFilter(new AuthorizationPolicyBuilder()
                .RequireRole("OrderAdmin")
                .Build()));
        }
        // Add more cases for other entity types as needed
    }
}

Step 4: Implement GenericControllerFeatureProvider (Optional)

Customize how your generic controllers are discovered by MVC with this feature provider:

public class GenericControllerFeatureProvider : IControllerFeatureProvider
{
    private readonly Type _entityType;

    public GenericControllerFeatureProvider(Type entityType)
    {
        _entityType = entityType;
    }

    public bool IsController(TypeInfo typeInfo)
    {
        return typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(GenericCrudController<>)
               && typeInfo.GetGenericArguments()[0] == _entityType;
    }
}

This approach ensures each generic controller instance gets the exact authorization rules it needs, whether you're using direct role checks or named policies.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:23:12