5

我正在设计一项新服务,使“客户”能够注册并为他们执行的特定搜索支付每次使用类型的费用。该服务将使用 RESTFul 和 SOAP 接口公开。通常,Web 服务将与客户的网站集成,然后向“公众”公开,任何人都可以使用客户的网站并利用我的 Web 服务功能(客户需要付费但可以完全控制审核)请求,这样他们就不会被收取太多费用)。

我想设计优化集成的服务,使其尽可能简单。Web 服务 API 将发生变化,因此在某些情况下,创建一个内部代理以向公众公开 Web 服务对客户来说太过分了。所以我看到的问题是创建一个平衡身份验证、安全性和集成的 Web 服务。

理想的

  1. 不使用 OAuth
  2. 避免强迫客户创建一个内部代理来重新公开我已经拥有的相同 Web 服务 API。
  3. 安全(令牌用户名/传递任何内容和 ssl)
  4. 在客户网站中嵌入一个 javascript 库 - 这将是一个客户端 Javascript 库,使集成步骤更加容易。
  5. Javascript 库需要足够安全,这样公众就无法简单地获取凭据并自行重新使用它
  6. 如果可能的话,不要太老套,所以如果 Firefox 87 出现(将在几分钟内发布)并决定对其进行更新,则不必重新构建 Web 服务。

似乎需要某种 3 向身份验证过程才能使其工作,即对特定客户端(在公共场合)、Web 服务(客户)和 Web 服务进行身份验证。

有没有人实施过类似的事情,他们是如何解决这样的情况的?

我也明白在可以做的事情和违反跨域安全的事情之间有一个平衡,所以也许整个 Web 服务可能会被另一个只返回 JSONP 数据的 GET 接口公开。

/**附录**/

从那以后,我发现了一个 Web 服务,它可以满足我的需求。但是,我不确定我是否完全了解实施细节。所以也许有人也可以详细说明我的想法。

我发现的 Web 服务似乎在服务端托管了 Javascript。然后,客户将通过将 Javascript 包含在脚本标记中来将他们的网站与服务端集成,但提供了这样做的密钥,即

不知何故,如果我将脚本添加到我的网站,它就不起作用。因此,在某个地方,令牌必须注册到特定的客户域,而“client-lib.js”实际上是一个 servlet 或类似的东西,它可以以某种方式检测到来自“公众”的用户实际上来自“客户”域。

我的想法对吗?是否有某种可以以这种方式使用的 http 标头?那安全吗?

干杯

4

2 回答 2

3

首先-让我为您提供我昨天回答的另一个SO问题的链接-因为它为类似的问题集提供了相当广泛的答案。

我假设您要向进行搜索的站点的所有者收费,而不是太在意进行搜索的个人用户是谁。如果这不正确,请澄清,我会相应地更新我的答案。

显然,在任何这种情况下,您需要做的第一件事就是确保您知道每个请求是哪个客户端。而且 - 正如您所说,您还想确保自己免受跨站点攻击和窃取用户密钥的人的侵害。

您可能会考虑以下内容:

  1. 在您身边创建一个私钥- 只有您的服务知道。
  2. 每当一个新的消费者网站向您创建帐户时,请创建一个只有您和他们知道的新共享密钥。我建议通过使用您的私钥作为密码来创建此密钥,并加密某种标识符,以便您识别此特定用户。
  3. 作为注册过程的一部分,让消费者网站告诉您他们将在哪个 URI 上使用您的脚本。

现在 - 你们进行跟踪和身份验证的方式变得相当简单。

您提到提供一个 JS 库,每次 FF 更新时都不需要更新。我建议使用 jQuery 或其他类似支持的跨浏览器 JS 基础库构建该库 - 并让它包装您的 AJAX。

但是,当客户端站点请求您的脚本时,让他们为您提供类似的内容:

http://www.yourdomain.com/scripts/library.js?key={shared key}

就您而言,当您收到此请求时,请检查以下内容:

  1. 当您使用您的私钥解密他们的共享密钥时,您不应该乱码。如果你这样做了——那是因为他们的密钥已经以某种方式改变了——并且无效。这应该会导致错误。401: Unauthorized
  2. 一旦您解密了密钥并知道这是哪个客户端站点(因为这就是密钥所包含的内容) - 检查以确保请求来自客户端注册的相同 URI。现在,这可以保护您免受他人窃取他们的密钥并将其注入不同的网站。
  3. 只要符合上述条件,就让他们下载文件。

现在 - 当您提供 JS 文件时,您可以通过将密钥注入该文件的方式来执行此操作 - 因此它可以访问它们的共享密钥。在您的每个 AJAX 请求中,包含该密钥,以便您可以识别该请求再次来自哪个客户端。在 RESTful 环境中,实际上不应该有会话——因此您需要在每个帖子上进行这种级别的身份验证。我建议将其作为 cookie 包含在内。

在您的服务器端 - 只需在每个后续请求中重复检查他们的密钥 - 瞧 - 您已经为自己建立了一些相当严格的安全性,而没有很多开销。

也就是说 - 如果您预计会有大量流量 - 您可能希望在未来返回并探索更深入的安全流程,因为滚动您自己的安全矩阵可能会留下意想不到的漏洞。然而——这是一个好的开始,会让你起步。

如果您需要,请随时提出任何问题,我会尝试相应地更新我的答案。

于 2012-11-02T16:14:53.347 回答
1

最好的方法是这样的(假设您想使用托管在服务器上的 javascript 并使包含部分尽可能简单):

*用户在您的网站上注册并收到他的域的令牌

*用户可以包含一个指向您的服务器的 js 文件,该 js 文件将类似于:

<script type="text/javascript" src="http://your.server.com/js.php?token=###&widget=xxx"></script>

或者

<script type="text/javascript" src="http://your.server.com/js.js?token=###&widget=xxx"></script>

如果您将使用 .htaccess 进行重定向

*在php文件中检查token是否与请求域匹配,如果是则回显js库,如果不是则抛出错误或其他东西

*在 js 中,您将需要构建一些对您的服务的 ajax 调用以及操作 HTML 的东西(创建一个小部件持有者,显示一些数据等)

*所有的调用也应该有令牌,你可以再次使用相同的逻辑来检查令牌==服务器地址

编辑:

REFERER 作为 HTTP 协议的一部分由客户端的浏览器发送,因此确实不可靠。

如果您想验证请求是否来自您的站点,那么您不能,但您可以验证用户是否访问过您的站点和/或已通过身份验证。Cookie 是在 AJAX 请求中发送的,因此您可以依赖它。但这意味着您需要使用 oAuth 之类的东西

如果你想使用这个方法,你仍然应该检查引用者以防止 CSRF en.wikipedia.org/wiki/Cross-site_request_forgery

理想情况下,您应该为每个用户的每个会话使用一个唯一令牌(如果您偏执,则每个请求)来防止 CSRF 攻击。检查引用者只是混淆的安全性,而不是真正的解决方案。

于 2012-09-19T17:47:34.083 回答