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>
Другие вопросы по тегам