公共面向REST的身份验证机制

时间:2012-09-11 00:02:42

标签: javascript web-services rest authentication

我正在设计一项新服务,使“客户”能够为他们执行的特定搜索注册并支付每次使用费。将使用RESTFul和SOAP接口公开此服务。通常,Web服务将与客户的网站集成,然后暴露给“公共”,任何人都可以使用客户的网站,并利用我的Web服务功能(客户将支付但完全控制调节)请求所以他们不会收取太多费用。)

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

理想

  1. 不使用OAuth
  2. 避免强迫客户创建内部代理,以重新公开我已经使用的相同Web服务API。
  3. 安全(令牌用户名/通过任何和ssl)
  4. 在客户网站中嵌入一个javascript库 - 这将是一个客户端Javascript库,使集成步骤更加容易。
  5. Javascript库需要足够安全,以便公众无法简单地获取凭据并自行重新使用
  6. 如果可能的话,不要太苛刻,因此如果Firefox 87出来(将在几分钟内发布)并决定使其成为fubar,则不必重新构建Web服务。
  7. 这似乎需要某种3方式身份验证过程才能工作,即对特定客户端(公共),Web服务(客户)和Web服务进行身份验证。

    有没有人实现类似的东西,他们是如何解决这种情况的呢?

    我也理解在可以做什么和违反跨域安全性之间存在平衡,因此整个Web服务可能会被另一个仅返回JSONP数据的GET接口公开。

    / ** 附录 ** /

    我发现了一个可以完成我正在照顾的Web服务。但是,我不完全了解实施细节。所以也许有人也可以详细说明我的想法。

    我发现的Web服务似乎在服务端托管了Javascript。然后,客户将其网站与服务端集成,方法是将Javascript包含在脚本标记中,但提供密钥即可。

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

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

    干杯

2 个答案:

答案 0 :(得分:3)

首先 - 让我为你提供昨天我回答的another SO question的链接 - 因为它给出了类似问题集的相当广泛的答案。

我假设您要对搜索所在的网站的所有者收取费用,而不关心个人用户是谁制作者搜索。如果这不正确,请澄清,我会相应地更新我的答案。

显然,在任何此类情况下,您需要做的首要事情是确保您知道每个请求上的客户端。并且 - 正如您所说,您还希望确保自己免受跨站点攻击和人们窃取用户密钥的侵害。

您可能会考虑以下内容:

  1. 在您身边创建一个私钥 - 只有您的服务知道。
  2. 每当新的消费者网站创建一个帐户时,请创建一个新的共享密钥,只有您和他们才能知道。我建议您使用私钥作为密码来创建此密钥,并加密某种标识符,以便识别此特定用户。
  3. 作为注册过程的一部分,请让消费者网站告诉您他们将使用您的脚本使用哪个URI。
  4. 现在 - 您进行跟踪和身份验证的方式变得相当简单。

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

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

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

    在您收到此请求时,请检查以下内容:

    1. 当您使用私钥解密共享密钥时,您不应该受到胡言乱语。如果你这样做 - 这是因为他们的密钥已经以某种方式被改变 - 并且无效。这会导致401: Unauthorized错误。
    2. 解密密钥后,知道这是哪个客户端站点(因为密钥包含的内容) - 检查以确保请求来自客户端注册的同一URI。现在,这可以保护您免受窃取密钥并将其注入其他网站的人的侵害。
    3. 只要上述内容匹配,就让他们下载文件。
    4. 现在 - 当你提供JS文件时,你可以通过将密钥注入该文件的方式来实现 - 因此它可以访问他们的共享密钥。在每个AJAX请求中,包含该密钥,以便您可以确定此请求来自哪个客户端。在RESTful环境中,实际上不应该有会话 - 因此您需要在每个帖子上进行此级别的身份验证。我建议把它作为一个cookie包含在内。

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

      那就是说 - 如果你期望很多的流量 - 你可能想回到这个并在未来探索更深层次的安全流程,因为滚动你自己的安全矩阵可能会留下意想不到的漏洞。然而 - 这是一个良好的开端,会让你开始。

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

答案 1 :(得分:1)

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

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

*用户可以包含指向您的服务器的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文件中检查令牌是否与请求域匹配,如果是,则回显js lib,如果没有抛出错误或其他什么

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

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

编辑:

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

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

这样的东西

如果您想使用此方法,您仍应检查引荐来源以防止CSRF en.wikipedia.org/wiki/Cross-site_request_forgery

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

相关问题