Asp.net mvc Как запретить браузеру вызывать метод действия? - PullRequest
14 голосов
/ 23 февраля 2012

У меня есть два действия внутри моего контроллера (shoppingCartController)

    public ActionResult Index()
    {
        //some stuff here
        return View(viewModel);
    }


    public ActionResult AddToCart(int id)
    {

        return RedirectToAction("Index");

    }

Есть ли возможность запретить пользователям напрямую вызывать действие индекса путем ввода URL-адреса в браузере?

Дляпример: если пользователь переходит на shoppingCart/index, перенаправляется на Home / Index.

Ответы [ 7 ]

15 голосов
/ 23 февраля 2012

Вы можете использовать атрибут [ChildActionOnly] в вашем методе действия, чтобы убедиться, что он не вызывается напрямую, или использовать свойство ControllerContext.IsChildAction внутри вашего действия, чтобы определить, хотите ли вы перенаправить.

Например:

public ActionResult Index()
{
    if(!ControllerContext.IsChildAction)
    {
       //perform redirect here
    }

    //some stuff here
    return View(viewModel);
}

Если вы не можете сделать действие Index дочерним действием, вы всегда можете проверить реферер, понимая, что оно не защищено от ошибок и может быть подделано. См:

Как получить URL-адрес реферера в действии ASP.NET MVC?

4 голосов
/ 23 февраля 2012

Попробуйте выполнить это действие контроллера индекса как private.Метод с private модификатором доступа не должен быть доступен извне класса.

И затем, в отличие от вызова RedirectToAction из AddToCart, вызовите его как простой метод, как показано ниже:

private ActionResult Index()
{
    //some stuff here
    return View(viewModel);
}


public ActionResult AddToCart(int id)
{

    return Index();

}
3 голосов
/ 23 февраля 2012

Если вас беспокоит только то, что пользователь вводит URL-адрес, то использование атрибута HttpPost должно предотвратить вызов вашего действия таким образом: -

[HttpPost]
public ActionResult AddToCart(int id)
{

Это предотвращает GET-запросы от вызова этого действия. Тем не менее, это не мешает кому-то писать фиктивную форму и размещать сообщения в вашем действии.

Если вы беспокоитесь о чем-то более злонамеренном, вы можете захотеть внедрить некоторую форму токена против подделки, здесь есть некоторая полезная информация здесь .

EDIT

ОК, поэтому при перечитывании вопроса вышеприведенное не совсем решает вашу проблему.

Как насчет маршрута? если у вас что-то похожее на приведенное ниже, это предотвратит вызов ShoppingCart / Index и перенаправит пользователя на индекс вашего сайта.

        routes.MapRoute(
            "ShoppingCartIndex",
            "ShoppingCart/Index",
            new { controller = "Home", action = "Index" }
        );
1 голос
/ 28 февраля 2017

NonAction - это атрибут для использования. Он является частью библиотеки MVC, поэтому вам не нужно создавать собственный атрибут.

1 голос
/ 20 декабря 2016

Здесь написан код, как запретить браузеру прямой доступ к методу действия: Введите следующий код в FilterConfig.cs

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class NoDirectAccessAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.HttpContext.Request.UrlReferrer == null ||
                    filterContext.HttpContext.Request.Url.Host != filterContext.HttpContext.Request.UrlReferrer.Host)
            {
            filterContext.Result = new RedirectToRouteResult(new
                           RouteValueDictionary(new { controller = "Home", action = "Index", area = "" })); 
        }
    }
}

Теперь примените этот код к вашему методу действия

[NoDirectAccess]
public ActionResult MyActionMethod()

Это ограничит прямой вызов любого класса или метода действия .

1 голос
/ 06 июня 2013

Если SessionState включен, вы можете использовать контроллер TempData для достижения вашей цели.Установите TempData в действии AddToCart и отображайте представление «Индекс» только в том случае, если действие «Индекс» может получить ключ TempData, установленный в действии AddToCart.

Если это необходимо для нескольких действий / проектов, используйте комбинацию пользовательских фильтров действий и ActionResult.Как это:

// Controller
[PreventDirectAccess]
public ActionResult Index()
{
    //some stuff here
    return View(viewModel);
}

public ActionResult AddToCart(int id)
{
    return new PreventDirectAccessRedirectToRouteResult(new RouteValueDictionary
    {
        {"action", "Index"}
    });
}

// Filter
public class PreventDirectAccessAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext == null)
            throw new ArgumentNullException("filterContext");

        if (filterContext.Controller.TempData[PreventDirectAccessRedirectToRouteResult.Executed] == null)
            filterContext.Result = new HttpNotFoundResult();

        base.OnActionExecuting(filterContext);
    }
}

// ActionResult
public class PreventDirectAccessRedirectToRouteResult : RedirectToRouteResult
{
    public const string Executed = "PreventDirectAccessRedirectExecuted";

    public override void ExecuteResult(ControllerContext context)
    {
        context.Controller.TempData[Executed] = true;
        base.ExecuteResult(context);
    }
}
0 голосов
/ 23 февраля 2012

Это не проверено, но я считаю, что вы можете использовать токен проверки фальсификации

В вашем коде на странице вам нужно будет поместить токен подтверждения в форму, которую необходимо опубликовать:

@Html.AntiForgeryToken()

Который производит:

<input name="__RequestVerificationToken" type="hidden" value="s9+jDREFMlNPkAT2zOlmhJZQbbDOzMhuarSTG1BVAC4GeHiNL5VtuQo7CQTF8obw8hEYIQac9YaQh+qVcF0xj0eNO7lVdezz+JxuSKGQo2d2gEdtkEdR+XTTFas4Gh6fjSYc7A1rWF8AAhxjZ9j6GlbRhECZOPAlPAItnjz49QQ=" />

Этот токен автоматически подбирается любым действием, имеющим этот атрибут:

[ValidateAuthenticationToken]
public ActionResult AddToCart(int id)
{
   return Index();
}

Если запрос прямой, тогда произойдет ошибка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...