简体   繁体   English

为所有控制器的自定义策略和全局的操作设置authorize属性

[英]Set authorize attribute for Custom policy for all controller and Actions at global

I am new to .Net / ASP.NET development and I am trying to use custom policy that I would like to add at the global level so that I don't have to add [ Authorize ] attribute in each controller for a policy I built. 我是.Net / ASP.NET开发的新手,我正在尝试使用我想在全局级别添加的自定义策略,这样我就不必在每个控制器中为我构建的策略添加[ Authorize ]属性。

I created a policy called SuperAdminUsers and uses custom requirement from UserNamesRequirement which I would like to set it at the global level, that way all SuperAdminUsers will have access to all controller and actions. 我创建了一个名为SuperAdminUsers的策略,并使用UserNamesRequirement中的自定义要求,我想在全局级别设置它,这样所有SuperAdminUsers都可以访问所有控制器和操作。

Below is my policy that I have created in startup.cs file. 以下是我在startup.cs文件中创建的策略。

services.AddAuthorization(
        option =>
        {
            option.AddPolicy("Admin", policy => policy.RequireRole("DOMAIN\\GroupName"));
            option.AddPolicy("SuperAdminUsers", policy => policy.Requirements.Add(new UserNamesRequirement("DOMAIN\\USER1", "DOMAIN\\USER2"))
        }
);
// Add Custom filters
services.AddMvc(
    config =>
    {
        var policy = new AuthorizationPolicyBuilder();
        policy.Requirements.Add(new UserNamesRequirement("DOMAIN\\USER1"));
                policy.Build();
                config.Filters.Add(new AuthorizeFilter(policy));
    }
);

In config.Filters above, I get an error shown in below screenshot: 在上面的config.Filters ,我收到以下屏幕截图中显示的错误:

在此输入图像描述

Here is my Customer Requirement and Handle classes: 这是我的客户要求和处理类:

public class UserNamesRequirement : IAuthorizationRequirement
{
    public UserNamesRequirement(params string[] UserNames)
    {
        Users = UserNames;
    }
    public string[] Users { get; set; }
}

protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, UserNamesRequirement requirement)
{
        // var userName = context.User.FindFirst(ClaimTypes.NameIdentifier).Value;
        var userName = context.User.Identity.Name;

        if (requirement.Users.ToList().Contains(userName))
            context.Succeed(requirement);
        return Task.FromResult(0);
}

UPDATE 1: 更新1:

Update start up file with below code, but still unable to authorize. 使用以下代码更新启动文件,但仍无法授权。

services.AddMvc
        (
            config =>
            {
                var policyBuilder = new AuthorizationPolicyBuilder();
                policyBuilder.Requirements.Add(new UserNamesRequirement("DOMAIN\\USER1", "DOMAIN\\USER2"));
                var policy = policyBuilder.Build();
                config.Filters.Add(new AuthorizeFilter(policy));
            }
        );

Controller I am trying to access: 控制器我试图访问:

[Authorize(Policy = "Admins")]
[Authorize(Policy = "SuperAdminUsers")]
public class OperatingSystemsController : Controller
{
    private readonly ServerMatrixDbContext _context;

    public OperatingSystemsController(ServerMatrixDbContext context)
    {
        _context = context;    
    }

    // GET: OperatingSystems
    public async Task<IActionResult> Index()
    {
        return View(await _context.OperatingSystems.ToListAsync());
    }
}

Here is what I see it in str output log file: 这是我在str输出日志文件中看到的内容:

NOTE: I removed real domain and username. 注意:我删除了真实域名和用户名。

Application started. Press Ctrl+C to shut down.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost/demo/OperatingSystems/Create  
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[1]
      Authorization was successful for user: DOMAIN\USER1.
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
      Authorization failed for user: DOMAIN\USER1.
warn: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
      Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
info: Microsoft.AspNetCore.Mvc.ChallengeResult[1]

Any help is really appreciated. 任何帮助都非常感谢。

A filter is one way to set the authorization attribute for all controllers and actions. 过滤器是为所有控制器和操作设置授权属性的一种方法。 For instance, here is policy that requires a specific user name. 例如,这是需要特定用户名的策略。

services.AddMvc(config =>
{
    var policy = new AuthorizationPolicyBuilder()
                     .RequireUserName("DOMAIN\\USERID")
                     .Build();

    config.Filters.Add(new AuthorizeFilter(policy));
});

The error you're receiving happens because the AuthorizationFilter constructor expects a policy not a policyBuilder . 您收到的错误是因为AuthorizationFilter构造函数需要policy而不是policyBuilder Here is your code with the variable names changed for greater clarity. 以下是更改变量名称的代码,以便更清晰。

services.AddMvc(config =>
{
    var policyBuilder = new AuthorizationPolicyBuilder();
    policyBuilder.Requirements.Add(new UserNamesRequirement("DOMAIN\\USER1"));

    // this will NOT work
    policyBuilder.Build();
    config.Filters.Add(new AuthorizeFilter(policyBuilder));

    // this will work
    var policy = policyBuilder.Build();
    config.Filters.Add(new AuthorizeFilter(policy));

});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM