在ASP.NET MVC Web API中拒绝一组用户对特定页面的访问



我已经在MVC4中开发了一个web API,我正在进行身份验证和授权。我有不同类型的用户,他们应该对API有不同的看法。所以,我刚刚创建了一个带有IsAdmin列的用户表,其中很少有人会将其作为1,而其他人则为0。

我已经写了一个方法来检查他使用的是什么样的用户以下代码

public bool IsValidAdmin(string _username, string _password)
        {
            using (var cn = new SqlConnection(@"Data Source=xyz.com;Initial Catalog=pqr;Persist Security Info=True;User ID=abc;Password=****"))
            {
                string _sql = @"SELECT [Username] FROM [dbo].[System_Users] " +
                       @"WHERE [Username] = @u AND [Password] = @p AND [IsAdmin]=1";
                var cmd = new SqlCommand(_sql, cn);
                cmd.Parameters.AddWithValue("@u",_username);
                cmd.Parameters.AddWithValue("@p", _password);
                cn.Open();
                var reader = cmd.ExecuteReader();
                if (reader.HasRows)
                {
                    reader.Dispose();
                    cmd.Dispose();
                    return true;
                }
                else
                {
                    reader.Dispose();
                    cmd.Dispose();
                    return false;
                }
            }

        }
        public bool IsValidUser(string _username, string _password)
        {
            using (var cn = new SqlConnection(@"Data Source=xyz.com;Initial Catalog=pqr;Persist Security Info=True;User ID=abc;Password=****"))
            {
                string _sql = @"SELECT [Username] FROM [dbo].[System_Users] " +
                       @"WHERE [Username] = @u AND [Password] = @p AND [IsAdmin]!=1";
                var cmd = new SqlCommand(_sql, cn);
                cmd.Parameters.AddWithValue("@u", _username);
                cmd.Parameters.AddWithValue("@p", _password);
                cn.Open();
                var reader = cmd.ExecuteReader();
                if (reader.HasRows)
                {
                    reader.Dispose();
                    cmd.Dispose();
                    return true;
                }
                else
                {
                    reader.Dispose();
                    cmd.Dispose();
                    return false;
                }
            }
        }

控制器

 [HttpPost]
        public ActionResult Login(Models.User user)
        {
            if (ModelState.IsValid)
            {
                if (user.IsValidAdmin(user.UserName, user.Password))
                {
                    FormsAuthentication.SetAuthCookie(user.UserName, user.RememberMe);
                    return RedirectToAction("Index", "Admin");
                }
                else if (user.IsValidUser(user.UserName, user.Password))
                {
                    FormsAuthentication.SetAuthCookie(user.UserName, user.RememberMe);
                    return RedirectToAction("Index", "Home");
                }
                else 
                {
                    ModelState.AddModelError("", "Login data is incorrect!");
                }
            }
            return View(user);

管理员

[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]
        [Authorize]
        public ActionResult Index()
        {
            return View();
        }

普通用户

[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]
      [Authorize]
      public ActionResult Index() {
      return View();
    }

它的工作原理就像当IsAdmin=0的用户登录时,它会将他重定向到正常页面,这正是我所需要的,但当用户通过身份验证时,他甚至可以访问其他页面。我想我需要处理一些请求。IsAuthenticated在我的主页中如下

Layout.cshtml

@if (Request.IsAuthenticated)
                {
                    <tr>
                    <td class="btn">@Html.ActionLink(@Html.Encode(User.Identity.Name).ToUpper()+"!!","Index","Admin")</td>
                  <td class="btn">  @Html.ActionLink("Sign Out", "Logout", "User")</td>
                        </tr>
                }
                else
                {
                     <tr>
                    <td class="User btn">
                    @Html.ActionLink("Sign In", "Login", "User")</td></tr>
                }

现在,在Request.IsAuthenticated中的上述cshtml中,当用户登录时,它显然会返回true,而不考虑IsAdmin是0还是1,并且他可以访问所有页面。

我可以知道一些避免这种情况并拒绝访问内部页面的方法吗?

您需要创建一个自定义AuthorizeAttribute,以便将其作为过滤器应用于控制器中需要更精细控制的特定操作。

public class CustomAuthorizeAttribute : AuthorizeAttribute
{
    public bool IsAdmin {get; set;}
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        //Load user permissions here
        if(IsAdmin) return user.IsAdmin;
        return false;
    }
}

然后你可以在控制器中的特定操作中使用它,如下所示:

[CustomAuthorize(IsAdmin = true)]
public ActionResult AdminOnlyAction()
{
}

如果你有很多特定的权限要筛选,那么最好只为角色使用一个字符串,然后根据这些角色测试用户。

[CustomAuthorize(Roles = "admin,superadmin")]

MVC提供了一个称为过滤器的功能,它适用于那些需要保护某些控制器操作的场景。

过滤器可以用作属性或全局过滤器。

简单地在谷歌上搜索"MVC安全过滤器"应该会给你足够的信息。。。

实现你自己的安全过滤器,检查你的自定义权限会做你想做的事,我想。。。

最新更新