我有一个操作TopSecret()
,它已应用安全策略:
[Authorize(Policy = "Level2SecurityClearance")]
public IActionResult TopSecret()
我可以通过执行此操作来检查用户是否符合政策要求(authorizationService
类型为IAuthorizationService
)
bool isAuthorised = await authorizationService.AuthorizeAsync(User, "Level2SecurityClearance");
此操作可能会在将来某个时候应用不同的策略,我不希望找到我生成链接的所有位置并更新代码。是否可以测试用户是否可以访问特定操作?
也许是这样的:
// Not a real method!!!
bool isAuthorised = authorizationService.IsAuthorisedForAction(User, "TopSecret", "SecretController");
答案 0 :(得分:1)
您应该研究开发需求
以下是使用您的标准的示例:
注意:我假设您使用的是Identity3,而您的用户拥有访问权限
在名为Level2SecurityClearanceRequirement
的新类中public class Level2SecurityClearanceRequirement : AuthorizationHandler<Level2SecurityClearanceRequirement>, IAuthorizationRequirement
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, Level2SecurityClearanceRequirement requirement)
{
if (context.User.HasClaim("TopSecret","yes")
context.Succeed(requirement);
return Task.FromResult(0);
}
}
在您的控制器方法中:
public async Task<IActionResult> BlahBlah() {
if (!await _authorizationService.AuthorizeAsync(User, nameof(PolicyName.Level2SecurityClearance), new Level2SecurityClearanceRequirement()))
return new ChallengeResult();
}
请注意,我在这里使用了nameof(),因此您没有任何魔术字符串,并且所有资源都是集中的。
在这种情况下,我有一个枚举:
public enum PolicyName {
Level2SecurityClearance
}
在您的startup.cs中:
在ConfigureServices方法中
添加以下内容:
services.AddAuthorization(options =>{
options.AddPolicy(nameof(PolicyName.Level2SecurityClearance), policy => { policy.AddRequirements(new Level2SecurityClearanceRequirement()); });
});
然后您可以随意使用此要求,并在要求本身中完成检查
答案 1 :(得分:0)
试试这个。在 ASP.NET Core 1.1
中测试//somewhere in view
@if (await Url.HasAccess(urlActionContext))
{
<p>You have access</p>
}
扩展方法
public static async Task<bool> HasAccess(this IUrlHelper urlHelper, UrlActionContext urlActionContext, string httpMethod = "GET" )
{
var httpContext = urlHelper.ActionContext.HttpContext;
var routeValues = new RouteValueDictionary(urlActionContext.Values);
routeValues["action"] = urlActionContext.Action;
routeValues["controller"] = urlActionContext.Controller;
var path = urlHelper.Action(urlActionContext);
var features = new FeatureCollection();
features.Set<IHttpRequestFeature>(new HttpRequestFeature()
{
Method = httpMethod,
Path = path,
});
var ctx = new DefaultHttpContext(features);
var routeContext = new RouteContext(ctx);
foreach (var entry in routeValues)
{
routeContext.RouteData.Values.Add(entry.Key, entry.Value);
}
var actionSelector = httpContext.RequestServices.GetRequiredService<IActionSelector>();
var provider = httpContext.RequestServices.GetRequiredService<IActionDescriptorCollectionProvider>();
var actionDescriptors = actionSelector.SelectCandidates(routeContext);
var actionDescriptor = actionSelector.SelectBestCandidate(routeContext, actionDescriptors);
var authService = httpContext.RequestServices.GetRequiredService<IAuthorizationService>();
//You need to implement your own AuthorizationHandler that
//checks the actionDescriptor. It will be in AuthorizationHandlerContext.Resource.
//In my case, I have custom Authorize attribute applied to the
//controller action and this attribute is available
//in actionDescriptor.FilterDescriptors
var ok = await authService.AuthorizeAsync(httpContext.User, actionDescriptor, "YOUR_POLICY");
return ok;
}