在澄清一些想法后,问题更多地集中在正确使用JWT上。
让我们只讨论编码(未加密)的JWT,让我们只考虑使用对称密钥的HMAC
,让我们称之为p@$$w0rd
这将用于签署JWT。
我们知道JWT不应该包含敏感信息,因为它们不会隐藏任何数据,因为有效负载只有Base64编码,它们只能通过signature
来验证信息来自正确的客户。
在我们的例子中,我们发送role
是为了显示/隐藏Web应用程序中的某些元素
在具有admin
角色的用户中,将看到创建/修改/删除用户等的链接作为示例。
的方案
A
- > admin
用户,在登录时从服务器(颁发者)请求JWT
Server
- >向JWT提出userID
,userName
,role
声明且声明到期日期。
A
- >应该在对server
的所有进一步API请求时发送此JWT令牌,服务器将使用此令牌进行身份验证。
B
- >是非管理员用户,并遵循相同的程序。
B
知道A
是管理员用户,并且知道userID
和userName
。这很有可能,没有敏感信息。
JWT只声明Base64编码,如果客户端也知道secret p@$$w0rd
,则客户端可以轻松生成令牌。我们知道验证者server
只重新编码已编码的JWT(来自客户端)以匹配使用该秘密发送的 upon login
。
通过https
,我们可以确定第三方或中间人无法知道这个秘密或任何其他信息,所以让我们把它放在一边。
#1
B
修改了自己的令牌并将角色更改为admin
的角色,并且只允许管理员用户使用API调用。
Server
很容易使此令牌无效,因为重新散列会失败,因为发送给B
的原始令牌已被修改,当我们修改令牌时,签名也随之改变有效载荷也是如此。
#2
作为恶意用户的 B
会创建一个令牌,以便将A
的令牌与A
的所有详细信息进行匹配,并且只允许管理员用户使用API请求。
server
将成功验证该令牌,并了解其A
。
如何防止这种情况?
我们是否应该使用id
声明作为有效载荷的一部分,并且是唯一的
不能轻易猜到?由于这个B
无法推导出来
正确的声明集以创建确切的A
令牌。虽然
这种方法更多地涉及存储这个额外的ID
每个用户并在服务器上进行身份验证。
我们是否应该透露用于签署JWT的secret
密钥,所以
客户端可以创建令牌吗?
我们知道,与Basic Authorization
相比,JWT肯定是一种更好的身份验证方式,password
在每个具有更大攻击窗口的API请求中也会发送用户的Base64编码df
。
答案 0 :(得分:1)
选项#2 - 如果永远不使用对称密钥,则在客户端以任何方式不安全的情况下向客户端公开它们,特别是如果客户端是Web应用程序。不要给出对称密钥是个好主意。 JWT应该在服务器上制造,即用对称密钥预先签名,然后提供给客户端。客户可以通过某种形式的身份验证通过安全API请求JWT,或者您可以通过其他方式创建JWT并向客户端发送。
我们两个都做。已经过身份验证的域用户可以通过API调用请求到期的JWT。域外的用户可以通过可以访问API调用的域上的已批准管理员专门为他们提供JWT。在任何时候都没有暴露对称密钥。
此过程开始复制OAuth的某些方面,因此您可能需要调查OAuth服务器/供应商,这就是我们的目标。