ASP.NET Core MVC Навигация по безопасности
В ASP.NET Core MVC я хотел бы скрыть в панели навигации ссылки, к которым у пользователя нет прав доступа. В настоящее время MvcSiteMapProvider, который я использовал в предыдущих проектах, не поддерживает ASP.NET Core MVC.
Подобный вопрос был задан пару лет назад, и хотя предложенный ответ сработает, потребуется повторение набора фильтров авторизации на контроллере / действии, чтобы убедиться, что ссылки скрыты.
Как это можно сделать, и есть ли текущие примеры обрезки безопасности в ASP.NET Core MVC?
1 ответ
Я создал специальный помощник тегов, чтобы справиться с этим.
[HtmlTargetElement(Attributes = "asp-roles")]
public class SecurityTrimmingTagHelper : TagHelper
{
[ViewContext]
public ViewContext Context { get; set; }
[HtmlAttributeName("asp-roles")]
public string Roles { get; set; }
/// <summary>
/// Hides html element if user is not in provided role.
/// If no role is supplied the html element will be render.
/// </summary>
/// <param name="context"></param>
/// <param name="output"></param>
public override void Process(TagHelperContext context, TagHelperOutput output)
{
if (!Context.HttpContext.User.Identity.IsAuthenticated)
{
output.SuppressOutput();
}
if (!string.IsNullOrEmpty(Roles))
{
var roles = Roles.Split(',');
foreach (var role in roles)
{
if (!Context.HttpContext.User.IsInRole(role))
{
output.SuppressOutput();
return;
}
}
}
}
}
Вы можете применить это к любому элементу HTML. Если вы хотите применить его только к определенному элементу HTML (скажем, <li>
) затем поменяйте HtmlTargetElement
в
[HtmlTargetElement("li",Attributes = "asp-roles")]
тогда ввиду можно сделать
<li asp-roles="Admin"><a href="/Profile/Admin">Admin</a></li>