【问题标题】:MVC C# preventing normal users from accessing admin control URL - No rolesMVC C# 阻止普通用户访问管理控制 URL - 无角色
【发布时间】:2017-08-03 07:52:49
【问题描述】:

现在,我的用户表有一个名为 Admin 的布尔值。如代码所示,如​​果 user.admin = true,用户可以看到管理区域按钮并访问它。

    @if (Common.UsuarioLogueado.Admin) {
                                <li><a href="@Url.Action("List","ClientesAdmin",new { Area = "Admin" })">Admin control panel</a></li>
                            }

这是按预期工作的。但是,非管理员用户仍然可以通过访问它的 url http://localhost/appName/admin/ClientesAdmin/list 来访问控制面板

我该如何防止这样的事情发生?我正在考虑显示错误消息

【问题讨论】:

  • Google AuthorizeAttribute - 用于由经过身份验证的用户或角色保护的属性。
  • 创建一个 FilterAttribute 来管理您所期望的安全性
  • 你需要的是ASP MVC中的Roles,你可以在网上找到大量的示例。

标签: c# asp.net-mvc


【解决方案1】:

与其他关于使用RolesAuthorizeAttribute.. 的答案一起,我认为这是实现您想要做的事情的更好方法,还有另一种方法。

您可以简单地将用户重定向到另一个页面。最好是一个错误页面,说明您无权访问所请求的页面,或者只是一个 401 页面,如果您没有被授权,AuthorizeAttribute 会这样做。

替代解决方案

public class ClientesAdmin : Controller {
    // [Authorize(Roles="Admin")]  could do it this way
    public ActionResult List() {
        // or..
         if(!Common.UsuarioLogueado.Admin)
         {
             return new HttpStatusCodeResult(401);
             // or
             // return View("Error") // usually there is an 'Error' view the Shared folder
         }

         return View();
    }
}

这不是最好的解决方案,但我不知道您的项目有多远,而只是一个替代解决方案。

【讨论】:

  • 项目几乎准备好了:(我是一名实习生,所以我不知道角色。感谢您的帮助,但是当用户尝试登录时,如何让我的控制器检查 AdminOnly 方法?
  • @MarianoGianni当用户尝试登录时是什么意思?用户要么是管理员要么不是管理员,因为您说在您的Users 表中,Admin 属性有点(布尔)。因此,如果用户尝试访问 url http://localhost/appName/admin/ClientesAdmin/list.. 流将转到 ClientesAdmin 控制器上的 List 操作,它将命中 if 语句
  • 没关系,在您的帮助下,我能够实现我的目标。谢谢。
  • 不客气。很高兴我能提供帮助。编码愉快!
【解决方案2】:

这就是我的做法。但是,您的会员系统需要使用 ASP.Net Roles 才能正常工作。

在您的控制器中,您只需添加数据注释Authorize。对于客户端访问的功能,他们必须登录并在功能中指定滚动。

此解决方案可能不是直接剪切和粘贴,但您可以看到基本用法然后可能对Authorize 功能进行更多研究。

public class MyController : Controller {
     [Authorize(Roles="Admin")]
     public ActionResult AdminIndex() {
          return View();
     }



    [Authorize(Roles = "basic")]
    public ActionResult BasicUsersIndex() {
         return View();
    }
}

【讨论】:

    【解决方案3】:

    理想情况下,您应该使用基于角色的访问控制。通过限制角色的访问,而不是表中的布尔值,您可以使用如下所示的授权属性来装饰您的 CientesAdmin 控制器。

    [Authorize(Roles = "Admin")]
    public class CientesAdminController : Controller
    { 
    }
    

    您还可以使用 razor 助手来检查用户是否为 IsInRole("Admin")。

    网上有很多帮助可以指导您走这条路,但如果您的应用程序已经开发完毕,您可能希望进行更改。然后建议创建您自己的 AuthoriseAttribue。就像是。

    public class RestrictAccessToAdmins : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            //Do the default Authorise Logic (Check if user is loggedin) 
            base.AuthorizeCore(httpContext);
             if (httpContext.User.IsInRole("Admin")) return true;
    
            var id = httpContext.User.Identity.GetUserId();
    
            using (ApplicationDbContext context = new ApplicationDbContext())
            {
                //Implement you own DB logic here returning a true or false. 
                return context.Common.First(u => u.userid == id).UsuarioLogueado.Admin;
            }
        }
    
    }
    

    要使用该属性,您需要执行以下操作。

    [RestrictAccessToAdmins]
    public class CientesAdminController : Controller
    { 
    }
    

    然后随着时间的推移,随着对默认授权属性的更好理解和一些重构,您可以轻松地将属性更改为以下 :)

    [RestrictAccessToAdmins(Roles = "Admin")]
    public class CientesAdminController : Controller
    { 
    }
    

    【讨论】:

    • 这很棒,是的,应用程序已经以这种方式开发了。我会在下一个项目中记住这一点。
    • where 谓词返回的序列不会有UsuarioLogueado 属性。你是说Find() 还是FirstOrDefault()
    • 是的,我知道,这纯粹是为了举例:) 随意编辑。
    • 同意@Crowcoder .. 理想情况下,该行应该是return context.Common.Single(u =&gt; u.userid === id).UsuarioLogueado.Admin;.. 如果userid唯一的,那么应该只有一个单个记录..所以不需要使用First()FirstOrDefault()
    猜你喜欢
    • 2019-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-31
    • 2016-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多