2012-02-26 69 views
0

我有一个包含按钮的应用程序,单击此按钮时,它将使用带有querystring参数的URL打开浏览器窗口(我正在编码的页面)。如何确保从我的应用程序调用url而不是从浏览器手动调用

有没有一种方法可以确保URL来自我的应用程序,仅来自我的应用程序 - 而不仅仅是任何人在网页浏览器中手动输入网址?

如果不是,是为了确保特定的URL是从特定的应用程序来的最好方式 - 而不仅仅是手动在地址栏或使用asp.net的web浏览器的

林进入。

回答

3

您可以检查请求是否使用你的应用程序的页面之一提出:

Request.UrlReferrer.Contains("mywebsite.com")

这就是简单的方法。

安全的方法是在客户端添加一个cookie,其中包含使用安全密钥加密的值或使用安全盐进行散列。如果cookie在关闭页面时设置为过期,则不应该有人伪造。

下面是一个例子:

在会重定向到该页面的页面,试图保护:

HttpCookie cookie = new HttpCookie("SecureCheck"); 
    //don't set the cookie's expiration so it's deleted when the browser is closed 
    cookie.Value = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(Session.SessionID, "SHA1"); 
    Response.Cookies.Add(cookie); 

在你试图保护的页面:

//check to see if the cookie is there and it has the correct value 
    if (string.IsNullOrEmpty(Request.Cookies["SecureCheck"]) || System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(Session.SessionID, "SHA1") != Request.Cookies["SecureCheck"]) 
    throw Exception("Invalid request. Please access this page only from the application."); 
    //if we got this far the exception was not thrown and we are safe to continue 
    //insert whatever code here 
+0

如果从应用程序调用URL,则引用者将为空。但是,这并不意味着应用程序启动了它 - 例如如果用户只是打开一个新标签并输入URL,它也是空的。 – Chris 2012-02-26 17:21:24

+0

非常容易伪造,并且浏览器不需要发送它,您可能很容易地阻止合法使用该应用程序的人执行此操作。 – tvanfosson 2012-02-26 17:22:08

+0

使用安全Cookie是一个非常好的主意,但它不会阻止授权用户只输入URL。该cookie也将与该请求一起发送。根据cookie是否持续存在,他们甚至可能甚至不需要让该应用程序在当时处于打开状态(例如,稍后他们可能能够通过书签访问该应用程序)。 – tvanfosson 2012-02-26 17:30:18

0

如果请求中没有包含先前生成的参数中的随机一次性令牌(例如,将存储在会话中),则无法拒绝该请求。

+1

你可以请举一个使用c#的例子吗? – Zee99 2012-02-26 17:54:28

+0

没有。不知道C#。 – 2012-02-26 18:09:48

0

虽然没有100%安全的方法来做到这一点,但我所建议的至少可以照顾到您的基本需求。

这是你可以做的。

客户端:添加一个HTTP标头,其编码字符串就像某个字的散列(sha256)。 然后让您的客户端始终执行POST请求而不是GET。 服务器:检查HTTP标头是否有编码字符串。还要确保它是一个POST请求。

这不是100%ofcourse人足够聪明能想出仍然产生一个请求,但根据您的需要时,你可能会发现这个不足或不

0

您可以检查引用者,用户代理,加一个额外的请求头,总是发送请求到该网址。但是,考虑到HTTP是以纯文本形式传输的,有人总是能够让wireshark或fiddler运行,捕获HTTP数据包并使用您的措施重新创建请求。

1

对于GET请求没有可靠的方法来做到这一点,也没有任何理由为合法用户进行尝试。您应该做的是确保无论用户的请求来自哪里都具有适当的权限和访问权限,并且会话受到适当保护(仅HTTP,Cookie,SSL等)。)如果请求正在改变数据,那么它应该是一个POST,而不是一个GET,它应该伴随着一些合适的跨站点请求防伪技术(例如一个包含一个随机数的cookie,形式本身)。

+0

请问您可以在c#中给出这个cookie的例子吗? – Zee99 2012-02-26 17:54:47

+0

ASP.NET MVC AntiForgeryToken和相关的帮助程序就是这样做的一个例子。 – tvanfosson 2012-02-26 20:01:42

0

从您的应用程序传递参数,以便您可以在服务器端进行验证。

我建议你使用加密算法并使用密码(密钥)生成随机文本。然后,解密服务器端的参数,并检查它是否符合您的期望。

虽然我不是很清楚。对不起,如果必须做这样的事情,那么,我会做类似于上面提到的事情。

0

你可以用它来检查MVC控制器像Request.Headers["Accept"];的头,如果它是从你的代码进来angularjs或jQuery的:

样品angularjs这样的:

var url = ServiceServerPath + urlSearchService + '/SearchCustomer?input=' + $scope.strInput; 

$http({ 
      method: 'GET', 
      url: url, 
      headers: { 
       'Content-Type': 'application/json' 
      },..... 

而且对MVC [HTTPGET ]动作方法

 [HttpGet] 
     [PreventDirectAccess]//It is my custom filters 
     // ---> /Index/SearchCustomer?input={input}/ 
     public string SearchCustomer(string input) 
     { 
      try 
      { 
       var isJsonRequestOnMVC = Request.Headers["Accept"];//TODO: This will check if the request comes from MVC else comes from Browser 
       if (!isJsonRequestOnMVC.Contains("application/json")) return "Error Request on server!"; 

       var serialize = new JavaScriptSerializer(); 
       ISearch customer = new SearchCustomer(); 
       IEnumerable<ContactInfoResult> returnSearch = customer.GetCustomerDynamic(input); 

       return serialize.Serialize(returnSearch); 
      } 
      catch (Exception err) 
      { 
       throw; 
      } 
     } 
相关问题