我有一个用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操作的访问,以便只有我的网站代码才能访问结果。现在,任何人都可以通过网络浏览器调用此操作。
关于我完成这些工作的一些选择的想法?
应该注意的是,不会登录此网站,因此不能以这种方式进行身份验证。而且我不想在与密码方法相关的html源代码中有任何内容。
为什么我要这个:
FindSomething
方法实际上调用了第三方服务,该服务是使用信用付费的。因此,实际上,通话次数越多,费用就越高。
我担心的是,如果有人知道此网址并希望使用相同的服务,那么他们可以通过我们的网址查询并避免收费。
我不确定这个第三方服务是否考虑过这个,他们提供了几种与服务交互的方式。一个是通过Web服务,我可以通过服务器代码(我正在做)和一个通过一些内联javascript引用调用 - 后者需要html源代码中的硬编码许可证密钥:S
......我可能值得为他们找一个答案,但无论我如何解决这个服务中的这个缺陷,它仍然会在SO上提出一个有趣的问题
答案 0 :(得分:3)
我担心,鉴于你的限制,没有可靠的方法来实现这一点。你可以通过使用例如防伪标记而不是100%防弹使其变得困难。不要忘记,不仅浏览器可以发送HTTP请求。任何人都可以伪造HTTP请求并将其发送到您的服务器。
使用非GUI API完成此操作的方法是将公钥提供给客户端,并且使用GUI应用程序(如网站)完成此操作的方法是为用户提供密码。
答案 1 :(得分:2)
最明智的做法是使用防伪标记+盐,如here所述:
[ValidateAntiForgeryToken(Salt = Constants.AntiForgeryTokenSalt)]
public ActionResult FindSomething(string search) { ... }
您现在可以将此与“身份验证令牌”结合使用,如下所示,这将保护针对跨站点脚本和未经授权的访问的操作:
[ValidateAntiForgeryToken(Salt = Constants.AntiForgeryTokenSalt)]
public ActionResult FindSomething(string search, string accessToken) { ... }
当然,在正常情况下,“访问令牌”是通过某种形式的身份验证机制(即OAuth)获得的。在这种情况下,它可以是您即兴传递给查看和请求的唯一字符串(就像防伪标记但使用'nonce',因此它只能使用一次)。