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白名单";
												

springboot自定义CORS&XSS拦截器的更多相关文章

  1. spring boot集成swagger,自定义注解,拦截器,xss过滤,异步调用,guava限流,定时任务案例, 发邮件

    本文介绍spring boot集成swagger,自定义注解,拦截器,xss过滤,异步调用,定时任务案例 集成swagger--对于做前后端分离的项目,后端只需要提供接口访问,swagger提供了接口 ...

  2. SpringBoot从零单排 ------ 拦截器的使用

    在项目开发中我们常常需要对请求进行验证,如登录校验.权限验证.防止重复提交等等,通过拦截器来过滤请求.自定义一个拦截器需要实现HandlerInterceptor接口.代码如下: import org ...

  3. springboot(五)过滤器和拦截器

    前言 过滤器和拦截器二者都是AOP编程思想的提现,都能实现诸如权限检查.日志记录等.二者有一定的相似之处,不同的地方在于: Filter是servlet规范,只能用在Web程序中,而拦截器是Sprin ...

  4. SpringBoot静态资源访问+拦截器+Thymeleaf模板引擎实现简单登陆

    在此记录一下这十几天的学习情况,卡在模板引擎这里已经是四天了. 对Springboot的配置有一个比较深刻的认识,在此和大家分享一下初学者入门Spring Boot的注意事项,如果是初学SpringB ...

  5. springBoot 2.X-自定义拦截器

    package com.cx.springboot.myInter; import javax.servlet.http.HttpServletRequest; import javax.servle ...

  6. 玩转SpringBoot之整合Mybatis拦截器对数据库水平分表

    利用Mybatis拦截器对数据库水平分表 需求描述 当数据量比较多时,放在一个表中的时候会影响查询效率:或者数据的时效性只是当月有效的时候:这时我们就会涉及到数据库的分表操作了.当然,你也可以使用比较 ...

  7. SpringBoot开发案例之拦截器注入Bean

    前言 由于业务需要,需要在拦截器中操作Redis缓存,按照 controller,service层配置发现无法注入,一直报空指针异常. 解决方案 @Configuration public class ...

  8. 如何在SpringBoot项目中使用拦截器

    相比springmvc,springboot中拦截器不需要在xml中配置,只需定义拦截器类 implements HandlerInterceptor 和拦截器拦截路径的配置类extends WebM ...

  9. springboot中配置了拦截器后,拦截器无效的解决方案之一

    springboot的启动类xxxApplication不能扫描到拦截器配置类,可加上@ComponentScan(basePackages={"com.maya.common"} ...

随机推荐

  1. linux命令(55):环境变量:LIBRARY_PATH 和 LD_LIBRARY_PATH的区别

    添加环境变量:https://www.cnblogs.com/lovychen/p/5583703.html PATH是可执行文件的环境变量. LIBRARY_PATH 和 LD_LIBRARY_PA ...

  2. Python3基础 内置函数 dir 查询对象的方法列表

             Python : 3.7.3          OS : Ubuntu 18.04.2 LTS         IDE : pycharm-community-2019.1.3    ...

  3. PRINT_INITA整体偏移值传变量

    打印维护和整体偏移相关博文:打印维护和整体偏移相关简短问答.打印维护开放给客户端可进行微调,结果在客户端本地.(建议开放给客户打印维护功能,调整一次,以后都会走调整后的,通过不同任务名区分模版) 如果 ...

  4. 【并行计算-CUDA开发】【视频开发】ffmpeg Nvidia硬件加速总结

    2017年5月25日 0. 概述 FFmpeg可通过Nvidia的GPU进行加速,其中高层接口是通过Video Codec SDK来实现GPU资源的调用.Video Codec SDK包含完整的的高性 ...

  5. 【并行计算-CUDA开发】GPU并行编程方法

    转载自:http://blog.sina.com.cn/s/blog_a43b3cf2010157ph.html 编写利用GPU加速的并行程序有多种方法,归纳起来有三种: 1.      利用现有的G ...

  6. [xsy3132]数表

    题意:一个$n\times m$的数表,数值$\in[0,4)$,你可以任意次选择一行或一列$+1,\text{mod }4$,要最小化所有数的和 因为$n\leq10$,所以数表可以看成$m$个$n ...

  7. 世界视频编码器大赛结果揭晓,腾讯V265编码器勇夺两项第一

    2019年10月22日,由莫斯科国立大学(Moscow State University)举办的MSU世界视频编码器大赛成绩揭晓, 腾讯内部开源协同的V265编码器再创佳绩,一举拿下PSNR(峰值信噪 ...

  8. Linux用户查询、新增&删除

    1.查询用户tail -1 /etc/passwd 2.新增用户&用户组groupadd testgroup #组的添加useradd testuser #创建用户testuserpasswd ...

  9. SQL Server 从Excel导入到数据库操作遇到的科学计数法问题

    问题描述 今天在做从Excel导入数据到SQL Server 中将数据更新到表中,可惜就这一个简单的操作中出现了一点小插曲,就在我根据Excel中的编号关联表编号以此更新姓名字段时出现转换错误问题.如 ...

  10. Spring学习指南-第二章-Spring框架基础(完)

    第二章 Spring框架基础 面向接口编程的设计方法 ​ 在上一章中,我们看到了一个依赖于其他类的POJO类包含了对其依赖项的具体类的引用.例如,FixedDepositController 类包含 ...