Securing ajax calls in a ASP.NET MVC application

2019-05-14 00:33发布

问题:

I have an ASP.NET MVC based application that allows different levels of access depending on the user. The way it currently works is when a user accesses a page, a check is done against the database to determine the rights that user has. The view is then selected based on the level of access that user has. Some users see more data and have more functionality available to them than do others. Each page also makes a variety of ajax calls to display and update the data displayed on the page.

My question is what is the best way to ensure that a particular ajax call originated from the view and was not crafted manually to return or update data the user does not have access to? I would prefer not to have to go to the database to re-check every time an ajax call is made since that was already done when the user initially loaded the page.

回答1:

Check out the Authorize Attribute, you can put it on an entire controller or just specific methods within your controller.

Examples:

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

or

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

Alternately, you can write a custom Authorize attribute to provide your own logic.

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

To use:

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

 }


回答2:

It depends on what type of session mechanisam you are using . Are you using default membership provider ? If not than you can pass user's id and sessionid make sure that user session is valid and user has required permission to make that call .



回答3:

Along with the Authorize attribute, you can also allow only Ajax requests using custom attributes as shown here.

Thanks



回答4:

If iyou are using a post use

[Authorize]
[ValidateAntiForgeryToken]

If iyou are using a get use

[Authorize]

You can also use this custom attribute

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

Then decorate your action as below

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

Remember to "Mark/Tick" if this solve your problem.