package com.whyc.filter; import com.whyc.constant.UserOperation; import com.whyc.constant.YamlProperties; import com.whyc.pojo.DocUser; import com.whyc.util.ActionUtil; import com.whyc.util.CommonUtil; 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 { @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; 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 || 3 == 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 = ActionUtil.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("mapOutline/all") || requestURI.contains("battMapInformation/findStationState") || requestURI.contains("battMapInformation/searchUserManageStation") || requestURI.contains("battMapInformation/del") || requestURI.contains("station3D/byDeviceId") || requestURI.contains("battMapInformation/multAmout") //对外接口-外部 || requestURI.contains("interface/") // || requestURI.contains("interface/getBattAlarm") // || requestURI.contains("interface/getPowerInf") // || requestURI.contains("interface/getPowerAlarm") //↑================此处与签名和无需登录放行保持一致===============↑/ //静态资源 || 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")) { //用户需要登录 DocUser user = (DocUser) request.getSession().getAttribute("user"); //无需登录可以调用接口放行 if (!requestURI.contains(".") && !servletPath.equals("/") && (! //签名所需时间戳 (requestURI.contains("server/timestamp") //↓================此处与签名和无需登录放行保持一致===============↓/ //对外接口-大屏 || requestURI.contains("mapOutline/all") || requestURI.contains("battMapInformation/findStationState") || requestURI.contains("battMapInformation/searchUserManageStation") || requestURI.contains("battMapInformation/del") || requestURI.contains("station3D/byDeviceId") || requestURI.contains("battMapInformation/multAmout") //对外接口-外部 || requestURI.contains("interface/") // || requestURI.contains("interface/getBattInf") // || requestURI.contains("interface/getBattAlarm") // || requestURI.contains("interface/getPowerInf") // || requestURI.contains("interface/getPowerAlarm") //↑================此处与签名和无需登录放行保持一致===============↑/ //登录页面接口 || requestURI.contains("User_infAction!searchSnIdByUId") //TODO 免登陆v2待开发 || requestURI.contains("message") || requestURI.contains("login") || requestURI.contains("user/updatePassword2") || requestURI.contains("pageParam/findByCategoryId") || requestURI.contains("pageParam/allList") || requestURI.contains("license") || requestURI.contains("UKey") || requestURI.contains("closeBrowser") || requestURI.contains("user/register") || requestURI.contains("face/activeOnline") || requestURI.contains("face/faceCompare2N") //WebSocket-账号其他主机登录 || requestURI.contains("loginCheck") || requestURI.contains("interfacePowerAlarm") || requestURI.contains("interfaceDevAlarm") || requestURI.contains("interfaceBattAlarm") || requestURI.contains("interfaceRealTime") //WebSocket-签名所需时间戳 || requestURI.contains("server") || requestURI.contains("docDepart/getAllRole") //options请求 || request.getMethod().toUpperCase().equals("OPTIONS") ))) { if (user == null) { //越权访问 //CommonUtil.record(0, UserOperation.TYPE_UNAUTHORIZED_ACCESS.getType(), "越权访问", "越权访问接口:" + requestURI); CommonUtil.record2(request, 0,"", UserOperation.TYPE_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() { } }