package com.whyc.filter;
|
|
import com.whyc.constant.OperationLogEnum;
|
import com.whyc.constant.YamlProperties;
|
import com.whyc.pojo.db_user.OperationLog;
|
import com.whyc.pojo.db_user.UserInf;
|
import com.whyc.service.OperationLogService;
|
import com.whyc.util.MD5Util;
|
import com.whyc.util.UserUtil;
|
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
import org.springframework.web.context.support.WebApplicationContextUtils;
|
import org.springframework.web.context.support.XmlWebApplicationContext;
|
|
import javax.servlet.*;
|
import javax.servlet.annotation.WebFilter;
|
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletResponse;
|
import java.io.IOException;
|
|
/**
|
* 防重放功能
|
* 及
|
* 用户登录验证拦截
|
*/
|
@WebFilter
|
public class AccessFilter implements Filter {
|
|
private OperationLogService logService;
|
|
@Override
|
public void init(FilterConfig filterConfig) throws ServletException {
|
ServletContext sc = filterConfig.getServletContext();
|
AnnotationConfigServletWebServerApplicationContext cxt = (AnnotationConfigServletWebServerApplicationContext)WebApplicationContextUtils.getWebApplicationContext(sc);
|
|
if(cxt != null && cxt.getBean("operationLogService") != null && logService == null) {
|
logService = (OperationLogService) cxt.getBean("operationLogService");
|
}
|
}
|
|
@Override
|
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
|
HttpServletRequest request = (HttpServletRequest) servletRequest;
|
HttpServletResponse response = (HttpServletResponse) servletResponse;
|
//加入接口防重放功能
|
String time = request.getParameter("t");
|
String sign = request.getParameter("sign");
|
String randomStr = request.getParameter("rd");
|
|
|
String requestURI = request.getRequestURI();
|
String servletPath = request.getServletPath();
|
//防重放
|
if (2 == YamlProperties.systemType) {
|
if (time != null && sign != null && randomStr != null) { //检查接口的防重放功能
|
//60秒内检查randomStr是否存在(60秒后定时清除)
|
//ServletContext context = request.getServletContext();
|
ServletContext context = request.getSession().getServletContext();
|
//如果存在就说明参数在60秒内已经使用过了
|
if (context.getAttribute(randomStr) != null) {
|
response.setStatus(403);
|
response.setContentType("text/html;charset=utf-8");
|
response.getWriter().write("非法请求,参数异常");
|
return;
|
} else { //不存在,说明第一次使用,存入内存
|
context.setAttribute(randomStr, time);
|
context.setAttribute("randomStr_" + randomStr, time);
|
}
|
|
//60秒后,检查时效性
|
if (System.currentTimeMillis() - Long.parseLong(time) >= 60 * 1000) {
|
response.setStatus(408);
|
response.setContentType("text/html;charset=utf-8");
|
response.getWriter().write("请求超时异常");
|
return;
|
}
|
boolean res = MD5Util.checkSignMD5(time, randomStr, sign);
|
if (!res) {
|
response.setStatus(403);
|
response.setContentType("text/html;charset=utf-8");
|
response.getWriter().write("非法请求,参数异常");
|
return;
|
}
|
}
|
//无需签名的接口和资源
|
else {
|
//签名所需时间戳
|
if (!(requestURI.contains("server/timestamp")
|
//↑================此处与签名和无需登录放行保持一致===============↑/
|
//静态资源
|
|| requestURI.contains(".")
|
|| servletPath.equals("/")
|
//webSocket放行
|
|| count(servletPath,'/')==1
|
)) {
|
response.setStatus(403);
|
response.setContentType("text/html;charset=utf-8");
|
response.getWriter().write("非法请求,参数异常");
|
return;
|
}
|
}
|
}
|
|
//if(YamlProperties.profileType.equals("prod")) {
|
//用户需要登录
|
UserInf user = UserUtil.getUser();
|
//无需登录可以调用接口放行
|
if (!requestURI.contains(".") && !servletPath.equals("/") &&
|
(!
|
//签名所需时间戳
|
(requestURI.contains("server/timestamp")
|
//↑================此处与签名和无需登录放行保持一致===============↑/
|
//登录页面接口
|
|| requestURI.contains("login/login")
|
//WebSocket-账号其他主机登录
|
|| requestURI.contains("loginCheck")
|
//WebSocket-签名所需时间戳
|
|| requestURI.contains("server")
|
//options请求
|
|| request.getMethod().toUpperCase().equals("OPTIONS")
|
))) {
|
if (user == null) {
|
//越权访问
|
logService.record(OperationLogEnum.TYPE_1_SYS.getType(), OperationLogEnum.TYPE_2_UNAUTHORIZED_ACCESS.getType(),"越权访问", "越权访问接口:" + requestURI);
|
response.setStatus(401);
|
response.setContentType("text/html;charset=utf-8");
|
response.getWriter().write("非法请求,身份未验证");
|
return;
|
}
|
else if(requestURI.contains("userInf/resetSnId") //重置其他用户密码,必须1000以下的管理员才能设置
|
||requestURI.contains("add")
|
||requestURI.contains("delete")
|
||requestURI.contains("update")
|
){
|
int userId = user.getUid();
|
if(userId>=1000){
|
//越权访问
|
logService.record(OperationLogEnum.TYPE_1_SYS.getType(), OperationLogEnum.TYPE_2_UNAUTHORIZED_ACCESS.getType(),"越权访问", "越权访问接口:" + requestURI);
|
response.setStatus(401);
|
response.setContentType("text/html;charset=utf-8");
|
response.getWriter().write("非法请求,身份未授权");
|
return;
|
}
|
}
|
//}
|
}
|
|
filterChain.doFilter(servletRequest, servletResponse);
|
}
|
|
private int count(String target,char charValue){
|
int count = 0;
|
for (char ch : target.toCharArray()){
|
if(charValue == ch){
|
count++;
|
}
|
}
|
return count;
|
}
|
|
|
@Override
|
public void destroy() {
|
|
}
|
}
|