【问题标题】:REST API token authenticationREST API 令牌认证
【发布时间】:2013-02-25 15:29:14
【问题描述】:

我刚刚开始在 .NET 中开发我的第一个 REST API。由于它将是无状态的,我将使用令牌进行身份验证:

基本思想(System.Security.Cryptography):

  • AES 用于加密 + HMACSHA256 用于完整性
  • 令牌数据将包含具有以下属性的对象:用户名、发行日期和超时
  • 数据库将保存用户名、哈希密码和 HMAC 哈希

登录:

  • 检查凭据是否有效(用户名,将散列密码与 db 值进行比较)
  • 如果为真,加密数据对象
  • 在生成的令牌上使用 HMAC 并将其存储到数据库中
  • 将令牌(不带 HMAC)返回给用户(cookie/字符串)

对需要身份验证的方法的请求:

  • 用户随每个请求发送令牌
  • 令牌已解密
  • 如果过期,报错
  • 如果未过期,请使用 HMAC 并将用户名 + 生成的哈希值与 db 值进行比较
  • 如果数据库检查有效,则用户已通过身份验证

在我看来,这种方法有以下优点:

  • 即使 db 被破坏,它也不包含实际的令牌(哈希无法反转...)
  • 即使攻击者拥有令牌,他也无法通过更新字段来增加过期时间,因为过期日期在令牌本身中

首先,我想知道这是否是一种好方法。

除此之外,我仍然没有弄清楚,在服务器上存储 AES 和 SHA256 密钥的位置(我应该硬编码它们吗?如果我将它们放入 web.config 或使用机器密钥,那么在加载时我会遇到问题平衡的服务器,...)。

最后我在哪里存储 AES IV 向量,因为 Crypto.CreateEncryptor 需要它来解密?是不是意味着用户每次请求都要发送token + IV?

我希望这是有道理的,我提前感谢您的回答。

更新:

好的,现在我做了更多研究并得出了这个解决方案:

  • 令牌将包含最初指定的数据(用户名、发行日期和超时)
  • token是用encrypt-then-mac生成的(它包括AES加密数据,IV向量+这2个值的标签用于认证,用HMACSHA265生成)
  • token 标签将被写入 db
  • 如果满足以下条件,用户将被验证:
    • 标签有效(令牌认证)
    • 数据可以解密
    • 令牌尚未过期
    • 标签与数据库中写入的标签匹配
    • 用户未在数据库中被阻止(令牌按需失效)
  • 密钥将存储在 web.config 的单独部分中。每个服务器上都必须有相同的密钥(当然是每个应用程序)

我没有使用 FormsAuthenticationTicket,因为在 .NET 中存在以下问题:

【问题讨论】:

  • 我很好奇,为什么将数据存储在令牌中?如果您必须针对数据库进行验证,那么为什么不将数据存储在数据库中并简单地使用 Guid 或其他随机令牌?
  • 由于令牌过期日期 - 我想确保它不能在数据库中更新 + 如果它已经过期,你不必进行数据库查询。
  • 您应该查看 OAuth (oauth.net),因为这基本上就是您在此处描述的内容。
  • @MikeCaron,感谢您的评论。您是否有一个很好的示例来说明如何为自定义用户存储库实现它(为了支持我试图用自己的逻辑实现的功能必须做些什么)?我不想支持使用 Twitter、FB 等帐户访问我的 API。用户必须注册。
  • @PavleGartner 从服务的角度来看:您可以选择您的权限,而客户将不得不使用这些凭据。如果您希望该权限成为您自己的数据库,那很好。只需自己进行验证!

标签: c# api rest aes token


【解决方案1】:

这是问题下方评论线程的后续跟进。

您似乎对 OAuth 到底是什么有点困惑,所以希望我能在这里澄清一下。

OAuth 不是网络服务或您使用的东西。它是一种协议,描述了站点可以根据服务对用户进行身份验证的方式,而无需让站点知道用户的凭据是什么。作为附带的好处,大多数 OAuth 提供者还有一个 Web 服务来查询用户的信息,并且可以同时授予这样做的权限。

通常,您有兴趣从站点(例如 AcmeWidgets.com)的角度实施 OAuth,以便用户可以通过 Facebook 或 Google 或其他方式登录。但是,您也可以实现服务端(例如 Facebook 通常所在的位置),并允许其他人针对您进行身份验证。

例如,假设您有一个网络服务,允许第三方网站为用户提供 Acme 品牌的小部件。您的第一个第三方实现者是流行的 MyBook.org。流程看起来像这样:

  1. 有人邀请用户在其 MyBook 个人资料中使用“Acme Widgets”应用。
  2. 用户单击该按钮,该按钮将重定向到 AcmeWidgets.com。 URL 类似于:

    http://acmewidgets.com/oauth/user?r=http%3A%2F%2Fmybook.org%2Foauth%2Fclient&appid=12345

  3. 系统询问用户是否允许 MyBook 访问他们的数据和配置小部件。
  4. 用户单击“是”,Acme Widgets 随即指出用户已允许这样做。
  5. 用户被重定向回 MyBook,网址如下:

    http://mybook.org/oauth/client?token=ABCDEFG

  6. MyBook,在服务器端,现在获取该令牌,并将 Web 服务调用 BACK 到 AcmeWidgets:

    http://acmewidgets.com/oauth/validate?token=ABCDEFG&appid=12345&appsecret=67890

  7. AcmeWidgets 回复最终身份验证令牌来标识用户。
  8. 或者,它失败了,这意味着用户正在尝试伪造令牌,或者他们拒绝了权限或其他一些失败情况。
  9. MyBook 现在可以使用令牌调用 AcmeWidgets API:

    http://acmewidgets.com/api/provision?appid=12345&token=ABC123&type=etc

这被称为 OAuth 舞蹈。请注意,这里有许多实现定义的东西,例如 URL、各种令牌的编码方式、令牌是否可以过期或被撤销等。

希望这可以为您解决所有问题!

【讨论】:

  • 谢谢,解释得很好
  • 网络第一名,我发现 OAuth 协议描述清楚且简短!
猜你喜欢
  • 1970-01-01
  • 2019-04-11
  • 2017-01-24
  • 1970-01-01
  • 1970-01-01
  • 2013-01-28
  • 2023-03-29
  • 2021-08-03
  • 2017-11-27
相关资源
最近更新 更多