c# - 基于 token 的身份验证的签名/加密如何用于无状态服务器(REST)

标签 c# encryption asp.net-web-api token basic-authentication

我的客户端都是浏览器。 所有客户端仅呈现一个从 Web API 获取数据的页面应用程序。 API 的设计遵循 REST 原则。

这是我的身份验证流程:

  1. 我的登录 View 使用基于 SSL 的基本身份验证。

  2. 如果用户发送的用户名和密码有效,我将 token 字符串放入响应中

  3. 此 token 存储在客户端的本地存储中

  4. 对服务器 API 的资源端点的每个进一步请求都包含 token 。

  5. 在我对 token 进行进一步调查(例如检查其到期日期)之前:

  6. 我需要知道 token 的真实性是否仍然有效或有人修改了它。这假设 token 之前是用 key 签名的。

  7. 我需要解密加密的 token 。

问题 1) 第 6 步和第 7 步使用 SSL 是否有意义?

问题 2) 让我们假设第 6 步和第 7 步有意义,那么我会执行以下操作:

当成功登录后创建例如 json 网络 token (JWT) 时,我使用 key 对其进行签名。此 key 位于服务器上的某处,可能存储在 xml 文件或单例类中。

无论我在创建 token 时将此签名 key 存储在何处,我都必须使用相同的 key 来验证 token 。这同样适用于 token 的加密。怎么可能在用户基础上对 token 使用不同的签名 key 。这意味着每个经过身份验证的登录都会获得一个带有单独签名 key 的 token 。

下次用户请求资源端点时,我想知道 token 是否仍然具有真实性。但我只能使用创建 token 时使用的相同签名 key 来检查这一点。

问题 3)这个签名 key 应该存储在哪里?

最佳答案

如果你使用 JWT,你有不同的安全可能性:

  1. 签署 token (参见 JWS)。在这种情况下,中间人仍然可以读取此 token 的内容但无法修改它,因为他没有对其进行签名的 key ,并且当服务器检查 token 的真实性时,它将检测到它具有被篡改
  2. 加密 token (参见 JWE )。在这种情况下,中间人无法读取 token 的内容,也无法修改其内容。

在您的案例中使用 SSL 可确保 token 不会被中间人窃取。因此,除非您在此 token 中存储了一些 super secret 信息,否则对其进行签名就足够了。显然签名 key 应该只存储在服务器上,而不是与世界其他地方共享。

就您关于根据用户使用不同 key 签署 token 的问题而言,我认为这没有必要。

我个人会使用仅包含最少信息的 JWT token ,例如 expjti声明并使用 key 对其进行签名。然后我将使用此 token 的值作为服务器上键/值存储中的键(可以是某些缓存实现,如 memcached 或 NoSQL DB)并将用户名和任何其他必要信息关联到此 token 。该值将在 token 有效期内缓存。当客户端将 JWT token 发送到服务器时,服务器将验证 token 的签名以确保其值未被篡改,然后在缓存中查找关联的用户信息。

关于c# - 基于 token 的身份验证的签名/加密如何用于无状态服务器(REST),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21652392/

相关文章:

C# Core 1.1 Web API 接收 zip 文件

c# - 文本框点击事件不会在 Windows 8 上触发鼠标单击

c# - 值不能为空。错误

c# - 带有 Sql Server 列级加密的 Entity Framework

Java 公钥大小

asp.net - 如何在 Web API 的服务上下文中访问用户?

c# - 我很难将我的 IEnumerable<T> 实现切换到 ICollection<T>

java - 如何使用来自 php 服务器的十六进制公钥在 Android 中使用 RSA 加密

从加密的 PDF 中提取 Python 数据

c# - 在消息处理程序中添加属性值