Java 如何在JWT中正确使用JTI声明以防止重播攻击?

Java 如何在JWT中正确使用JTI声明以防止重播攻击?,java,angularjs,spring,spring-security,jwt,Java,Angularjs,Spring,Spring Security,Jwt,我使用Spring创建了一些RESTAPI,并使用JWT实现了Spring安全性以进行身份验证。我的前端运行AngularJs并使用这些RESTAPI来接收JSON响应。JWT身份验证工作正常,但它允许将请求参数和头从浏览器控制台简单地复制和粘贴到Postman或任何其他REST客户端,以便从后端甚至从受保护的API获取成功响应 我试图通过在JWT中使用JTI声明来解决这个问题。我计划对每个请求后身份验证使用不同的JTI值,这样简单地从浏览器中窃取头就不起作用了 现在,在浏览了大量在线可用资源之

我使用Spring创建了一些RESTAPI,并使用JWT实现了Spring安全性以进行身份验证。我的前端运行AngularJs并使用这些RESTAPI来接收JSON响应。JWT身份验证工作正常,但它允许将请求参数和头从浏览器控制台简单地复制和粘贴到Postman或任何其他REST客户端,以便从后端甚至从受保护的API获取成功响应

我试图通过在JWT中使用JTI声明来解决这个问题。我计划对每个请求后身份验证使用不同的JTI值,这样简单地从浏览器中窃取头就不起作用了

现在,在浏览了大量在线可用资源之后,我仍然不清楚客户机还是服务器应该在JWT中设置JTI值

根据我的理解,如果我在服务器端执行此操作,我将不得不在每次响应中发送一个新的JWT,并在客户机的下一个请求中预期它,同时在数据库中维护已使用JTI的记录。但是,如果攻击者发现了这一点,他们只需使用以前请求中的令牌,然后就可以轻松地与我的API交互

另一方面,如果在客户端执行此操作,则必须在javascript代码中保留JWT的秘密签名密钥和JTI生成逻辑,以便它可以附加JTI值并再次散列令牌。 我的问题是:

  • 正确的实施方式是什么?我是错过了什么,还是完全走错了方向
  • 我是否可以实现其他解决方案来禁止或取消对来自非浏览器客户端的任何请求的身份验证(就像在使用JSP的旧式Spring MVC应用程序中发生的那样)

  • 非常感谢您的帮助。我已经在这个问题上纠缠了很长时间。

    我无法与Java/Spring对话,但我可以尝试澄清您对JWTs和JTI声明的担忧

    实现JTI以唯一标识JWT有助于防止攻击者发送相同的JWT以发出请求。服务器将生成JTI值,并在每次响应时将其与新的JWT一起发送。当接收到新请求时,服务器必须验证JTI值(以确保以前没有使用过该值)。实现这一点确实需要在服务器上使用某种类型的持久性存储,这看起来或多或少类似于传统会话,因此感觉有点奇怪,因为JWT的宣传优势之一是“无状态应用程序”


    你对中间人攻击的关注是绝对正确的:如果有人拦截JWT(和它的一次性使用JTI),然后在你做请求之前,他们的请求将被认为是有效的,你的后续请求将出现在服务器上“重放”(服务器将认为它们无效)。.

    我想您希望保护您的客户免受csrf的攻击,因此我建议您进一步阅读此链接:这是否意味着使用JTI的唯一好处是存储量更少?保存JTI字符串并检查它们是否已发出,而不是检查整个令牌。不,在JWTs上实现唯一标识符(JTI)的好处是一个安全好处——实现一个正确创建、存储,检查JTIs需要更多的资源/存储,因为正确的实现将为每个JWT发出的每个请求创建一个新ID。系统不仅可以判断JWT是否有效,还可以判断以前是否使用过JWT。我想C.M.的意思是,你可以将JWT本身存储在一个数据库(或什么东西)中,以记录以前是否见过它,但可能我遗漏了什么。