C# 为全局上所有控制器和操作的自定义策略设置授权属性
我是.Net/ASP.Net开发的新手,我正在尝试使用我想在全局级别添加的自定义策略,这样我就不必为我构建的策略在每个控制器中添加[C# 为全局上所有控制器和操作的自定义策略设置授权属性,c#,asp.net-core,asp.net-core-mvc,C#,Asp.net Core,Asp.net Core Mvc,我是.Net/ASP.Net开发的新手,我正在尝试使用我想在全局级别添加的自定义策略,这样我就不必为我构建的策略在每个控制器中添加[Authorize]属性 我创建了一个名为SuperAdminUsers的策略,并使用UserNamesRequirement中的自定义需求,我希望将其设置为全局级别,这样所有SuperAdminUsers都可以访问所有控制器和操作 下面是我在startup.cs文件中创建的策略 services.AddAuthorization( option =
Authorize
]属性
我创建了一个名为SuperAdminUsers
的策略,并使用UserNamesRequirement
中的自定义需求,我希望将其设置为全局级别,这样所有SuperAdminUsers
都可以访问所有控制器和操作
下面是我在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));
}
);
在上面的config.Filters
中,我得到一个错误,如下面的屏幕截图所示:
以下是我的客户要求和处理类:
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);
}
更新1:
使用以下代码更新启动文件,但仍无法授权
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));
}
);
我正在尝试访问的控制器:
[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());
}
}
非常感谢您的帮助。过滤器是为所有控制器和操作设置授权属性的一种方法。例如,以下是需要特定用户名的策略
services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireUserName("DOMAIN\\USERID")
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
});
您收到的错误是因为AuthorizationFilter
构造函数需要策略
而不是策略生成器
。这是您的代码,为了更清晰,更改了变量名
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));
});
为所有控制器创建一个基类,并仅为该类设置[Authorize]。因此,我创建了一个基类并添加了Authorize,我只是将它添加到所有控制器中,就像这样
公共类SearchController:controller,BaseAuth{}
?我的意思是这个BaseController:controller,你的控制员:BaseController可能是Thank you Shaun的副本。这很有帮助,但是我如何实现我用来利用自定义handler
和requirement
类的自定义策略呢?我在问题中添加了更多细节,但出现了错误。@rayBuild()
方法返回一个策略。它不会将策略生成器
更改为策略
。我的编辑可能会为你澄清这一点。啊。。现在这是有道理的谢谢你花时间给我解释。我真的很感谢你的帮助。。看起来筛选不起作用。我尝试访问的一个控制器的页面为403页。它可能是操作系统控制器
的控制器的顶级[Authorize]
属性吗?我从另一个控制器中删除了所有[Authorize]
,它正在工作。
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));
});