在Aspnet MVC中基于Auth访问的视图上隐藏按钮-无需硬编码在Controller中进行授权 [英] Hide button on view based on Auth access in Aspnet MVC - Without hard coding Authorization in Controller

查看:83
本文介绍了在Aspnet MVC中基于Auth访问的视图上隐藏按钮-无需硬编码在Controller中进行授权的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

项目概述: 在项目后端的仪表板视图中工作.我有一个权限驱动菜单.当用户登录并查看仪表板时,将填充菜单.当前,用户看到所有按钮IE:删除,编辑,详细信息,创建.我想从视图中隐藏那些按钮.当前,他们可以选择它,并且如果他们没有访问权限,它将重定向到未经授权的页面.

Project Overview: Working in dashboard Views on back-end of project. I have a Permission driven Menu. Menu gets populated when User logs in and views dashboard. Currently the User sees all the buttons IE: delete, edit, details, create. I would like to hide those buttons from the view. Currently they can select it and it will redirect to a UnAuthorized page if they do not have access.

我有一个Menu/MenuPermissions表,如果用户具有访问权限,则该位置1.我正在寻找一些东西来利用此信息来隐藏按钮.

I have a Menu / MenuPermissions tables that bits are set if the user has access or not. I am looking for something to utilize this information to hide the buttons.

我已经创建了一个ActionLink扩展,其中包含几个类,可以将某些属性设置为true或False,但这需要我具备

I have created a ActionLink Extension with a couple of classes to turn a bit true or False, but it requires me to have

[Authorize(Roles = "Administration")]

在控制器动作中.这是不理想的,因为我可以灵活地编辑,创建和删除角色.

in the controller action. This not desirable as i have the flexibility to edit, create, and delete Roles.

我看了几本教程,它们似乎都与Asp.Net Core有关,我的项目不是,也不需要它.

I have looked at several Tutorials and they all seem to relate to Asp.Net Core, which my project is not and do not need it to be.

我在这篇文章中找到了我需要的东西:

I found what i needed in this post: asp-net-how-to-hide-or-show-a-link-button

但是,这是一个不完整的问题-该问题没有答案被接受.显然,这个人已经弄清楚了,但是没有去理会他的所作所为.

However it is an incomplete Question - There is no answer to this question that was accepted. Apparently the person has figured it out but did not bother to show what he did..

这是我尝试过的ActionLink扩展示例:

This is the ActionLink extension example i have tried:

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

就像我说的那样,这要求控制器将其设置为授权". 下面的代码用作OnActionExecuting(context),它超出了我的需要.但是,这可能有助于找到可用的解决方案.

This, Like i said requires the controller to have it set as Authorized. The Code below is used as a OnActionExecuting(context) Which is past the point that i would need it. However could help in finding a usable solution.

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"];

接下来的两个区域可帮助您根据菜单权限查找用户是否被授权:

The Next two areas aid in finding if the user is authorized based on menu permissions:

 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;
        }
    }

下面的代码在用于隐藏按钮的类中-再次要求在Controller中设置Authorize.

The code that is below is in the class that is used to hide the button - Again it requires that the Authorize is set in the Controller.

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;
    }

然后有一个链接扩展名可以在另一个文件中使用.

Then there are link extensions to use in another file.

如果有人可以向我指出我如何使用代码的正确方向,我已经必须检查菜单权限,然后在不进行硬编码的情况下隐藏按钮,将不胜感激.或者,如果有一种更简单的方法也行得通.

If someone could point me in the right direction as to how i can use the code i already have to check menu permissions and then hide the button without hard-coding, It would be appreciated. Or if there is a simpler way of doing this that would also work.

最终结果是摆脱了重定向.我的项目不喜欢它,因为它尝试在已设置标题后通过注销"传递标题.

The end result is to get rid of the redirect. My project does not like it because it tries to pass headers after headers are already set - Via "Log-Out".

感谢您的帮助.

更新:

此问题已在我发布的另一篇文章中解决. stackoverflow.com/questions/11668261

This has been resolved in another post i posted. stackoverflow.com/questions/11668261

推荐答案

我执行的方法与您所链接的问题中被高度评价的方法相同. https://stackoverflow.com/a/11668462/5367916

I do this the same way as the highly upvoted in the question you linked to. https://stackoverflow.com/a/11668462/5367916

一个非常简化的版本:

.cshtml

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

其缺点是,这意味着您的实现之间没有自动链接:

The downside of this is that it means there is no automatic link between your implementation:

[Authorize(Roles = "Admin")]

,然后在cshtml中签入.在基于角色的安全性实现中,我至少通过对安全对象使用枚举,自定义属性和方法来使其具有强类型性.

and your check in the cshtml. I at least make it strongly typed by using enums and custom attributes and methods for my securables in my role-based security implementation.

@if (User.HasSecurable(Securable.AdminPower))
{
  <button>Admin power button</button>
}

[AllowSecurables(Securable.AdminPower)]
public ActionResult AdminPower()
{
}

这篇关于在Aspnet MVC中基于Auth访问的视图上隐藏按钮-无需硬编码在Controller中进行授权的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