标签:
struts2 token 不仅能够有效防止表单重复提交,而且还可以进行 CSRF 验证。以最新版的 2.3.20 为例。我们在 struts.xml 对某 action 加 <interceptor-ref name="token"></interceptor-ref> 标签,事实上是配置了 org.apache.struts2.interceptor.TokenInterceptor 拦截器。查看其 doIntercept 源码:
	protected String doIntercept(ActionInvocation invocation) throws Exception {
		if (log.isDebugEnabled()) {
			log.debug("Intercepting invocation to check for valid transaction token.");
		}
		
		//see WW-2902: we need to use the real HttpSession here, as opposed to the map
		//that wraps the session, because a new wrap is created on every request
		HttpSession session = ServletActionContext.getRequest().getSession(true);
		
		synchronized (session) {
			if (!TokenHelper.validToken()) {
				return handleInvalidToken(invocation);
			}
		}
		return handleValidToken(invocation);
	}	public static boolean validToken() {
		String tokenName = getTokenName();
		
		if (tokenName == null) {
			if (LOG.isDebugEnabled()) {
				LOG.debug("no token name found -> Invalid token ");
			}
			return false;
		}
		
		String token = getToken(tokenName);
		
		if (token == null) {
			if (LOG.isDebugEnabled()) {
				LOG.debug("no token found for token name "+tokenName+" -> Invalid token ");
			}
			return false;
		}
		
		Map session = ActionContext.getContext().getSession();
		String sessionToken = (String) session.get(tokenName);
		
		if (!token.equals(sessionToken)) {
			if (LOG.isWarnEnabled()) {
				LOG.warn(LocalizedTextUtil.findText(TokenHelper.class, "struts.internal.invalid.token", ActionContext.getContext().getLocale(), "Form token {0} does not match the session token {1}.", new Object[]{token, sessionToken}));
			}
			
			return false;
		}
		
		// remove the token so it won‘t be used again
		session.remove(tokenName);
		
		return true;
	}	public static String getTokenName() {
		Map params = ActionContext.getContext().getParameters();
		
		if (!params.containsKey(TOKEN_NAME_FIELD)) {
			if (LOG.isWarnEnabled()) {
				LOG.warn("Could not find token name in params.");
			}
			
			return null;
		}
		
		String[] tokenNames = (String[]) params.get(TOKEN_NAME_FIELD);
		String tokenName;
		
		if ((tokenNames == null) || (tokenNames.length < 1)) {
			if (LOG.isWarnEnabled()) {
				LOG.warn("Got a null or empty token name.");
			}
			
			return null;
		}
		
		tokenName = tokenNames[0];
		
		return tokenName;
	}	public static String getToken(String tokenName) {
		if (tokenName == null ) {
			return null;
		}
		Map params = ActionContext.getContext().getParameters();
		String[] tokens = (String[]) params.get(tokenName);
		String token;
		
		if ((tokens == null) || (tokens.length < 1)) {
			if (LOG.isWarnEnabled()) {
				LOG.warn("Could not find token mapped to token name " + tokenName);
			}
			return null;
		}
		
		token = tokens[0];
		
		return token;
	}<script>
var strutsToken = "<s:property value="#session[‘struts.tokens.token‘]" />";
var token = {
  "struts.token.name": "token",
  "token": strutsToken
};
$.ajax({
  url: ‘/endpoint‘,
  data: token,
  dataType: ‘jsonp‘,
  cache: true,
  success: function() { console.log(‘success‘); },
  error: function() { console.log(‘failure‘); }
});
</script><td>
	<a href="findSigleDetail.action?TransId=${value.transid}&struts.token.name=token&token=
		<s:property value="#session[‘struts.tokens.token‘]" />" title="Edit Meta"><img src="frame/image/pencil.png"
		alt="Edit Meta" />查看详细</a>
</td>标签:
原文地址:http://blog.csdn.net/defonds/article/details/42460925