我使用Spring创建了一些REST,并使用JWT实现了Security以进行身份验证。我的前端运行AngularJs,并使用这些接收JSON响应的rest API。JWT身份验证工作良好,但它允许简单地将请求参数和头从浏览器的控制台复制和粘贴到Postman或任何其他REST客户端,甚至可以从后端从受保护的API获取成功的响应。
我试图通过在JWT中使用JTI声明来解决这个问题。我计划为每个请求后身份验证使用不同的JTI值,这样简单地从浏览器中窃取头就不能工作了。
现在,在浏览了大量在线可用的资源之后,我仍然不清楚客户机还是服务器应该在JWT中设置JTI值。
根据我的理解,如果我在服务器端这样做,我将不得不发送一个包含每个响应的新JWT,并在客户端的下一个请求中期待它,同时在数据库中维护一个使用过的JTI的记录。但是,如果攻击者发现了这一点,他们只需使用来自上一次请求的令牌,然后就可以轻松地与我的API交互。
另一方面,如果我在客户端这样做,我必须在javascript代码中保存JWT的秘密签名密钥和生成JTI的逻辑,以便它可以追加JTI值并再次散列令牌。我的问题是:
任何帮助都是非常感谢的。已经坚持了很长时间了。
发布于 2017-11-29 18:24:27
我无法与Java/Spring对话,但我可以尝试澄清您对JWT和JTI声明的关注。
实现JTI以唯一标识JWT有助于防止攻击者发送相同的JWT来发出请求的重放攻击。服务器将生成JTI值,并在每个响应上连同一个新的JWT一起发送它。当接收到新请求时,服务器必须验证JTI值(以确保它以前没有被使用过)。实现这一点确实需要服务器上的某种持久性存储,这种存储看起来或多或少类似于传统会话,因此感觉有点奇怪,因为JWT的一个明显优点是“无状态应用程序”。
您对中间人攻击的关注是绝对正确的:如果有人拦截了JWT (以及它的单用途JTI),然后在您之前发出请求,那么他们的请求将被认为是有效的,您随后的请求在服务器看来是“重放”的(而服务器会认为它们无效)。
https://stackoverflow.com/questions/44658963
复制相似问题