我有一个jsp包含一个jquery post到我的tomcat服务器上的一个servlet,它创建了一个HttpServletRequest
。我想确保只有我的jsp对我的servlet的调用被处理,并且任何来自非jsp的源的请求都被忽略。 是否有保证的方式来查看调用我的服务器的引用页面是什么?我读过使用request.getHeader("referer")
可以欺骗,所以我知道我不能依靠这一点。谁在呼叫我的HttpServletRequest?
回答
生成一个唯一的字符串作为标记,将其存储在会话中,并将其作为隐藏的输入值嵌入到JSP的POST表单中,最后在标记有效的情况下检查servlet。
基本上:
在创建会话(在HttpSessionListener#sessionCreated()
,例如):
Set<String> tokens = new HashSet<String>();
event.getSession().setAttribute("tokens", tokens);
在JSP请求的预处理(在HttpServlet#doGet()
,例如):
String token = UUID.randomUUID().toString();
Set<String> tokens = (Set<String>) request.getSession().getAttribute("tokens");
tokens.add(token);
request.setAttribute("token", token);
在处理JSP本身:
<input type="hidden" name="token" value="${token}" />
在窗体的后处理提交(以HttpServlet#doPost()
为例):
String token = request.getParameter("token");
Set<String> tokens = (Set<String>) request.getSession().getAttribute("tokens");
if (!tokens.remove(token)) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
// ...
当然我假设你jQuery.post()
函数都写在一个不显眼的方式为$.post(form.action, form.serialize(), callback)
,这样它模拟完全正常同步请求(换句话说,你的表单在JS禁用的情况下工作得很好)。
您可以将安全令牌呈现给您的JSP,并将其包含在您可以验证它的Servlet的Ajax调用中。这也不能保证Ajax调用是使用浏览器和Javascript完成的,但它至少需要有人在进行调用之前从JSP获取安全令牌。
建议使用类似的概念来减轻CSRF。
您可以为您的jsp创建一个随机cookie,然后将其附加到您的POST表单,并只接受具有正确cookie值的请求。
这实际上比其他提到的解决方案更安全。 Upvoting。 – Perception 2012-01-03 20:38:00
@Perception:请注意,HTTP会话本身已经由“随机cookie”支持。 – BalusC 2012-01-04 13:52:20
@BalusC - 通常是真的(有些使用URL重写)。我的主要观点是cookie会被未经授权的客户欺骗,而不是嵌入在HTML页面中的令牌。 – Perception 2012-01-04 14:20:59
只是一些语义。请求通常从显示您的JSP的浏览器创建。您不能阻止另一个程序请求您的JSP,并使用您提供的任何信息再次请求。
您可以停止在用户浏览器中查看的另一个网页执行对您网站的请求。这被称为Cross-site request forgery。您可以缓解这种情况。
因此,根据您要阻止的内容,CSRF解决方案可能适合您。您可以从Web服务器中找到预制解决方案。例如,这里是Tomcat's
- 1. 谁叫我的RPC?
- 2. 谁呼叫自动释放池
- 3. 呼叫来电呼叫
- 4. 呼叫在Xcode
- 5. 呼叫在IE
- 6. 呼叫在freebsd
- 7. 呼叫在AsyncIllegalStateException
- 8. 呼叫在AngularJS
- 9. 呼叫在PHP
- 10. 呼叫在WebSphere
- 11. C#Outlook - 呼叫被拒绝的呼叫
- 12. http呼叫中的角度http呼叫
- 13. Api呼叫请求每小时呼叫限制1个呼叫
- 14. 谁叫atexit()?
- 15. 谁叫didFinishLaunchingWithOptions?
- 16. 检测呼叫与星号和谁打来的电话
- 17. 呼叫从我Timer.Tick事件
- 18. 呼叫
- 19. 呼叫
- 20. 错误呼叫在
- 21. 呼叫在用C
- 22. 在python子呼叫
- 23. Twilio网络挂接(的NodeJS) - 在呼入呼叫,通过呼叫的SID
- 24. 的参数在呼叫
- 25. 呼叫在的NodeJS时间
- 26. 在android中的呼叫块
- 27. 呼叫在Magento的扩展
- 28. 添加的功能,我的XML呼叫
- 29. 呼叫的iFrame JS
- 30. 呼叫的jQuery $就
非常感谢您的回复。我必须承认我是jquery的新手,所以我不确定这种方法是否适用于我的问题。在我的jsp我有这样的[code] [/ code]。所以我不清楚如何传递你所描述的令牌。谢谢。 – Steve 2012-01-03 20:47:21
哦,你正在使用一个servlet作为web服务。这实际上不是你问题中提到的“jQuery post”。这只是一个GET请求。什么时候这被调用?在页面加载期间只有一次?或多次用户交互? – BalusC 2012-01-04 13:51:56
对不起,我感到困惑。它实际上是基于javascript定时器(在循环中使用setTimeout方法)调用的。每隔几秒钟,就会调用“$ .getJSON ...”根据返回的json对象来更新jsp上的状态。 – Steve 2012-01-04 21:19:26