我的客户端都是浏览器。 所有客户端只渲染单个页面应用程序从Web API获取数据。 API的设计遵循REST原则。
这是我的身份验证流程:
我使用SSL进行基本身份验证作为登录视图。
如果用户发送的用户名和密码有效,我会在回复中添加一个令牌字符串
此令牌存储在客户端的本地存储中
对服务器API的ressource端点的每个进一步请求都包含令牌。
在我使用令牌进行进一步调查之前,例如检查其到期日期:
我需要知道令牌的真实性仍然有效或有人修改过它。这假定令牌之前已使用密钥签名。
或者
我需要解密加密的令牌。
问题1)使用SSL,步骤6和7是否有意义?
问题2)让我们假设步骤6和7有意义,然后我会做以下事情:
创建成功登录后的json web token(JWT)时,我用密钥签名。此密钥位于服务器上的某个位置,可能存储在xml文件或单个类中。
在创建令牌时,只要我存储此签名密钥,我就必须使用相同的密钥来验证令牌。这对于令牌的加密也是有效的。如何在用户的基础上为令牌使用不同的符号键是如何可能的。这意味着每个经过身份验证的登录都会获得一个带有单独签名密钥的令牌。
下次用户请求资源端点时,我想知道令牌是否仍具有真实性。但我只能使用创建令牌的相同符号键来检查这一点。
问题3)该签名密钥应存放在哪里?
答案 0 :(得分:4)
如果你使用JWT,你有不同的安全可能性:
JWS
)。在这种情况下,中间人仍然可以读取此令牌的内容,但无法修改它,因为他没有密钥签名,当服务器检查令牌的真实性时,它会检测到它有JWE
)。在这种情况下,中间人无法读取令牌的内容,也无法修改其内容。在您的情况下使用SSL可以确保令牌不会被中间人偷走。因此,除非您在此令牌中存储了一些超级机密信息,否则签名就足够了。显然,签名密钥只应存储在服务器上,不能与世界其他地方共享。
关于根据用户使用不同密钥签署令牌的问题,我不认为这是必要的。
我个人会使用一个JWT令牌,它只包含exp
和jti
声明等最小信息,并用密钥签名。然后我将使用此标记的值作为服务器上的键/值存储中的键(可能是某些缓存实现,如memcached或NoSQL DB),并将用户名和任何其他必要信息关联到此标记。该值将在令牌的有效期内被缓存。当客户端将JWT令牌发送到服务器时,服务器将验证令牌的签名以确保其值未被篡改,然后将其查找为相关用户信息的缓存。
答案 1 :(得分:0)
SSL可以防止中间人被篡改,但最终用户自己呢?我不相信任何人,包括最终用户。任何邪恶的最终用户都可以从公共计算机或其他人那里劫持令牌,只需将令牌发送回服务器即可。如果您对安全性要求没有问题,那么SSL就足够了。
但是,人们使用术语令牌来表示任何类型的blob。但是软件安全令牌应该是声明的容器。如果确实使用令牌来存储声明,则通过验证签名来检查完整性非常重要。即使是合法用户也可以添加虚假声明并通过HTTPS将令牌推送到服务器。
每个用户都可以拥有一个密钥。您可以将它存储在任何您想要的地方。但是你需要确保密钥的安全性。