springboot 项目前后端接口,防止xss攻击以及跨域问题解决

1、启动类添加注解

@ServletComponentScan

2、cors的拦截类

package com.longfor.hrssc.api.config;

import com.longfor.hrssc.common.util.ResultUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component; import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set; @Component
@PropertySource("classpath:application-dev.yml")
@WebFilter(urlPatterns = "/*", filterName = "CorsFilter")
public class CorsFilter implements Filter { @Value("${bpm.fiter.domain}")
private String allowDomains; @Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest reqs = (HttpServletRequest) req; // 设置允许多个域名请求
//String[] allowDomains = {"http://www.xxxx.xin","http://xxxx:8080","http://localhost:8080"};
String[] allowDomain = allowDomains.split(",");
Set allowOrigins = new HashSet(Arrays.asList(allowDomain));
String curOrigin = reqs.getHeader("Origin");
/*if("null".equalsIgnoreCase(curOrigin)){
curOrigin = "http://xxxxxx:8888";
}*/
if(allowOrigins.contains(curOrigin) || null == curOrigin){
//设置允许跨域的配置
// 这里填写你允许进行跨域的主机ip(正式上线时可以动态配置具体允许的域名和IP)
response.setHeader("Access-Control-Allow-Origin", curOrigin);
response.setHeader("Access-Control-Allow-Credentials", "true");
//response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT"); response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, OPTIONS, PATCH"); response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, token");
chain.doFilter(reqs, response); }else{
throw new IOException(ResultUtils.doFilter().toString());
} } @Override
public void init(FilterConfig filterConfig) {} @Override
public void destroy() {}
}

3、xss相关类

XssFilter
package com.longfor.hrssc.api.config;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException; /** * XSS过滤器 * @author Jozz */
@WebFilter(filterName="xssFilter",urlPatterns="/*")
public class XssFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException { } @Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)servletRequest; String path = request.getServletPath();
//由于我的@WebFilter注解配置的是urlPatterns="/*"(过滤所有请求),所以这里对不需要过滤的静态资源url,作忽略处理(大家可以依照具体需求配置)
String[] exclusionsUrls = {".js",".gif",".jpg",".png",".css",".ico"};
for (String str : exclusionsUrls) {
if (path.contains(str)) {
filterChain.doFilter(servletRequest,servletResponse);
return;
}
} filterChain.doFilter(new XssHttpServletRequestWrapper(request),servletResponse);
}
@Override public void destroy() { }
}
XssHttpServletRequestWrapper
package com.longfor.hrssc.api.config;

