C# 基于Aspnet MVC中的身份验证访问在视图上隐藏按钮-无需控制器中的硬编码授权

C# 基于Aspnet MVC中的身份验证访问在视图上隐藏按钮-无需控制器中的硬编码授权,c#,asp.net-mvc,entity-framework,authorization,C#,Asp.net Mvc,Entity Framework,Authorization,项目概况: 在项目后端的仪表板视图中工作。我有一个权限驱动的菜单。当用户登录并查看仪表板时,菜单将填充。当前,用户可以看到所有按钮,即:删除、编辑、详细信息、创建。我想在视图中隐藏这些按钮。目前,他们可以选择它,如果他们没有访问权限,它将重定向到未经授权的页面 我有一个菜单/菜单,如果用户有访问权限或没有访问权限,可以设置位。我正在寻找一些东西来利用这些信息隐藏按钮 我已经创建了一个ActionLink扩展,其中包含几个类,可以将其设置为true或False,但它要求我 [Authorize(R

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

我有一个菜单/菜单,如果用户有访问权限或没有访问权限,可以设置位。我正在寻找一些东西来利用这些信息隐藏按钮

我已经创建了一个ActionLink扩展,其中包含几个类,可以将其设置为true或False,但它要求我

[Authorize(Roles = "Administration")]
在控制器操作中。这是不可取的,因为我可以灵活地编辑、创建和删除角色

我看过几个教程,它们似乎都与Asp.NETCore有关,我的项目不是也不需要它

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

然而,这是一个不完整的问题——这个问题没有被接受的答案。显然,这个人已经明白了,但没有费心去展示他的所作所为

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

 @Html.ActionLinkAuthorized("Edit Roles", "Edit", "Roles", new { UserName = item.UserName }, new { @class = "btn btn-warning btn-sm" }, true)
正如我所说,这需要控制器将其设置为授权。 下面的代码用作OnActionExecuting(上下文),它已经超出了我需要它的范围。然而,这可能有助于找到一个可用的解决方案

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;
    }
然后在另一个文件中使用链接扩展名

如果有人能为我指出正确的方向,告诉我如何使用我已经拥有的代码来检查菜单权限,然后在没有硬编码的情况下隐藏按钮,我将不胜感激。或者,如果有一种更简单的方法也能做到这一点

最终的结果是摆脱重定向。我的项目不喜欢它,因为它试图在已经设置了头之后通过“注销”传递头

谢谢你在这方面的帮助

更新:

这已经在我发布的另一篇帖子中得到了解决。

我这样做的方式与您链接的问题中的高投票率相同。

非常简化的版本:

.cshtml

@if (User.IsInRole("Admin"))
{
  <button>Admin power button</button>
}
以及您在cshtml中的签入。在基于角色的安全实现中,我至少通过使用枚举、自定义属性和方法来实现强类型

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

是的,这是我过去实现这一目标的一种方式。但是我不想硬编码。如果我创建了一个角色,并且希望该角色具有或不具有权限,我不希望必须再次检查代码和硬代码。然后重新部署。我需要灵活性。随着时间的推移,我可能会改变事情,这将是更容易做的后端和更少的混乱!谢谢你的意见……是的,这就是为什么我使用安全的方法。每个函数都被认为是安全的。因此,创建一个新用户可能是一个安全的方法。也许上传文件是另一个问题。然后将安全性映射到数据库中的角色。因此,安全性只定义一次,永远不会更改(除非函数被删除),我可以随意手动更新角色。如果可能,你有这个安全性的好链接吗?我对它不熟悉。
@if (User.HasSecurable(Securable.AdminPower))
{
  <button>Admin power button</button>
}
[AllowSecurables(Securable.AdminPower)]
public ActionResult AdminPower()
{
}