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

Public facing Authentication mechanisms for REST

本文关键字:身份验证 机制 REST      更新时间:2023-09-26

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

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

理想

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

似乎需要某种三向身份验证过程才能工作,即验证特定的客户端(在公众中)、web服务(客户)和web服务。

有人实施过类似的措施吗?他们是如何应对这种情况的?

我也知道可以做什么和违反跨域安全性之间存在平衡,所以整个web服务可能会被另一个只返回JSONP数据的GET接口暴露。

/**附录**/

从那以后,我发现了一个web服务,它可以做我要做的事情。然而,我不相信我完全理解实施细节。所以也许有人也可以详细阐述我的想法。

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

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

我的想法正确吗?有没有某种http头可以这样使用?这样安全吗?

干杯

首先,让我为您提供我昨天回答的另一个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环境中,不应该有真正的会话,所以您需要对每个帖子进行这种级别的身份验证。我建议把它作为饼干。

在服务器端,只需在每个后续请求上重复检查他们的密钥,瞧,你就为自己建立了一些相当严密的安全性,而不会产生太多开销。

也就是说,如果你预计会有很多流量,你可能想回到这一点,并在未来探索更深入的安全流程,因为滚动自己的安全矩阵可能会留下意想不到的漏洞。然而,这是一个良好的开端,会让你脚踏实地。

如果你需要,可以随时提出任何问题,我会相应地更新我的答案。

最好的方法是这样的(假设你想使用服务器上托管的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文件中,检查令牌是否与请求域匹配,如果是,则回显js-lib,如果不是,则抛出错误或其他

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

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

编辑:

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

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

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

理想情况下,您应该为每个用户的每个会话(如果您是偏执狂,则为每个请求)使用唯一的令牌来防止CSRF攻击。检查引用人只是通过模糊处理实现的安全性,并不是一个真正的解决方案。