5

我正在为一些开发实现一组 RESTful 服务,其中一个是身份验证服务

身份验证服务对两种身份进行身份验证:

  • 应用程序基于 AppKey 的身份验证,因此客户端必须注册密钥才能访问其余服务
  • 用户基于众所周知的凭据(用户+密码)的用户身份验证,因此人类和机器可以通过客户端应用程序使用这些 RESTful 服务。

这些 RESTful 服务无状态的。

当客户端应用程序针对身份验证服务进行身份验证时,或者当人或机器使用凭据作为身份进行身份验证时,这两个操作都会分别生成AppTokenUserToken

这些令牌是加盐哈希,因此对 RESTful 基础架构的后续请求将在不共享AppKey凭据的情况下进行身份验证。

从完全无状态方法的角度来看,这些令牌不应该存储在服务层的任何位置,而是以某种客户端状态(fe,Web 客户端将使用HTTP cookie存储它)。这就是我当前的实现现在的工作方式

因为使用这些令牌重新验证每个请求并让服务层接收来自客户端的令牌,因此它可以比较来自客户端的令牌检查它是否是在服务层重新生成它的有效令牌并与客户拥有的太贵了,我已经实现了一个服务层AppTokenUserToken,两者都有一个到期日期和一个所有者(为其创建令牌的应用程序或用户),以检查令牌是否来自客户端的存在于令牌存储中。

客户端如何以交互方式取消身份验证? 只是删除客户端安全状态。如果是 Web 客户端,它会丢弃身份验证 cookie 并刷新页面,客户端检测到没有身份验证 cookie 并将用户重定向到登录页面。

从 RESTful 服务的角度来看,这是一种无状态的非身份验证:客户端不知道拥有服务层伪身份验证状态的技巧。它只是一个服务实现细节——一个性能优化——。

我不会列出无状态服务的优点,因为我绝对确定这种方法是可行的,但我发现了一个问题:无状态身份验证/未身份验证意味着客户端不会通知服务器他们关闭会话,所以安全存储以很多无用的记录结束

如果服务客户端的会话时间有限(fe、1 小时、3 小时、一天...),这不是一个大问题,但是如果用户必须永远进行身份验证(8 个月、一年)会发生什么) ? . 你如何区分什么是过期的令牌?

有一些方法可以解决这种情况:

  1. 每当服务层收到请求时,它都会更新令牌到期日期,因此自动化过程可能会丢弃那些已过期的令牌,定义令牌的任意到期时间(fe 24 小时)

  2. 妥协架构的无状态特性,让客户端通知服务层他们不想再被验证,因此服务可以将关联的令牌丢弃到客户端会话但是等等......如果客户端关闭 Web 客户端会发生什么?用户永远不会主动通知服务必须丢弃令牌......所以......僵尸令牌还在那里,所以自动化过程应该丢弃它们,但是......什么是僵尸令牌?我不喜欢这种方法

  3. 完全无状态身份验证,无存储,按请求身份验证。

这就是问题!你建议的方法是什么 - 即使不是 1.、2. 或 3. - 为什么?

感谢您的长时间阅读-老实说,我相信该问题的结论对任何人都非常有用-!

4

2 回答 2

7

第三

无状态身份验证,基于令牌。假设传输级加密。

  • [X]SS-- X 由 S 的公钥签名
  • [X|Y]-- X 和 Y 在同一个信封中
  • Y [M]SY -> S-- Y 将签名消息 M 发送给 S。

目标: 客户 C 希望与服务 S 通话。

  1. 客户端 C 将其共享密钥或公钥发送给服务 A,C 知道服务 A 的端点和公钥 ( )。PKCPKA

  2. A [now + interval | user-id or PKC]SA -> C

    解释:

    服务 A 为当前日期/时间添加一个间隔作为到期。在要发送的缓冲区中现在是到期日期和用户 ID (假设您有一个有效的身份提供者)。PKC

    [now + interval | user-id or PKC] = T

    A 签名;

    [T]SA

  3. 客户端 C 希望与后端服务 S 对话。

  4. C [[M|[T]SA]SC -> S

    C 将消息 M 和它从 A 签署的令牌发送到服务 S。

  5. S 关心 C 确实发送了它,并验证了它从信封中读取的 C 的签名。SC

    S 验证令牌的签名。失败意味着请求被拒绝。SA

    S 验证令牌:用户 ID/正确且令牌日期 >= 现在。过期令牌意味着向客户端 C 发送“令牌过期”消息。如果令牌签名错误,则权限被拒绝。[T]SAPKC

    (可选;S 授权 C,题外话)

  6. S 执行工作并发送回客户端 C。[M2]SS

这不会有太多开销;验证签名是一个非常快的操作。

证书

问题“ C# Sign Data with RSA using Bouncy Castle ”显示了您如何签署和验证一段字符串,即您发送的消息。

您将需要证书;如果您正在使用配置管理器(您应该这样做!;)),例如 puppet,那么您创建一个证书签名请求 (CSR),然后使用 puppet 对其进行签名

