|
@ -0,0 +1,114 @@
|
|
|
|
package com.yihu.jw.gateway.filter;
|
|
|
|
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
|
|
import javax.servlet.*;
|
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.net.MalformedURLException;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.regex.Matcher;
|
|
|
|
import java.util.regex.Pattern;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Created by yeshijie on 2022/3/15.
|
|
|
|
*/
|
|
|
|
@Component
|
|
|
|
public class CsrfFilter implements Filter {
|
|
|
|
private Logger log = LoggerFactory.getLogger(CsrfFilter.class);
|
|
|
|
/**
|
|
|
|
* 过滤器配置对象
|
|
|
|
*/
|
|
|
|
FilterConfig filterConfig = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 是否启用
|
|
|
|
*/
|
|
|
|
@Value("${security.csrf.enable}")
|
|
|
|
private boolean enable;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 忽略的URL
|
|
|
|
*/
|
|
|
|
private List<String> excludes = new ArrayList<>();
|
|
|
|
|
|
|
|
public void setExcludes(List<String> excludes) {
|
|
|
|
this.excludes = excludes;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 初始化
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public void init(FilterConfig filterConfig) throws ServletException {
|
|
|
|
this.filterConfig = filterConfig;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 拦截
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
|
|
|
|
throws IOException, ServletException {
|
|
|
|
HttpServletRequest request = (HttpServletRequest) servletRequest;
|
|
|
|
HttpServletResponse response = (HttpServletResponse) servletResponse;
|
|
|
|
|
|
|
|
String referer = request.getHeader("Referer");
|
|
|
|
String host = request.getServerName();
|
|
|
|
// 不启用或者已忽略的URL不拦截
|
|
|
|
if(!enable ||referer == null||referer.indexOf("http://ehr.yihu.com")==0
|
|
|
|
||referer.indexOf("https://zhyzh.gongshu.gov.cn")==0
|
|
|
|
||referer.indexOf("27.154.233.186")>0
|
|
|
|
||referer.indexOf(host)>0){
|
|
|
|
filterChain.doFilter(servletRequest, servletResponse);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
java.net.URL url = null;
|
|
|
|
try {
|
|
|
|
url = new java.net.URL(referer);
|
|
|
|
} catch (MalformedURLException e) {
|
|
|
|
// URL解析异常,也置为404
|
|
|
|
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 判断是否存在外链请求本站
|
|
|
|
if (!host.equals(url.getHost())) {
|
|
|
|
log.error("CSRF过滤器 => 服务器:{} => 当前域名:{}", host, referer);
|
|
|
|
servletResponse.setContentType("text/html; charset=utf-8");
|
|
|
|
servletResponse.getWriter().write("系统不支持当前域名的访问!");
|
|
|
|
} else {
|
|
|
|
filterChain.doFilter(servletRequest, servletResponse);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 销毁
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public void destroy() {
|
|
|
|
this.filterConfig = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 判断是否为忽略的URL
|
|
|
|
*
|
|
|
|
* @param url URL路径
|
|
|
|
* @return true-忽略,false-过滤
|
|
|
|
*/
|
|
|
|
private boolean isExcludeUrl(String url) {
|
|
|
|
if (excludes == null || excludes.isEmpty()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return excludes.stream().map(pattern -> Pattern.compile("^" + pattern)).map(p -> p.matcher(url))
|
|
|
|
.anyMatch(Matcher::find);
|
|
|
|
}
|
|
|
|
}
|