Spring MVC中防止csrf攻击的拦截器示例

时间:2022-12-10 23:49:19
package com.hikvision.cms.pms.base;

import java.util.HashSet;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.hikvision.cms.pms.common.log.PmsLogRecord;
import com.hikvision.cms.pms.common.util.SysConfigUtil;

/**
* @description 拦截csrf攻击
* @date 2017年1月18日上午11:47:46
* @version
*/

public class CsrfInterceptor extends HandlerInterceptorAdapter {
private static final String URL_PROTO_HTTP="http://";
private static final String URL_PROTO_HTTPS="https://";
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
String referer = request.getHeader("Referer");
String port = "-1";
if(StringUtils.isNotBlank(referer)){
if(referer.startsWith(URL_PROTO_HTTP)){
referer = referer.replace(URL_PROTO_HTTP, "");
}else if(referer.startsWith(URL_PROTO_HTTPS)){
referer = referer.replace(URL_PROTO_HTTPS, "");
}
int i = referer.indexOf("/");
if(i > 0){
referer = referer.substring(0,i);
if(referer.indexOf(":") > 0){ //referer 10.20.147.80:7888 -> 10.20.147.80只验证ip
port = referer.split(":")[1];
referer= referer.substring(0, referer.indexOf(":"));
}
PmsLogRecord.logDebug("pmsCsrfInterceptor referer:{}",referer);
}
if(!getPlatDomains().contains(referer)){ //不同域请求 视为非法
if(!SysConfigUtil.PMS_PORT.equals(port)){
throw new Exception("非法请求,请求源不正确");
}
}
}
return true;
}

private Set<String> getPlatDomains() {
Set<String> domains = new HashSet<String>();
//add apache代理地址
String cmsIp = SysConfigUtil.BYTERRIVER_IP;
if(StringUtils.isNotBlank(cmsIp)){
domains.add(cmsIp);
}
//多网域未考虑
//add 服务节点自身 ip或者域名地址
return domains;
}

}

springmvc-servlet.xml中的配置如下:
<mvc:interceptors>
<bean class="com.hikvision.cms.pms.base.CsrfInterceptor" />
</mvc:interceptors>