2012-02-23 42 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庫的一部分,因此您不必創建自己的屬性。

相關問題