/**
* Created by 裴帅楠 on 2019/7/10.
*/
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
//import org.apache.commons.text.StringEscapeUtils;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*; import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern; /** * ServletRequest包装类,对request做XSS过滤处理
* @author Jozz
*
* */ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
public XssHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
}
@Override
public String getHeader(String name) {
return StringEscapeUtils.escapeHtml4(super.getHeader(name));
} @Override
public String getQueryString() {
return StringEscapeUtils.escapeHtml4(super.getQueryString());
} @Override public String getParameter(String name) {
return StringEscapeUtils.escapeHtml4(super.getParameter(name));
} @Override
public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name);
if(values != null) {
int length = values.length;
String[] escapseValues = new String[length];
for(int i = 0; i < length; i++){
escapseValues[i] = StringEscapeUtils.escapeHtml4(values[i]);
}
return escapseValues;
}
return values;
} @Override
public ServletInputStream getInputStream() throws IOException {
String str=getRequestBody(super.getInputStream());
Map<String,Object> map= JSON.parseObject(str,Map.class);
Map<String,Object> resultMap=new HashMap<>(map.size());
for(String key:map.keySet()){
Object val=map.get(key);
if(null != val){
stripXss(val.toString());
} if(map.get(key) instanceof String){
resultMap.put(key,StringEscapeUtils.escapeHtml4(val.toString()));
}else{
resultMap.put(key,val);
}
}
str=JSON.toJSONString(resultMap); final ByteArrayInputStream bais = new ByteArrayInputStream(str.getBytes());
return new ServletInputStream() {
@Override
public int read() throws IOException {
return bais.read();
} @Override
public boolean isFinished() {
return false;
} @Override
public boolean isReady() {
return false;
} @Override
public void setReadListener(ReadListener listener) { }
};
} private String getRequestBody(InputStream stream) {
String line = "";
StringBuilder body = new StringBuilder();
int counter = 0;
// 读取POST提交的数据内容
BufferedReader reader = new BufferedReader(new InputStreamReader(stream, Charset.forName("UTF-8")));
try {
while ((line = reader.readLine()) != null) {
body.append(line); counter++;
}
} catch (IOException e) {
e.printStackTrace();
} return body.toString();
} private static List<Pattern> patterns = null; public static String stripXss(String value) {
if(StringUtils.isNotBlank(value)) {
Matcher matcher = null;
for(Pattern pattern : getPatterns()) {
matcher = pattern.matcher(value);
// 匹配
if(matcher.find()) {
// 删除相关字符串
value = matcher.replaceAll("");
}
}
value = value.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
}
/* if (LOG.isDebugEnabled()) {
LOG.debug("strip value: " + value); return value;
}*/
return value;
} private static List<Object[]> getXssPatternList() {
List<Object[]> ret = new ArrayList<Object[]>();
ret.add(new Object[]{"<(no)?script[^>]*>.*?</(no)?script>", Pattern.CASE_INSENSITIVE});
ret.add(new Object[]{"eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL});
ret.add(new Object[]{"expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL});
ret.add(new Object[]{"(javascript:|vbscript:|view-source:)*", Pattern.CASE_INSENSITIVE});
ret.add(new Object[]{"<(\"[^\"]*\"|\'[^\']*\'|[^\'\">])*>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL});
ret.add(new Object[]{"(window\\.location|window\\.|\\.location|document\\.cookie|document\\.|alert\\(.*?\\)|window\\.open\\()*", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL});
ret.add(new Object[]{"<+\\s*\\w*\\s*(oncontrolselect|oncopy|oncut|ondataavailable|ondatasetchanged|ondatasetcomplete|ondblclick|ondeactivate|ondrag|ondragend|ondragenter|ondragleave|ondragover|ondragstart|ondrop|onerror=|onerroupdate|onfilterchange|onfinish|onfocus|onfocusin|onfocusout|onhelp|onkeydown|onkeypress|onkeyup|onlayoutcomplete|onload|onlosecapture|onmousedown|onmouseenter|onmouseleave|onmousemove|onmousout|onmouseover|onmouseup|onmousewheel|onmove|onmoveend|onmovestart|onabort|onactivate|onafterprint|onafterupdate|onbefore|onbeforeactivate|onbeforecopy|onbeforecut|onbeforedeactivate|onbeforeeditocus|onbeforepaste|onbeforeprint|onbeforeunload|onbeforeupdate|onblur|onbounce|oncellchange|onchange|onclick|oncontextmenu|onpaste|onpropertychange|onreadystatechange|onreset|onresize|onresizend|onresizestart|onrowenter|onrowexit|onrowsdelete|onrowsinserted|onscroll|onselect|onselectionchange|onselectstart|onstart|onstop|onsubmit|onunload)+\\s*=+", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL});
return ret;
}
private static List<Pattern> getPatterns() {
if (patterns == null) {
List<Pattern> list = new ArrayList<Pattern>();
String regex = null;
Integer flag = null;
int arrLength = 0;
for(Object[] arr : getXssPatternList()) {
arrLength = arr.length; for(int i = 0; i < arrLength; i++) {
regex = (String)arr[0]; flag = (Integer)arr[1]; list.add(Pattern.compile(regex, flag));
}
}
patterns = list;
}
return patterns;
} }

4、yml中配置

#bpm域名过滤
bpm:
fiter:
domain: http://xxx.sit,https://xxxxx.net:8089,http://xxxxx.sit:8088,http://xxxxx:8888,https://xxxxx:8443

5、返回

/**
* 跨域白名单
* @return
*/
public static ResultUtils doFilter() {
return new ResultUtils(Constants.doFilterCode, Constants.doFilterException, null);
}

6、自定义code

public static final int doFilterCode  = 403;
public static final String doFilterException = "请申请IP白名单";
												

最新文章

  1. loadrunner agent 中删除失效的mmdrv进程
  2. 常用中文字体 Unicode 编码
  3. 串口总是报&#39;Error opening serial port&#39;
  4. android 多级下拉菜单实现教程
  5. PHP出错界面详细说明
  6. css修改滚动条默认样式
  7. ubuntu16 网络设置
  8. HDU-1864-最大报销额
  9. 写个神经网络,让她认得我`(๑•ᴗ•๑)(Tensorflow,opencv,dlib,cnn,人脸识别)
  10. 关于string.h中字符串的操作
  11. 走进Linux01-磁盘分区与文件夹结构
  12. geopyspark入门
  13. go语言之行--golang操作redis、mysql大全
  14. 14.Odoo产品分析 (二) – 商业板块(7) –制造(1)
  15. Selenium自动化测试,接口自动化测试开发,性能测试从入门到精通
  16. phpstudy手动把mysql数据库从5.5.56升级到5.6.41
  17. Arria10中PHY的时钟线结构
  18. Thinkphp5笔记一:项目部署
  19. MySQL分区(Partition)功能
  20. python group()--转载

热门文章

  1. 【转载】 CUDA_DEVICE_ORDER 环境变量说明 ( ---------- tensorflow环境下的应用 )
  2. 用selenium自动加载浏览器下载图片
  3. base64加密后无法解密
  4. LwIP应用开发笔记之五:LwIP无操作系统TCP服务器
  5. 大数据 -- kafka学习笔记:知识点整理(部分转载)
  6. [转]解决 gem install 安装失败
  7. ng2 空标签
  8. Ubuntu下重启mysql
  9. python 异常处理(25)
  10. Matlab 非线性规划问题模型代码