日期:2014-05-17  浏览次数:20860 次

struts2表单重复提交的问题
本帖最后由 zhangqh2012 于 2013-04-26 10:24:36 编辑
自己做了个网站,最近经常被攻击,主要现象就是表单提交没有经过表单的onsubmit,直接就提交了,不大清楚这是怎么做到的,哪位能给解释下?
另外也出现了表单重复提交,我用js控制了防止重复提交但是看来没起作用。不知道他们是怎么做到的?
为了解决以上问题,我想到了struts2的<s:token/>标签和防止重复提交拦截器,用起来报错java.lang.NullPointerException
org.apache.struts2.util.TokenHelper.setToken(TokenHelper.java:71)
查了下资料是因为配置了     
<dispatcher>REQUEST</dispatcher> 
<dispatcher>FORWARD</dispatcher> 
这是我用urlrewrite做的配置,去掉的话urlrewrite就不起作用了。
http://www.hopercorner.com 好望角 这是我的网站,“关于好望角”这个栏目中的表单提交经常被攻击。求各位帮想想办法,最近几天一到晚上网站就打不开了,实在愁人,不知道该怎么办,哪位能帮帮我啊!
Struts 网站攻击

------解决方案--------------------
应该不是这个问题,看下你的web.xml配置
------解决方案--------------------
使用<s:token/>时,action要继承ActionSupprot才不会报空指针
或者直接用<s:tokenSession/>
------解决方案--------------------
1.你在form表单中写上<s:token>
2.在struts.xml中相对应提交表单的action中写上
<interceptor-ref name="token"></interceptor-ref>
3.在全局跳转中写上<result name="invalid.token">重复提交后所提示的页面</result>
------解决方案--------------------
以下是我以前解决的,没有用框架:你参考参考。
在客户端,可以使用js脚本语言让用户提交一次后,按钮变灰。
form表单的写法:
<form id='f1' action=” RegistServlet” method=’post’>
……………
<input id='bt1' type='button' value='注册' onclick='toSubmit()'/>
</form>
     js实现提交一次后按钮变灰
<script type='text/javascript'>
function toSubmit(){
document.getElementById('f1').submit();//按钮具备提交功能
document.getElementById('bt1').disabled=true;//提交一次变灰
}
</script>

md5算法的实现
MessageDigest md = MessageDigest.getInstance("md5");
byte b[] = md.digest(message.getBytes());
BASE64Encoder base64 = new BASE64Encoder();
return base64.encode(b);//采用Base64编码转换字节序列为明文。

可以在提交表单中增加一个type是hidde,来存储md5的算法后的数据,然后用session同时去存储md5的算法后的数据。数据指纹的算法好处是数据无论怎么变,长度始终一样。
<input type='hidden' name='token' value='"+token+"'/>
----------------------------------------------------------------------
//生成一个随机的令牌
String token = ""+System.currentTimeMillis()+new Random().nextLong();
//算数据指纹,用MD5算法。
token = MD5Util.md5(token);
//放入HttpSession中
request.getSession().setAttribute("token", token);

验证表单提交的hidde类型的令牌与服务器的令牌是否一致。
String formToken = request.getParameter("token");
String sessionToken = (String) request.getSession().getAttribute("token");
if(formToken.equals(sessionToken)){
//正常提交
System.out.println("保存了:"+name);
request.getSession().removeAttribute("token");
}else{
out.write("请不要重复提交");
}

------解决方案--------------------
引用:
终于解决了!
struts2过滤器使用org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter即可,之前使用的FilterDispatcher这个过滤器太老了,看来新版过滤器解决了这个问题。
分享出来,希望遇到同样问题的同学少走点弯路

谢谢楼主分享