我使用Spring创建了一些REST API,并使用JWT实现了Spring Security以进行身份验证。我的前端运行AngularJs并使用这些接收JSON响应的其他API。 JWT身份验证工作正常,但它允许从浏览器控制台到Postman或任何其他REST客户端的请求参数和标头的简单复制和粘贴,以便从后端的受保护API获取成功的响应。
我试图通过在JWT中使用JTI声明来解决这个问题。我打算为每个请求后验证使用不同的JTI值,这样只需从浏览器中窃取标题就行不通。
现在经过在线提供的大量资源后,我仍然不清楚客户端或服务器是否应该在JWT中设置JTI值。
根据我的理解,如果我在服务器端执行此操作,我将不得不在每次响应时发送一个新的JWT,并在客户端的下一个请求中期望它,同时在数据库中保留已使用的JTI的记录。但是,如果攻击者发现这一点,他们只需要使用先前请求中的令牌,然后他们就可以轻松地与我的API进行交互。
另一方面,如果我在客户端执行此操作,我必须在javascript代码中保留JWT的秘密签名密钥和JTI生成逻辑,以便它可以附加JTI值和再次哈希令牌。 我的问题是:
非常感谢任何帮助。现在已经坚持了很长时间。
答案 0 :(得分:5)
我无法与Java / Spring对话,但我可以尝试澄清您对JWT和JTI声明的担忧。
实施JTI以唯一标识JWT有助于防止攻击者发送相同JWT以发出请求的replay attacks。服务器将生成JTI值,并在每个响应上将其与新的JWT一起发送。当收到新请求时,服务器必须验证JTI值(以确保它之前没有使用过)。实现这一点确实需要在服务器上使用某种持久存储,这看起来或多或少类似于传统会话,所以感觉有点奇怪,因为JWT的一个广告好处是无状态应用程序"。 / p>
你对中间人攻击的关注是绝对正确的:如果有人拦截JWT(及其一次性使用的JTI)然后在你做之前提出请求,他们的请求将会被视为有效,您的后续请求将显示给服务器"重播" (并且服务器会认为它们无效)。