4

我有一个用 C# 编写的 ASP.Net MVC3 Web 应用程序。

我有一个 ActionResult 旨在返回 Json 结果,以便可以使用 JavaScript 的网页异步调用它。动作基本如下:

public ActionResult FindSomething(string search)
{
   var result = GetSearchResult(search);

   return Json(new { @Result = result }, JsonRequestBehavior.AllowGet);
}

然后在其中一个网页中,我有一些 JavaScript(使用 JQuery)来获取数据。

但是,我想尝试并做的是限制对此 FindSomething 操作的访问,以便只有我的网站代码才能访问结果。就目前而言,任何人都可以从 Web 浏览器调用此操作。

关于我完成这项工作的一些选择的任何想法?

应该注意的是,不会登录到该网站,因此无法通过这种方式进行身份验证。而且我不想在 html 源代码中包含与密码方法相关的任何内容。


为什么我想要这个

FindSomething方法实际上调用了第三方服务,该服务是使用积分付费的。所以实际上,通话次数越多,它的成本就越高。

我担心的是,如果有人知道这个 URL 并想使用相同的服务,那么他们可以通过我们的 URL 查询它并避免收费。

我不确定这个第 3 方服务是否考虑过这一点,他们提供了几种与服务交互的方式。一种是通过我可以通过服务器代码调用的 Web 服务(我正在这样做),另一种是通过一些内联的 javascript 引用 - 后者需要在 html 源代码中硬编码许可证密钥:S

...可能值得我向他们寻求答案,但无论我如何解决服务中的这个缺陷,它仍然会在 SO 上提出一个有趣的问题

4

2 回答 2

3

鉴于您的限制,恐怕没有可靠的方法可以实现这一目标。您可以通过使用例如防伪令牌而不是 100% 防弹来使其变得困难。不要忘记,不仅浏览器可以发送 HTTP 请求。任何人都可以伪造 HTTP 请求并将其发送到您的服务器。

使用非 GUI API 完成此操作的方式是将公钥提供给客户端,而使用 GUI 应用程序(例如网站)完成此操作的方式是向用户提供密码。

于 2012-05-08T15:44:47.000 回答
2

最明智的做法是使用防伪令牌+盐,如下所述

[ValidateAntiForgeryToken(Salt = Constants.AntiForgeryTokenSalt)]
public ActionResult FindSomething(string search) { ... }

您现在可以将其与如下所示的“身份验证令牌”结合使用,这将保护该操作免受跨站点脚本和未经授权的访问:

[ValidateAntiForgeryToken(Salt = Constants.AntiForgeryTokenSalt)]
public ActionResult FindSomething(string search, string accessToken) { ... }

当然,一般情况下,“访问令牌”是通过某种形式的认证机制(即OAuth)获得的。在这种情况下,它可以是您即兴的唯一字符串传递给查看并请求返回(就像防伪令牌,但带有“随机数”,因此只能使用一次)。

于 2012-05-08T15:48:08.860 回答