SOA - 签名授权服务 - 如何使Web界面访问用户数据

时间:2012-10-06 12:27:59

标签: web-services security soa http-authentication

我设计了一个REST授权服务,其工作方式与Amazon S3 REST Authentication非常相似,并且足够安全,可以在HTTP上工作(无需开销就可以在SSL上运行所有通信)。

它足够安全,因为签名在每个请求时都会更改,并且可能会过期。所以它对MITM是安全的(不能编辑任何东西,否则端点将无法重新生成相同的签名)和重放攻击(因为时间戳的使用)。

这对所有客户都有好处,知道私钥,现在可以对他们自己的数据执行请求的操作,生成包含请求数据的唯一签名。

授权服务不生成任何令牌(因此它不受MITM攻击)并且它仅在内部调用,这意味着客户端直接向右端点执行请求以执行某些操作,而不是请求令牌给予该服务...然后接收该请求的端点向授权服务询问“嘿,请求合法吗?”如果是这样,授权服务返回“200 OK”并且服务执行请求的操作,否则返回“401 Unauthorized”。

我现在需要的是允许特殊客户端(Web用户界面)使用户使用电子邮件/密码登录并使用webUI本身来获取/编辑他们的数据。 webUI将在HTTPS上运行。请考虑创建一个新帐户始终生成user / pwd login和pubkey / privatekey,但实际上我们只使用pubkey / privatekey。用户和密码存储在将仅由WebUI使用的数据库中,而pubkey / privatekey存储在授权服务(使用另一个数据库)内。

当然,为了处理客户数据,我需要一些方法来使webUI起作用,因为它是为登录用户编写的客户端(具有生成签名的pubkey / privatekey关联对)。我不确定最安全的方法是什么,所以我将解释我应该解决的几个解决方案。

我尝试的第一个解决方案是为web界面提供自己的pubkey / privatekey,使其成为真正的客户端,然后编辑授权服务以识别它并允许它发送publickey(可以由授权服务检索) )使用像“X-Forwarded-For”这样的标题并始终信任webUI权限。但是我害怕不知怎的,我错过了一些可能导致攻击利用此权限来获取你未获得授权的数据的东西。

第二个解决方案是,一旦成功登录,将pubkey / privatekey从授权服务传输到WebUI,然后将其存储在会话中,每次执行操作时,它都会使用该数据生成有效签名。但我真的不想通过网络传递这些数据(也因为这种通信至少应该通过SSL来避免私钥被嗅探),我真的不想将私钥存储在会话后端中

我讨论的最后一个解决方案是重新考虑授权服务,并允许用户和密码进行身份验证(不再存储在webUI中,而是在授权服务中使用pubkey / privatekey)。这总是需要SSL连接,因为webui必须传递电子邮件和密码,但如果正确记录,它只能将这些数据存储在创建的会话中。另一个副作用是可以实现其他服务来使用user / pwd而不是使用签名方法,通过HTTP将意味着向世界公开数据。

我想要最强大,更合理的解决方案,这使得webUI充当客户端,因为整个架构被认为是基于客户端 - 服务器的。我也可以接受此处未列出的其他建议。

如果您需要了解更多信息,请告诉我。

谢谢(如果您已阅读整篇文章:-P)

1 个答案:

答案 0 :(得分:0)

<强> HTTPS

首先,我认为你误解了所有HTTPS的事情。使用HTTPS,您可以提供客户端证书,但在最常见的情况下,仅使用服务器证书。因此,在这种常见情况下,HTTPS不提供验证用户的方式,只提供服务器本身。它还提供消息加密。

如果您正在使用HTTP,即使您可以防止真正的MITM攻击,任何MITM都会看到您的所有消息。如果他们不被私密(某些私人数据等),也许没关系。

另一件事是验证服务器本身。从我指定的数据中我可以看到(可能是其中一些丢失或我误解了),所有请求都已签名,但响应不是(或者是它们)。在这种情况下,您很容易受到MITM攻击,因为攻击者可以伪装成您的身份验证服务器。

我建议使用HTTPS来验证服务器并编码消息和签名以验证客户端。另请注意,为了防止MITM攻击,您还必须使用来自根CA证书来检查服务器证书。

私钥

我不太明白如何启动客户端的私钥。嗯,技术 - 是的,但私钥是私密的。如果你生成它们,它们就不再是私有的。在这种情况下,您可以生成一些共享密钥,并使用一些更简单的算法来对请求进行签名。当你知道两个密钥不比共享密钥更安全时使用PPK,至少在我看来是这样。

另一种方法是允许客户端在生成后将公钥上传到服务器。

<强>密码

在我看来,授权服务器应该做出有关授权的所有决定。因此,我会在授权服务器中存储密码和公钥(或共享密钥),而不是UI部分。

<强>结论

你的情况让我想起OAuth2 protocol。有资源所有者,客户端,授权服务器和资源服务器。资源所有者以某种方式授予对客户端的访问权限,客户端从提供该授权的授权服务器获取访问令牌。然后它使用它来访问资源服务器。

您的系统中可以使用两种授权类型:资源所有者密码凭据授予和客户端凭据授予。

  • 您的资源所有者本身就是客户。
  • UI也是客户。
  • UI通过提供客户端的密码凭据获取访问令牌,然后对资源服务器进行一些调用。
  • 客户端只需使用共享密钥或公钥进行身份验证即可获取访问令牌。

当然,如果在您的情况下不完全适合,您可以从协议中获取一些想法。

至于签署请求,有MAC access authentication,可以在同一个OAuth2中使用。

所以,我建议将密码存储在授权服务器中,UI只是传递它们来修改一些资源。不要为客户端生成私钥 - 使用共享密钥或让他们上传公钥。使用HTTPS验证远程服务器。