受损的 JSON Web 令牌 (JWT) 不记名令牌

信息安全 验证 oauth 休息 json
2021-08-15 14:50:38

我们正在实现一个需要身份验证和授权的 REST 服务。由于 REST API 的无状态特性,我们希望使用 JWT 通过令牌对 API 进行经过身份验证的调用,而无需为每个 API 调用访问数据库。

在评估了 JWT 之后,我们有一些问题:

  1. 您如何处理客户端和服务器之间共享的令牌机密泄露的情况?
  2. 您是否注销所有客户端并为将来的请求定义新的令牌密码?(那将是一个糟糕的体验)
  3. 有没有办法只注销受感染的客户端?

背景细节:我们将在 iOS 应用程序和 Node.js 后端之间使用该流程。

4个回答

要回答您的问题:

1)您如何处理客户端和服务器之间共享的令牌机密泄露的情况?

为您的令牌添加到期日期。确保令牌在过期时间后无法使用。但这并不能防止在令牌有效期内进行未经授权的访问。

因此,为了克服这个问题,您可以在令牌中嵌入客户端的 IP 地址或其他此类信息。并确保带有令牌的传入请求是从发出它的同一 IP 地址使用的。

2)您是否注销所有客户端并为将来的请求定义新的令牌密码?(那将是一个糟糕的体验)

如果您的意思是注销所有以授权方式使用多个令牌的客户端,那么不。您可以继续同时使用多个令牌,前提是您有一个有限的令牌到期期限。这确保您的令牌在预期的时间范围内使用。

但是,如果您的意思是令牌被盗并且您以某种方式弄清楚了。最好使该用户的所有令牌无效。

但是,您可能希望有一种机制可以在特殊情况下显式撤销所有令牌。可能就像用户重置他的密码,因为他认为他的密码可能被泄露。

3) 有没有办法只注销受感染的客户端?

可能是,取决于您准确识别哪个令牌已被泄露的能力。这可能会导致所有使用该令牌的客户端失去访问权限。但是,我不会推荐它。但是,嘿,您总是可以编写代码,当旧客户端不能再使用令牌时,动态重新验证并获取新的访问令牌。:-)

必要时不要害怕使令牌无效。如果您丢失了令牌,请编写动态脚本以重新进行身份验证。如果您认为在使用新令牌时可能会丢失会话详细信息,请在重新验证时将过期的令牌重新发送到服务器。使用此过期令牌,您可以使用旧令牌的会话详细信息重建新令牌。前提是您在过期令牌中嵌入了会话详细信息。

如果您希望能够在其到期日期之前撤销之前授予的令牌(一个有效的安全问题),您需要包含一个数据库查找,这否定了 JWT 的主要优势之一,所以您可能决定不首先使用它们。

这是一篇关于这个案例的文章:https ://www.dinochiesa.net/?p=1388

就我而言,我也将令牌存储在我的数据库中。

在此处输入图像描述

在初始身份验证期间,用户发送用户名密码。验证凭据,然后生成存储在数据库中的令牌,并将令牌发送给客户端。在每个客户端请求中,我都会验证我的数据库中是否也存在该用户的令牌。

如果客户端注销并想要撤销令牌,我只需从身份表中删除令牌。

JWT 令牌可以解码,所有信息都可以读取为 json 格式,例如:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.
TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

第一部分是标题: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

{
  "alg": "HS256",
  "typ": "JWT"
}

第二部分是有效载荷: eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

最后一部分是创建为的签名:

//In our example, the algorithm is (HS256)
signature = algorithm(hash of (header + payload), secret)

现在,它只是隐藏在令牌签名中的密钥,那么,我们得出结论:

  1. KEY 应妥善保管,不得泄露给任何人。
  2. 如果 JWT 令牌用于身份验证,则必须通过 SSL/TLS 使用。
  3. 未经signature密钥验证,不得信任 JWT 令牌
  4. JWT token 的 ISSUER 不得将敏感信息放入 JWT token 中,以防仅对 JWT 使用的信息进行签名。

阿卡哈斯

1)您如何处理客户端和服务器之间共享的令牌机密泄露的情况?

使用 SSL/TLS(安全连接)并根据您的登录系统使每个令牌过期。每次用户登录创建 JWT 令牌时,JWT 令牌必须用作永久令牌。

2)您是否注销所有客户端并为将来的请求定义新的令牌密码?(那将是一个糟糕的体验)

如果您的密钥被泄露,您必须创建新的密钥并通过发出注销更新活动会话并强制系统重新验证所有活动用户。