首页 > 解决方案 > Environment dependent controller with [Authorize]

问题描述

To mark a controller as requiring authorization you typically decorate it like this:

[Authorize]
public class MyController : Controller

Our auth is through a 3rd party provider and given the way it is setup, we only want this to actually be in effect in our production environment, we don't want it to be active in QA environment for example. It's easy to toggle off environment in the Startup.cs file but is there a way to conditionally decorate the controllers? I started looking at policies and roles and that seem like it might be hacked to work but is there a better way?

标签: c#asp.netcontrollerauthorization

解决方案


如果您使用的是 Asp.NET Core,请遵循此处的文档:

https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-2.1 https://docs.microsoft.com/en-us/aspnet/core/security/authorization /dependencyinjection?view=aspnetcore-2.1

您可以像这样制定自定义策略:

public class EnvironmentAuthorize : IAuthorizationRequirement
{
    public string Environment { get; set; }

    public EnvironmentAuthorize(string env)
    {
        Environment = env;
    }
}

public class EnvironmentAuthorizeHandler : AuthorizationHandler<EnvironmentAuthorize>
{
    private readonly IHostingEnvironment envionment;

    public EnvironmentAuthorizeHandler(IHostingEnvironment env)
    {
        envionment = env;
    }

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, EnvironmentAuthorize requirement)
    {
        if (requirement.Environment != envionment.EnvironmentName)
        {
            context.Succeed(requirement);
        }

        return Task.CompletedTask;
    }
}

在 de Startup.cs 中:

        services.AddAuthorization(options =>
        {
            options.AddPolicy("ProductionOnly", policy =>
                policy.Requirements.Add(new EnvironmentAuthorize("Production")));
        });

        services.AddSingleton<IAuthorizationHandler, EnvironmentAuthorizeHandler>();

在控制器中:

[Authorize(Policy = "ProductionOnly")]
public class MyController : Controller

虽然有可能,但我不推荐这样做,在不同的环境中有不同的行为确实是一场噩梦。


推荐阅读