一、Maven依赖,我把所有的依赖贴出来了,大家可以自行删减
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-starter-thymeleaf
net.sourceforge.nekohtml
nekohtml
1.9.22
org.javassist
javassist
3.22.0-GA
org.springframework
spring-jdbc
5.1.2.RELEASE
mysql
mysql-connector-java
5.1.43
com.alibaba
fastjson
1.2.51
com.alibaba
druid
1.1.9
二、拦截器
CrosXssFilter.java
package com.ctg.test.cros.springbootcros.filter;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
/**
* 跨域:由于浏览器的安全性限制,不允许AJAX访问 协议不同、域名不同、端口号不同的 数据接口;
* 前后端都需要设置允许跨域
*/
@WebFilter
public class CrosXssFilter implements Filter {
// 多个跨域域名设置
public static final String[] ALLOW_DOMAIN = {"http://localhost:8080",
"http://localhost:8090", "http://localhost:8081","http://127.0.0.1:8020"};
private static final Logger logger = LoggerFactory.getLogger(CrosXssFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//跨域设置
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String originHeader = req.getHeader("Origin");
if (Arrays.asList(ALLOW_DOMAIN).contains(originHeader)) {
//通过在响应 header 中设置 ‘*’ 来允许来自所有域的跨域请求访问。
res.setHeader("Access-Control-Allow-Origin", originHeader);
//通过对 Credentials 参数的设置,就可以保持跨域 Ajax 时的 Cookie
//设置了Allow-Credentials,Allow-Origin就不能为*,需要指明具体的url域
res.setHeader("Access-Control-Allow-Credentials", "true");
//请求方式
res.setHeader("Access-Control-Allow-Methods", "*");
//(预检请求)的返回结果(即 Access-Control-Allow-Methods 和Access-Control-Allow-Headers 提供的信息) 可以被缓存多久
res.setHeader("Access-Control-Max-Age", "86400");
//首部字段用于预检请求的响应。其指明了实际请求中允许携带的首部字段
//res.setHeader("Access-Control-Allow-Headers", "*");
res.setHeader("Access-Control-Allow-Headers", "Timestamp,Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token,Access-Control-Allow-Headers");
}
//sql,xss过滤
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
Cookie[] cookies = httpServletRequest.getCookies();
logger.info(".......sessionid:{},session:{}",httpServletRequest.getSession().getId(), JSONObject.toJSONString(httpServletRequest.getSession().getAttributeNames()));
logger.info(".......,cookie:{}",JSONObject.toJSONString(httpServletRequest.getCookies()));
logger.info("CrosXssFilter.......orignal url:{},ParameterMap:{}", httpServletRequest.getRequestURI(), JSONObject.toJSONString(httpServletRequest.getParameterMap()));
XssHttpServletRequestWrapper xssHttpServletRequestWrapper = new XssHttpServletRequestWrapper(
httpServletRequest);
chain.doFilter(xssHttpServletRequestWrapper, response);
logger.info("CrosXssFilter..........doFilter url:{},ParameterMap:{}", xssHttpServletRequestWrapper.getRequestURI(), JSONObject.toJSONString(xssHttpServletRequestWrapper.getParameterMap()));
}
@Override
public void destroy() {
}
}
XssHttpServletRequestWrapper.java 防止sql注入
package com.ctg.test.cros.springbootcros.filter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* 防止sql注入,xss攻击
* 前端可以对输入信息做预处理,后端也可以做处理。
*/
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
private final Logger log = LoggerFactory.getLogger(getClass());
private static String key = "and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+";
private static Set notAllowedKeyWords = new HashSet(0);
private static String replacedString="INVALID";
static {
String keyStr[] = key.split("\\|");
for (String str : keyStr) {
notAllowedKeyWords.add(str);
}
}
private String currentUrl;
public XssHttpServletRequestWrapper(HttpServletRequest servletRequest) {
super(servletRequest);
currentUrl = servletRequest.getRequestURI();
}
/**覆盖getParameter方法,将参数名和参数值都做xss过滤。
* 如果需要获得原始的值,则通过super.getParameterValues(name)来获取
* getParameterNames,getParameterValues和getParameterMap也可能需要覆盖
*/
@Override
public String getParameter(String parameter) {
String value = super.getParameter(parameter);
if (value == null) {
return null;
}
return cleanXSS(value);
}
@Override
public String[] getParameterValues(String parameter) {
String[] values = super.getParameterValues(parameter);
if (values == null) {
return null;
}
int count = values.length;
String[] encodedValues = new String[count];
for (int i = 0; i < count; i++) {
encodedValues[i] = cleanXSS(values[i]);
}
return encodedValues;
}
@Override
public Map getParameterMap(){
Map values=super.getParameterMap();
if (values == null) {
return null;
}
Map result=new HashMap<>();
for(String key:values.keySet()){
String encodedKey=cleanXSS(key);
int count=values.get(key).length;
String[] encodedValues = new String[count];
for (int i = 0; i < count; i++){
encodedValues[i]=cleanXSS(values.get(key)[i]);
}
result.put(encodedKey,encodedValues);
}
return result;
}
/**
* 覆盖getHeader方法,将参数名和参数值都做xss过滤。
* 如果需要获得原始的值,则通过super.getHeaders(name)来获取
* getHeaderNames 也可能需要覆盖
*/
@Override
public String getHeader(String name) {
String value = super.getHeader(name);
if (value == null) {
return null;
}
return cleanXSS(value);
}
private String cleanXSS(String valueP) {
// You'll need to remove the spaces from the html entities below
String value = valueP.replaceAll("<", "<").replaceAll(">", ">");
value = value.replaceAll("<", "& lt;").replaceAll(">", "& gt;");
value = value.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41;");
value = value.replaceAll("'", "& #39;");
value = value.replaceAll("eval\\((.*)\\)", "");
value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
value = value.replaceAll("script", "");
value = cleanSqlKeyWords(value);
return value;
}
private String cleanSqlKeyWords(String value) {
String paramValue = value;
for (String keyword : notAllowedKeyWords) {
if (paramValue.length() > keyword.length() + 4
&& (paramValue.contains(" "+keyword)||paramValue.contains(keyword+" ")||paramValue.contains(" "+keyword+" "))) {
paramValue = StringUtils.replace(paramValue, keyword, replacedString);
log.error(this.currentUrl + "已被过滤,因为参数中包含不允许sql的关键词(" + keyword
+ ")"+";参数:"+value+";过滤后的参数:"+paramValue);
}
}
return paramValue;
}
}
CookieUtils.java
package com.ctg.test.cros.springbootcros.util;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @Description: TODO
* @Author: qw
* @Date: 2018/11/30 11:20
*/
public class CookieUtils {
public static String getCookie(HttpServletRequest request,String cookieName){
Cookie[] cookies = request.getCookies();
if(cookies != null){
for(Cookie cookie : cookies){
if(cookie.getName().equals(cookieName)){
return cookie.getValue();
}
}
}
return null;
}
//设置cookie域
public static void writeCookie(HttpServletResponse response, String cookieName, String value){
Cookie cookie = new Cookie(cookieName,value);
cookie.setPath("/");
cookie.setMaxAge(3600);
response.addCookie(cookie);
}
}
SpringbootCrosApplication.java
package com.ctg.test.cros.springbootcros;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@SpringBootApplication
@ServletComponentScan //触发过滤器
public class SpringbootCrosApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootCrosApplication.class, args);
}
}
IndexController.java
package com.ctg.test.cros.springbootcros.controller;
import com.ctg.test.cros.springbootcros.service.UserService;
import com.ctg.test.cros.springbootcros.util.CookieUtils;
import com.ctg.test.cros.springbootcros.util.IpUtil;
import com.ctg.test.cros.springbootcros.util.ResultUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 启动2个后台进程,
* server.port=8080
* server.context-path=/webapp1
* server.port=8090
* server.context-path=/webapp2
* 访问:http://localhost:8080/webapp1
*/
@Controller
@EnableAutoConfiguration
public class IndexController {
@Autowired
private Environment env;
@Autowired
IpUtil ipUtil;
@Autowired
private UserService userService;
@RequestMapping("/")
String index(HttpServletRequest request) {
return "/index";
}
@RequestMapping("/index")
String index2(HttpServletRequest request) {
return "/index";
}
@RequestMapping("/test")
@ResponseBody
public Object test(HttpServletRequest request, HttpServletResponse response) {
Map result=new HashMap<>();
String ip="";
try {
HttpSession session = request.getSession();
String id = session.getId();
InetAddress inetAddress=ipUtil.getLocalHostLANAddress();
ip=inetAddress.getHostAddress();
} catch (Exception e) {
e.printStackTrace();
}
result.put("data","url:"+request.getRequestURL()+",ip: "+ip+",port:"+env.getProperty("server.port"));
return ResultUtil.success(result);
}
@RequestMapping(value = "/setSession", method ={RequestMethod.POST,RequestMethod.GET} )
@ResponseBody
public Object setSession(HttpSession session, HttpServletRequest request, HttpServletResponse response, @RequestParam("key") String key
, @RequestParam("value") String value) {
Map result = new HashMap<>();
request.getSession().setAttribute(key, value);
result.put("setSession-session_id", session.getId());
System.out.println("放入的sessionID"+session.getId());
List list = userService.query();
request.getSession().setAttribute("list",list);
result.put("session_key", key);
result.put("session_value", value);
CookieUtils.writeCookie(response,key,value);
return ResultUtil.success(result);
}
@RequestMapping(value = "/getSession", method = RequestMethod.GET)
@ResponseBody
public Object getSession(HttpSession session, HttpServletRequest request, HttpServletResponse response, @RequestParam("key") String key) {
Map result = new HashMap<>();
System.out.println("获取到的sessionID"+session.getId());
result.put("getSession-session_id", session.getId());
result.put("session_key", key);
result.put("cookie获取session_value", CookieUtils.getCookie(request,key));
return ResultUtil.success(result);
}
@RequestMapping(value = "/query", method = RequestMethod.POST)
@ResponseBody
public Object query(HttpSession session){
List list = (List)session.getAttribute("list");
return ResultUtil.success(list);
}
}
application.properties
#端口和上下文
server.port=8090
server.context-path=/webapp2
##html##
spring.thymeleaf.cache=false
spring.thymeleaf.check-template-location=true
spring.thymeleaf.content-type=text/html
spring.thymeleaf.enabled=true
spring.thymeleaf.mode=LEGACYHTML5
spring.mvc.static-path-pattern=/static
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://192.168.0.167:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
前端ajax xhrFields: {
withCredentials: true 这个是携带 cookie的必须携带
},
加群:687942640