特别是关于未经身份验证的帖子

有一种叫做证书撤销请求的东西,它基本上是一个已被撤回且不被信任/使用的公钥的洗衣清单。放在那里并广播撤销,它基本上通过要求客户端进行另一轮证书签名请求来执行。PKC

此外,如果您希望能够使特定令牌T过期,请在创建令牌时向令牌添加唯一 ID (UUID/GUID) ,并拥有一个令牌撤销列表,在更改时类似地广播,您可以在令牌 UUID 时清除它们到期。因此,如果接收到的 T 在其中,服务还将检查令牌撤销列表。

基于哈希的令牌

看看软件巨头在做什么。例如 Amazon 的 REST 接口,它使用共享密钥:

Amazon S3 REST API 使用基于密钥 HMAC(哈希消息身份验证代码)的自定义 HTTP 方案进行身份验证。要对请求进行身份验证,您首先连接请求的选定元素以形成一个字符串。然后,您使用您的 AWS 秘密访问密钥来计算该字符串的 HMAC。非正式地,我们将此过程称为“签名请求”,我们将 HMAC 算法的输出称为“签名”,因为它模拟了真实签名的安全属性。最后,使用本节中描述的语法将此签名添加为请求的参数。

阅读有关亚马逊计划的更多信息。

上面的颠覆/攻击向量

  • 我最初描述的方案需要 SSL,它容易受到众多证书颁发机构以及许多其他东西的攻击。
  • 您很容易受到重放攻击,即中间人重新发送消息。如果您的 REST 接口是幂等的,那么您是安全的。如果您向请求添加服务器已知的加密随机数,您也是安全的。
于 2012-08-30T07:04:29.470 回答
-1

选择的方法:完全无状态的身份验证和非身份验证

最后,我得到了一个结论和一个协议,以便切换到整个完全无状态的基于令牌的身份验证和非身份验证。

如何实现?

首先,这是您需要对应用程序进行基于令牌的无状态身份验证(但用户身份验证将以相同的方式工作,不包括此清单):

  • 一个应用程序注册系统。应用程序是对您的服务的访问。它是“您的应用程序访问网络上的某些服务(内联网、互联网、云......)。这是创建应用程序密钥(跳过此进行用户身份验证)。
  • 服务器证书,因此客户端到服务的连接使用 HTTPS/SSL 进行加密。

这是验证应用程序的流程:

  1. 客户端向身份验证服务发送身份验证请求。此请求必须包含应用程序密钥 (AppKey)

  2. 身份验证服务接收先前发送的请求。

  3. 现在,身份验证服务创建一个应用程序令牌(AppToken),它是必要信息的自描述串联,用于跟踪具体的经过身份验证的客户端到依赖于身份验证服务的服务。

  4. AppToken是一个复合字符串(这个组合可以是一个使用 JSON 序列化的对象):

    • 应用程序哈希(*a SHA - 或其他 - 这是连接一些应用程序信息的结果。这个信息将是服务机密 +到期日期(它是令牌本身的一部分)。为什么到期日期?。想象一下中间人或其他东西可以破坏安全并修改令牌的过期时间?当加密令牌被解密以验证请求时,再次哈希过期日期+ AppKey的结果将不再产生相同的哈希,因此令牌无效。
    • 发行日期。创建令牌时的当前 UTC 日期+时间。
    • 到期日。令牌将不再有效的 UTC DateT+Time。
  5. 身份验证服务加密第 4 步结果(JSON 序列化对象)。**使用 AppKey 作为对称密码的密钥或密码。就我而言,我将为此使用 Rijndael。

  6. 后续请求将包含此令牌以避免发送纯文本凭据。这些请求也将始终包含AppKey,因此身份验证服务将能够识别正在尝试对请求进行身份验证的应用程序。

  7. 一段时间后,令牌过期或无效,客户端请求新的 AppToken。或者客户端被用户关闭并且没有可以保存安全令牌的持久存储,因此下一个客户端会话将在需要时请求新的。


有关此类身份验证方法的 .NET 实现的一些提示和详细信息:

  • 我已经使用System.Security.Cryptography.RijndaelManaged类进行对称加密。AppKey 和 AppToken (在基于令牌的用户身份验证的情况下,它几乎是相同的解决方案)都是使用RijndaelManaged类生成的。

  • 加密文本被转换为 HEX 字符串。这与身份验证响应一起发送。在我们的例子中(一个 RESTFul API),代表AppToken的 HEX 字符串将作为响应头发送。每当请求包含此 HEX 字符串时,身份验证过程会将其重新转换为原始加密文本,然后将其解密以评估令牌是否有效。


感谢 Henrik 的努力。我在您自己的答案中采用了一些概念,并将它们与我自己的结论混合在一起。

于 2012-09-04T09:50:11.090 回答