2012-02-23 43 views
10

我有我的控制器(shoppingCartController)Asp.net mvc如何防止浏览器调用操作方法?

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


    public ActionResult AddToCart(int id) 
    { 

     return RedirectToAction("Index"); 

    } 

反正是有防止用户直接调用在浏览器中键入URL索引操作中两个动作?

例如:如果用户浏览到shoppingCart/index被重定向到Home/Index。

回答

13

您可以使用[ChildActionOnly]属性上的操作方法,以确保它不是直接调用,或使用ControllerContext.IsChildAction确定您是否要重定向。

例如:

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

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

如果你不能使索引操作一个孩子的动作,你总是可以检查引用,理解,这不是万无一失的,可以被欺骗。请参阅:

How do I get the referrer URL in an ASP.NET MVC action?

+0

如果我把我的索引方法[ChildActionOnly]它不会从redirectToAction调用。它只适用于如果我有html.action()。另外controllerContext.ischildAction不会将redirecttoaction识别为childaction调用。 – 1AmirJalali 2012-02-23 04:59:51

+0

如果你想要一个像常规操作那样工作的动作(也就是你可以使用RedirectToAction),但只能从一个地方重定向,你可以尝试检查动作中的引用者,如果引用者不是引用,则重定向到home/index AddToCart网址。尽管如此,这不是万无一失的,因为引用者可能会被欺骗。 – 2012-02-23 05:11:41

+0

我打算检查响应状态码。我应该如何检查参考? – 1AmirJalali 2012-02-23 05:18:07

3

尝试使此索引控制器的操作为private。具有private访问修饰符的方法不应从外部类访问。

然后,rahter比调用从AddToCart RedirectToAction称其为简单的方法,象下面这样:

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


public ActionResult AddToCart(int id) 
{ 

    return Index(); 

} 
+0

但它不会将用户重定向到home/index。 – 1AmirJalali 2012-02-23 04:33:39

+0

所以它不能解决重定向用户的问题,如果他们明确地输入了网址shoppingCart/Index,它只是给了一些错误,无法找到资源 – 1AmirJalali 2012-02-23 04:49:29

+0

好的。你在Index中有什么应该是一些辅助方法,应该从AddToCart调用。实际索引方法应该公开,并且重定向到Home/Index。 – Maheep 2012-02-23 05:03:17

2

如果你所担心的是用户键入的URL,然后使用HttpPost属性应该阻止你的行动被称为这种方式: -

[HttpPost] 
public ActionResult AddToCart(int id) 
{ 

这样可防止通过调用该操作获取请求。但是,它不会阻止某人编写虚拟表单并将其发送到您的操作。

如果您担心的是更恶意的东西,您可能需要实施某种形式的防伪标记,但有关here的一些更好的信息。

编辑

OK,于是就重新阅读了上面的问题并没有完全解决您的问题。

路线怎么样?如果您有类似下面的内容,则会阻止ShoppingCart/Index被调用并将用户重定向到您的网站索引。

 routes.MapRoute(
      "ShoppingCartIndex", 
      "ShoppingCart/Index", 
      new { controller = "Home", action = "Index" } 
     ); 
+0

我不认为这是他要保护的AddToCart操作,而是Index操作,它是一个GET操作。 – 2012-02-23 05:13:39

+1

但是你说得对,AddToCart动作肯定需要是POST。 :-) – 2012-02-23 05:15:58

+0

不用担心用户输入example.com/shoppingcart并看到空的shoppingCart。 – 1AmirJalali 2012-02-23 05:16:53

0

这是未经测试,但我相信你可以使用验证防伪造令牌

在你的代码的网页上,您将需要安置的验证令牌将被贴在表格:

@Html.AntiForgeryToken() 

主要生产:

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

此令牌是自动的任何回升具有此属性的操作:

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

如果请求是直接的,则会发生错误。

+0

我喜欢这个想法,但如果这个链接I有没有形式? – retslig 2012-10-03 19:50:48

+1

@retslig - 如果你的意思是一个标准的GET请求,[那么你不能使用这种方法](http://stackoverflow.com/a/4943610/59532) – Dann 2012-10-03 22:04:58

1

如果启用SessionState,则可以使用控制器的TempData来实现您的目标。在AddToCart操作中设置TempData,并且只有在Index操作可以在AddToCart操作中获取TempData键时才显示Index视图。

如果您需要多个操作/项目,请使用自定义Action Filter和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

下面是编写的代码如何防止浏览器直接访问行动方法: 下面写代码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() 

这将限制直接致电任何类别行动方法

0

NonAction是要使用的属性。它是MVC库的一部分,因此您不必创建自己的属性。

相关问题