在 .NET Core 1.0 MVC 的视图中使用授权策略的任何方式?
Posted
技术标签:
【中文标题】在 .NET Core 1.0 MVC 的视图中使用授权策略的任何方式?【英文标题】:Any way to use Authorization Policies in a view in .NET Core 1.0 MVC? 【发布时间】:2016-03-17 18:17:42 【问题描述】:我知道在控制器中,您可以毫无问题地编写[Authorize("policyName")]
,但是有没有办法在视图中使用策略?我不想每次我想授权一些 html 时都使用User.IsInRole(...)
。
编辑:
这里有一些代码
Startup.cs -- 政策声明
services.AddAuthorization(options =>
options.AddPolicy("testPolicy", policy =>
policy.RequireAuthenticatedUser()
.RequireRole("RoleOne", "RoleTwo", "RoleThree")
.RequireClaim(ClaimTypes.Email);
);
);
管理员控制器
[Authorize("testPolicy")]
public class AdminController : Controller
public IActionResult Index()
return View();
导航栏 HTML
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a asp-controller="Home" asp-action="Index">Home</a></li>
<!-- I want to implement my policy here. -->
@if (User.IsInRole("..."))
<li><a asp-controller="Admin" asp-action="Index">Admin</a></li>
</ul>
@await Html.PartialAsync("_LoginPartial")
</div>
</div>
【问题讨论】:
我对您为什么需要这个以及您的确切意思感到困惑?您能否在您的帖子中发布一些示例代码。您可以在控制器中执行此操作,如果他们不在该角色中,则重定向到不同的视图。 好吧,就我而言,我专门谈论的是导航栏。我想在导航栏上添加一个 [Admin] 链接以重定向到管理控制器。控制器本身已通过策略授权,但我的目的纯粹是装饰性的 - 如果用户满足策略要求,则仅显示 [Admin] 选项卡,就像在控制器中一样 @MartinMazzaDawson 如果对您有帮助,我会将代码添加到我的 OP 中。 我很确定唯一的方法是像上面所做的那样添加服务器端检查,你正在做的事情完全没问题。我仍然不明白为什么您需要除此检查之外的任何其他内容。尽管使这更好的是将业务逻辑与视图逻辑分开并执行@if (FooModel.IsInRole("..."))
并将控制器的操作方法中的此属性值分配给IsInRole(...)
我发现这个链接可能会有所帮助.. docs.asp.net/en/latest/security/authorization/views.html
【参考方案1】:
我最终创建了一个标签助手来有条件地隐藏与之关联的元素。
[HtmlTargetElement(Attributes = "policy")]
public class PolicyTagHelper : TagHelper
private readonly IAuthorizationService _authService;
private readonly ClaimsPrincipal _principal;
public PolicyTagHelper(IAuthorizationService authService, IHttpContextAccessor httpContextAccessor)
_authService = authService;
_principal = httpContextAccessor.HttpContext.User;
public string Policy get; set;
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
// if (!await _authService.AuthorizeAsync(_principal, Policy)) ASP.NET Core 1.x
if (!(await _authService.AuthorizeAsync(_principal, Policy)).Succeeded)
output.SuppressOutput();
用法
<li policy="testPolicy"><a asp-controller="Admin" asp-action="Index">Admin</a></li>
【讨论】:
迄今为止最干净的方法——这应该随着技术的进步而更新,成为真正的答案。 +1 很棒的解决方案!对于 TagHelpers 的新开发人员,您需要在视图或 _ViewImports 文件中注册您的标签助手,如下所示:@addTagHelper *, YourAssemblyName
阅读更多:docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/…【参考方案2】:
我发现此链接可能会有所帮助:https://docs.asp.net/en/latest/security/authorization/views.html
该页面的示例:
@if (await AuthorizationService.AuthorizeAsync(User, "PolicyName"))
<p>This paragraph is displayed because you fulfilled PolicyName.</p>
在某些情况下,资源将成为您的视图模型,您可以调用 AuthorizeAsync 的方式与在基于资源的授权期间检查的方式完全相同;
@if (await AuthorizationService.AuthorizeAsync(User, Model, Operations.Edit))
<p><a class="btn btn-default" role="button"
href="@Url.Action("Edit", "Document", new id= Model.Id)">Edit</a></p>
【讨论】:
不确定在 1.0 或 2.0 中,但在核心 3.0 中,身份验证检查应为@if ((await AuthorizationService.AuthorizeAsync(User, "PolicyName")).Succeeded)
- 请注意 Succeeded
的最终属性检查。【参考方案3】:
这是 ASP Core 的一大改进,您可以将标识注入到启动文件中的所有页面:
@if (User.IsInRole("Admin"))
<p>
<a asp-action="Create" asp-controller="MyController">Create New</a>
</p>
在 Startup.cs 中:
services.AddIdentity<ApplicationUser, IdentityRole>()
编辑: 好吧,我看错了帖子,你已经知道了 :) - 如果有人可以使用它,无论如何我都会留下它。
【讨论】:
以上是关于在 .NET Core 1.0 MVC 的视图中使用授权策略的任何方式?的主要内容,如果未能解决你的问题,请参考以下文章
[MVC&Core]ASP.NET Core MVC 视图传值入门
007.Adding a view to an ASP.NET Core MVC app -- 在asp.net core mvc中添加视图