Кнопка «Скрыть» в представлении, основанная на доступе Auth в As pnet MVC - без жесткого кодирования - PullRequest
0 голосов
/ 10 февраля 2020

Обзор проекта: Работа в панели инструментов Представления в конце проекта. У меня есть меню с правами доступа. Меню заполняется, когда пользователь входит в систему и просматривает панель управления. В настоящее время пользователь видит все кнопки IE: удаление, редактирование, детали, создание. Я хотел бы скрыть эти кнопки от вида. В настоящее время они могут выбрать его, и он будет перенаправлен на неавторизованную страницу, если у них нет доступа.

У меня есть таблицы Menu / MenuPermissions, в которых биты устанавливаются, если пользователь имеет доступ или нет. Я ищу что-то, чтобы использовать эту информацию, чтобы скрыть кнопки.

Я создал расширение ActionLink с парой классов, чтобы сделать его истинным или ложным, но для этого требуется, чтобы в действии контроллера было

[Authorize(Roles = "Administration")]

. Это нежелательно, так как у меня есть возможность редактировать, создавать и удалять роли.

Я просмотрел несколько учебных пособий, и все они, похоже, относятся к Asp. Net Ядру, которым не является мой проект, и в котором он не нуждается.

Я нашел то, что мне было нужно в этом посте: asp - net как скрыть или показать ссылку на кнопку

Однако это неполный вопрос - нет ответа на этот вопрос, который был принят. Видимо, человек понял это, но не удосужился показать, что он сделал.

Это пример расширения ActionLink, который я пробовал:

 @Html.ActionLinkAuthorized("Edit Roles", "Edit", "Roles", new { UserName = item.UserName }, new { @class = "btn btn-warning btn-sm" }, true)

Это, как я уже сказал, требует контроллер, чтобы он был установлен как авторизованный. Код ниже используется в качестве OnActionExecuting (context), который прошел точку, которая мне понадобится. Однако это может помочь в поиске подходящего решения.

string userid = Env.GetUserInfo("userid");
            string roleid = Env.GetUserInfo("roleid");
            var descriptor = context.ActionDescriptor;
            var actionName = descriptor.ActionName.ToLower();
            var controllerName = descriptor.ControllerDescriptor.ControllerName.ToLower();

            var GetOrPost = context.HttpContext.Request.HttpMethod.ToString();
            var checkAreaName = context.HttpContext.Request.RequestContext.RouteData.DataTokens["area"];

Следующие две области помогают определить, авторизован ли пользователь на основании разрешений меню:

 private bool IsActionNameEqualToCrudPageName(string actionName)
    {
        bool ActionIsCrud = false;
        switch (actionName)
        {
            case "add":
                ActionIsCrud = true;
                break;
            case "create":
                ActionIsCrud = true;
                break;
            case "index":
                ActionIsCrud = true;
                break;
            case "details":
                ActionIsCrud = true;
                break;
            case "edit":
                ActionIsCrud = true;
                break;
            case "multiviewindex":
                ActionIsCrud = true;
                break;
            case "delete":
                ActionIsCrud = true;
                break;
            default:
                ActionIsCrud = false;
                break;
        }

        return ActionIsCrud;
    }

    private void CheckAccessOfPageAction(ActionExecutingContext context, string actionName, MenuOfRole checkRoleUrlCrud)
    {
        switch (actionName)
        {
            case "add":
                if (checkRoleUrlCrud.IsAdd == false)//Check Crud
                {
                    UnAuthoRedirect(context);
                }
                break;
            case "create":
                if (checkRoleUrlCrud.IsCreate == false)//Check Crud
                {
                    UnAuthoRedirect(context);
                }
                break;
            case "index":
                if (checkRoleUrlCrud.IsRead == false)//Check Crud
                {
                    UnAuthoRedirect(context);
                }
                break;
            case "details":
                if (checkRoleUrlCrud.IsRead == false)//Check Crud
                {
                    UnAuthoRedirect(context);
                }
                break;
            case "edit":
                if (checkRoleUrlCrud.IsUpdate == false)//Check Crud
                {
                    UnAuthoRedirect(context);
                }
                break;
            case "multiviewindex":
                if (checkRoleUrlCrud.IsUpdate == false)//Check Crud
                {
                    UnAuthoRedirect(context);
                }
                break;
            case "delete":
                if (checkRoleUrlCrud.IsDelete == false)//Check Crud
                {
                    UnAuthoRedirect(context);
                }
                break;

            default:
                break;
        }
    }

Код ниже в классе, который используется, чтобы скрыть кнопку - снова требуется, чтобы в контроллере была установлена ​​авторизация.

public static bool ActionAuthorized(this HtmlHelper htmlHelper, string actionName, string controllerName)
    {
        ControllerBase controllerBase = string.IsNullOrEmpty(controllerName) ? htmlHelper.ViewContext.Controller : htmlHelper.GetControllerByName(controllerName);
        ControllerContext controllerContext = new ControllerContext(htmlHelper.ViewContext.RequestContext, controllerBase);
        ControllerDescriptor controllerDescriptor = new ReflectedControllerDescriptor(controllerContext.Controller.GetType());
        ActionDescriptor actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName);

        if (actionDescriptor == null)
            return false;

        FilterInfo filters = new FilterInfo(FilterProviders.Providers.GetFilters(controllerContext, actionDescriptor));

        AuthorizationContext authorizationContext = new AuthorizationContext(controllerContext, actionDescriptor);
        foreach (IAuthorizationFilter authorizationFilter in filters.AuthorizationFilters)
        {
            authorizationFilter.OnAuthorization(authorizationContext);
            if (authorizationContext.Result != null)
                return false;
        }
        return true;
    }

Тогда есть расширения ссылок для использования в другом файле.

Если бы кто-то мог указать мне правильное направление относительно того, как я могу использовать код, который мне уже нужен, чтобы проверить разрешения меню и затем скрыть кнопку без жесткого кодирования, это было бы желательно. Или, если есть более простой способ сделать это, который также будет работать.

Конечный результат - избавиться от перенаправления. Мой проект не нравится, потому что он пытается передать заголовки после того, как заголовки уже установлены - через «Выход».

Спасибо за вашу помощь в этом.

ОБНОВЛЕНИЕ:

Это было решено в другой публикации, которую я опубликовал. stackoverflow.com / вопросы / 11668261

1 Ответ

0 голосов
/ 10 февраля 2020

Я делаю это так же, как высоко голосовали в вопросе, с которым вы связаны. { ссылка }

Очень упрощенная версия:

.cs html

@if (User.IsInRole("Admin"))
{
  <button>Admin power button</button>
}

Недостаток этого означает, что между вашей реализацией нет автоматической c связи:

[Authorize(Roles = "Admin")]

и вашей проверкой в ​​cs html. Я, по крайней мере, делаю его строго типизированным, используя перечисления и пользовательские атрибуты и методы для своих защищаемых объектов в моей реализации безопасности на основе ролей.

@if (User.HasSecurable(Securable.AdminPower))
{
  <button>Admin power button</button>
}
[AllowSecurables(Securable.AdminPower)]
public ActionResult AdminPower()
{
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...