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. PMP 第6章错题总结

    项目进度管理的步骤:   1.项目的商业价值指特定项目的成果能够为相关方带来的有形的或无形的效益. 其中有形的效益包括:股东权益.市场份额.货币资产 无形的效益包括:品牌认知度.商誉.战略一致性等2. ...

  2. oracle plsql 统计

    set serveroutput on DECLARE cursor cemp is select to_char(hiredate,'yyyy') from emp ; phiredate ); c ...

  3. CVI中调用VC动态库

    1.在VC环境中建立新工程,创建32位动态库(Win32 Dynamic-Link Library)  -> A simple DLL project 2.在工程中可加入别的动态库,在工程菜单中 ...

  4. element ui表格常用功能如:导出 新增 删除 多选 跨页多选 固定表头 多级表头 合并行列 等常见需求

    <template> <div class="table-cooperte"> <el-table :data="tableData&quo ...

  5. PHP设计模式 - 解释器模式

    给定一个语言, 定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子. 角色: 环境角色(PlayContent):定义解释规则的全局信息. 抽象解释器(Empress):定 ...

  6. 【Tyvj2046】掷骰子

    好水一道题 掷骰子Description Rainbow和Freda通过一次偶然的机会来到了魔界.魔界的大门上赫然写着:小盆友们,欢迎来到魔界~!乃们需要解决这样一个问题才能进入哦lala~有N枚骰子 ...

  7. Codeforces Round #581 (Div. 2)

    A:暴力. #include<cstdio> #include<cstring> #include<iostream> #include<algorithm& ...

  8. CentOS7 安装 Docker、最佳Docker学习文档

    目录 一.Docker支持 二.安装Docker -1.在新主机上首次安装Docker CE之前,需要设置Docker存储库.之后,就可以从存储库安装和更新Docker. 0.卸载旧版 1.正式安装 ...

  9. mapreduce课堂测试结果

    package mapreduce; import java.io.IOException; import java.util.StringTokenizer; import org.apache.h ...

  10. codeforces Round #568(Div.2)A B C

    有点菜,只写出了三道.活不多说,上题开干. A. Ropewalkers Polycarp decided to relax on his weekend and visited to the per ...