2012-01-03 71 views
4

我有一个jsp包含一个jquery post到我的tomcat服务器上的一个servlet,它创建了一个HttpServletRequest。我想确保只有我的jsp对我的servlet的调用被处理,并且任何来自非jsp的源的请求都被忽略。 是否有保证的方式来查看调用我的服务器的引用页面是什么?我读过使用request.getHeader("referer")可以欺骗,所以我知道我不能依靠这一点。谁在呼叫我的HttpServletRequest?

回答

5

生成一个唯一的字符串作为标记,将其存储在会话中,并将其作为隐藏的输入值嵌入到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禁用的情况下工作得很好)。

+0

非常感谢您的回复。我必须承认我是jquery的新手,所以我不确定这种方法是否适用于我的问题。在我的jsp我有这样的[code] [/ code]。所以我不清楚如何传递你所描述的令牌。谢谢。 – Steve 2012-01-03 20:47:21

+0

哦,你正在使用一个servlet作为web服务。这实际上不是你问题中提到的“jQuery post”。这只是一个GET请求。什么时候这被调用?在页面加载期间只有一次?或多次用户交互? – BalusC 2012-01-04 13:51:56

+0

对不起,我感到困惑。它实际上是基于javascript定时器(在循环中使用setTimeout方法)调用的。每隔几秒钟,就会调用“$ .getJSON ...”根据返回的json对象来更新jsp上的状态。 – Steve 2012-01-04 21:19:26

0

您可以将安全令牌呈现给您的JSP,并将其包含在您可以验证它的Servlet的Ajax调用中。这也不能保证Ajax调用是使用浏览器和Javascript完成的,但它至少需要有人在进行调用之前从JSP获取安全令牌。

建议使用类似的概念来减轻CSRF

1

您可以为您的jsp创建一个随机cookie,然后将其附加到您的POST表单,并只接受具有正确cookie值的请求。

+0

这实际上比其他提到的解决方案更安全。 Upvoting。 – Perception 2012-01-03 20:38:00

+0

@Perception:请注意,HTTP会话本身已经由“随机cookie”支持。 – BalusC 2012-01-04 13:52:20

+0

@BalusC - 通常是真的(有些使用URL重写)。我的主要观点是cookie会被未经授权的客户欺骗,而不是嵌入在HTML页面中的令牌。 – Perception 2012-01-04 14:20:59

0

只是一些语义。请求通常从显示您的JSP的浏览器创建。您不能阻止另一个程序请求您的JSP,并使用您提供的任何信息再次请求。

您可以停止在用户浏览器中查看的另一个网页执行对您网站的请求。这被称为Cross-site request forgery。您可以缓解这种情况。

因此,根据您要阻止的内容,CSRF解决方案可能适合您。您可以从Web服务器中找到预制解决方案。例如,这里是Tomcat's