package com.moon.server.interceptor; import com.alibaba.fastjson.JSON; import com.moon.server.entity.all.HttpStatus; import com.moon.server.entity.all.ResponseMsg; import com.moon.server.entity.all.StaticData; import com.moon.server.entity.sys.ResEntity; import com.moon.server.entity.sys.ResLogEntity; import com.moon.server.entity.sys.TokenEntity; import com.moon.server.entity.sys.UserEntity; import com.moon.server.helper.AsyncHelper; import com.moon.server.helper.HttpHelper; import com.moon.server.helper.StringHelper; import com.moon.server.helper.WebHelper; import com.moon.server.service.all.PermsService; import com.moon.server.service.all.SysService; import com.moon.server.service.sys.ResLogService; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import javax.annotation.Resource; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.List; import java.util.TimerTask; /** * 代理过滤器 * @author WWW * @date 2023-07-04 */ @WebFilter(urlPatterns = {"/proxy/*"}) public class ProxyFilter implements Filter { @Resource private SysService sysService; @Resource private PermsService permsService; @Resource private ResLogService resLogService; private final static int LEN = "/proxy/".length(); private static final Log log = LogFactory.getLog(ProxyFilter.class); public static final String ILLEGAL_RESOURCE = JSON.toJSONString(new ResponseMsg(HttpStatus.UNAUTHORIZED, "没有资源访问权限")); @Override public void init(FilterConfig filterConfig) { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { try { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; // 2.获取令牌 String token = getToken(req); // 3.获取用户 UserEntity ue = getUser(res, token); if (null == ue) { return; } int resId = getResId(req.getRequestURI(), LEN + token.length() + 1); if (!check(req, res, ue, token)) { return; } // 9.获取资源实体 ResEntity entity = getResEntity(ue, resId); if (null == entity) { WebHelper.writeStr2Page(res, ILLEGAL_RESOURCE); return; } insertLog(req, ue, resId); String url = getSourceUrl(req, entity); proxy(req, res, url); } catch (Exception ex) { log.error(ex.getMessage(), ex); } } @Override public void destroy() { } /** * 获取令牌 */ private String getToken(HttpServletRequest req) { return req.getRequestURI().substring(LEN, req.getRequestURI().indexOf("/", LEN)); } /** * 获取用户 */ private UserEntity getUser(HttpServletResponse res, String token) { UserEntity ue = sysService.tokenService.getUserByToken(token); if (ue == null) { WebHelper.writeStr2Page(res, AuthInterceptor.NO_LOGIN); return null; } return ue; } /** * 获取资源ID */ private int getResId(String uri, int start) { int end = uri.indexOf("/", start); String str = -1 == end ? uri.substring(start) : uri.substring(start, end); return Integer.parseInt(str); } /** * 检查 */ private boolean check(HttpServletRequest req, HttpServletResponse res, UserEntity ue, String token) { // 4.获取IP String ip = WebHelper.getIpAddress(req); if (StringHelper.isEmpty(ip)) { return WebHelper.writeStr2Page(res, AuthInterceptor.IP_NULL); } // 5.检查黑名单 if (!checkBlackList(ip, req)) { return WebHelper.writeStr2Page(res, AuthInterceptor.BLACK_LIST); } // 6.admin跳过权限检测 if (StaticData.ADMIN.equals(ue.getUid())) { return true; } // 7.检查白名单 if (!checkWhiteList(ip, req)) { // 检查IP一致性 if (!checkIpSource(ip, token)) { return WebHelper.writeStr2Page(res, AuthInterceptor.ILLEGAL_TOKEN); } } // 8.检查用户ID是否禁用 if (sysService.tokenService.isUidDisable(ue)) { return WebHelper.writeStr2Page(res, AuthInterceptor.USER_LOCK); } return true; } /** * 检查黑名单 */ private boolean checkBlackList(String ip, HttpServletRequest request) { List blackList = sysService.blacklistService.selectIpList(1); if (blackList == null || blackList.isEmpty()) { return true; } if (blackList.contains(ip)) { return false; } return true; } /** * 检查白名单 */ private boolean checkWhiteList(String ip, HttpServletRequest request) { List whiteList = sysService.blacklistService.selectIpList(2); if (whiteList == null || whiteList.isEmpty()) { return false; } return whiteList.contains(ip); } /** * 检查IP一致性 */ private boolean checkIpSource(String ip, String token) { TokenEntity te = sysService.tokenService.getEntityByToken(token); return te.getIp().equals(ip); } /** * 检查资源权限 */ private ResEntity getResEntity(UserEntity ue, int resId) { String uid = StaticData.ADMIN.equals(ue.getUid()) ? null : ue.getUid(); List rs = permsService.selectResList(uid); if (null == rs || rs.isEmpty()) { return null; } // List list = rs.stream().filter(resEntity -> resEntity.getId() == resId).collect(Collectors.toList()); for (ResEntity entity : rs) { if (resId == entity.getId()) { return entity; } } return null; } /** * 插入日志 */ private void insertLog(HttpServletRequest req, UserEntity ue, int resId) { AsyncHelper helper = new AsyncHelper(); helper.execute(new TimerTask() { @Override public void run() { String ip = WebHelper.getIpAddress(req); ResLogEntity entity = new ResLogEntity(); entity.setResid(resId); entity.setType(getRequestType(req.getMethod())); entity.setIp(ip); entity.setUrl(req.getRequestURL().toString()); entity.setCreateUser(ue.getId()); resLogService.insert(entity); } }); } /** * 获取请求类别 */ private int getRequestType(String method) { // 请求类:1-GET,2-POST,3-PUT,4-DELETE,5-TRACE,6-HEAD,7-OPTIONS,8-CONNECT'; switch (method) { case "GET": return 1; case "POST": return 2; case "PUT": return 3; case "DELETE": return 4; case "TRACE": return 5; case "HEAD": return 6; case "OPTIONS": return 7; case "CONNECT": return 8; default: return -1; } } /** * 获取原始Url */ private String getSourceUrl(HttpServletRequest req, ResEntity entity) { return ""; } /** * 代理服务 */ private void proxy(HttpServletRequest request, HttpServletResponse response, String url) throws Exception { HttpHelper httpHelper = new HttpHelper(); httpHelper.service(request, response, url, null); } }