【问题标题】:Securing ajax calls in a ASP.NET MVC application保护 ASP.NET MVC 应用程序中的 ajax 调用
【发布时间】:2012-08-22 22:03:17
【问题描述】:

我有一个基于 ASP.NET MVC 的应用程序,它允许根据用户进行不同级别的访问。它当前的工作方式是当用户访问页面时,对数据库进行检查以确定用户拥有的权限。然后根据用户拥有的访问级别选择视图。一些用户比其他用户看到更多的数据并且拥有更多可用的功能。每个页面还进行各种ajax调用来显示和更新页面显示的数据。

我的问题是,确保特定 ajax 调用源自视图并且不是手动制作以返回或更新用户无权访问的数据的最佳方法是什么?我宁愿不必在每次进行 ajax 调用时都去数据库重新检查,因为在用户最初加载页面时已经完成了。

【问题讨论】:

  • 你为什么不坚持使用内置的会员资格和角色提供者?这是开箱即用的,因为您的 ajax 调用带有所有 cookie,所以所有身份验证 cookie 肯定都在那里。
  • 除了 Wiktor 所说的,我不会对任何与网站安全有关的事情进行任何 ajax 调用,我只会做普通的帖子。最好是安全的人。
  • 我认为没有“最好的方法”来做到这一点......这取决于你如何构建你的安全层......就像你是否基于 asp 成员创建它们一样...... .. 无论如何...我会创建一个共享安全类来缓存数据库中的安全设置...这样您就不需要在每次调用时访问您的数据库...您只需从内存中读取它。跨度>
  • @HanletEscaño 普通帖子比 Ajax 帖子更安全吗?
  • @Charlino,您无法将普通帖子与 XMLHTTPRequest 进行比较,尽管它们看起来可能会做同样的事情,但事实并非如此。即使没有经验的用户也可以轻松查看和更新​​这类帖子,而普通形式的帖子也是如此,但它仍然会更安全。

标签: asp.net asp.net-mvc security


【解决方案1】:

查看Authorize Attribute,您可以将它放在整个控制器上,也可以只放在控制器中的特定方法上。

例子:

[Authorize(Roles = "Administrator")]
public class AdminController : Controller
{
 //your code here
}

public class AdminController : Controller
{
    //Available to everyone
    public ActionResult Index()
    {
        return View();
    }

    //Just available to users in the Administrator role.
    [Authorize(Roles = "Administrator")]
    public ActionResult AdminOnlyIndex()
    {
        return View();
    }
}

或者,您可以编写自定义 Authorize 属性来提供您自己的逻辑。

public class CustomAuthorizeAttribute : AuthorizeAttribute 
{           
    protected override bool AuthorizeCore(HttpContextBase httpContext)     
    {
        IPrincipal user = httpContext.User;     
        var validRoles = Roles.Split(',');//Roles will be a parameter when you use the Attribute        
        List<String> userRoles = GetRolesFromDb(user);//This will be a call to your database to get the roles the user is in.

        return validRoles.Intersect(userRoles).Any();
    }
} 

使用方法:

 [CustomAuthorizeAttribute(Roles = "Admin,Superuser")] 
 public class AdminController : Controller {

 }

【讨论】:

  • 我不认为这对我有用,因为我们没有使用 Windows 角色。我们的角色在数据库中定义,需要进行 db 调用以确保成员资格。
  • 我希望有一种方法不需要进入数据库来独立检查每个请求,但也许这是唯一的方法。您的解决方案确实非常干净地完成了这项工作。
  • 一个选项可能是在登录后缓存用户在会话中的角色。
【解决方案2】:

这取决于您使用的会话机制类型。您是否使用默认会员服务提供商?如果不是,您可以传递用户的 id 和 sessionid 确保用户会话有效并且用户具有进行该调用所需的权限。

【讨论】:

    【解决方案3】:

    除了 Authorize 属性,您还可以只允许使用自定义属性的 Ajax 请求,如 here 所示。

    谢谢

    【讨论】:

      【解决方案4】:

      如果你使用的是帖子使用

      [Authorize]
      [ValidateAntiForgeryToken]
      

      如果你使用的是 get 使用

      [Authorize]
      

      你也可以使用这个自定义属性

      public class HttpAjaxRequestAttribute : ActionMethodSelectorAttribute
      {
          public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
          {
              if (!controllerContext.HttpContext.Request.IsAjaxRequest())
              {
                  throw new Exception("This action " + methodInfo.Name + " can only be called via an Ajax request");
              }
              return true;
          }
      }
      

      然后如下装饰你的动作

      [Authorize]
      [HttpAjaxRequest]
      public ActionResult FillCity(int State)
      {
          //code here
      }
      

      如果这能解决您的问题,请记住“标记/打勾”。

      【讨论】:

        猜你喜欢
        • 2011-01-25
        • 2021-08-04
        • 1970-01-01
        • 2014-12-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多