Commit e175a729 by 宋祥

1.统一异常处理

2.接口鉴权拦截器
3.RequestRejectedException异常拦截处理
parent 0738d0c9
package com.baosight.hpjx.core.constant;
/**
* 平台消息统一存放key
*
* @author:songx
* @date:2024/3/12,10:49
*/
public class EPCodeConstant {
// 许可证不正确
public static final String EP_0000 = "ep.0000";
// 页面不存在或禁止访问
public static final String EP_0010 = "ep.0010";
// 页面不存在或禁止访问
public static final String EP_0012 = "ep.0012";
// 您所访问的页面没有访问权限
public static final String ES001 = "ES001";
// 空白页
public static final String ES999 = "ES999";
// 500页面
public static final String ES500 = "ES500";
}
package com.baosight.hpjx.core.exception;
import com.baosight.hpjx.core.constant.EPCodeConstant;
import com.baosight.hpjx.core.tools.ServletTools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author:songx
* @date:2024/3/11,14:58
*/
@RestControllerAdvice
public class GlobalExceptionHandler {
@Autowired
private HttpServletRequest request;
@Autowired
private HttpServletResponse response;
/**
* RuntimeException
*
* @param e
* @throws IOException
* @throws ServletException
*/
@ExceptionHandler(Exception.class)
public void exceptionHandler(Exception e) throws IOException, ServletException {
// 权限异常
if (e instanceof AccessDeniedException) {
ServletTools.dispatcherError(EPCodeConstant.ES001, request.getServletPath(), request, response);
} else if (e instanceof ClassNotFoundException) {
// class不存在
ServletTools.dispatcherError(EPCodeConstant.EP_0010, request.getServletPath(), request, response);
} else {
ServletTools.dispatcherError(EPCodeConstant.ES500, "您所访问的服务出错了", request, response);
}
}
}
package com.baosight.hpjx.core.filter;
import com.baosight.hpjx.core.constant.EPCodeConstant;
import com.baosight.hpjx.core.tools.ServletTools;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpHeaders;
import org.springframework.security.web.firewall.RequestRejectedException;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import lombok.extern.slf4j.Slf4j;
/**
* 滤波器处理
*
* @author:songx
* @date:2024/3/12,10:32
*/
@Slf4j
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class MyGenericFilterFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
try {
chain.doFilter(servletRequest, servletResponse);
} catch (RequestRejectedException e) {
log.warn("request_rejected: remote={}, user_agent={}, request_url={}", request.getRemoteHost(),
request.getHeader(HttpHeaders.USER_AGENT), request.getRequestURL(), e);
ServletTools.dispatcherError(EPCodeConstant.EP_0010, request.getServletPath(), request, response);
}
}
}
package com.baosight.hpjx.core.interceptor;
import com.baosight.hpjx.core.constant.EPCodeConstant;
import com.baosight.hpjx.core.tools.ServletTools;
import com.baosight.hpjx.util.ObjectUtils;
import com.baosight.hpjx.util.StringUtils;
import com.baosight.iplat4j.core.ioc.spring.PlatApplicationContext;
import com.baosight.xservices.xs.util.LoginUserDetails;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import lombok.extern.slf4j.Slf4j;
/**
* 自定义拦截器
*
* @author:songx
* @date:2022/10/9,8:58
*/
@Slf4j
public class MyHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
try {
// 校验接口权限
boolean isInterfaceAuth = this.checkUserInterfaceAuth(request, response);
if (!isInterfaceAuth) {
return false;
}
} catch (IOException e) {
log.error("重定向失败:{}", e.getMessage(), e);
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o,
ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) {
}
/**
* 校验用户
*
* @param request
* @param response
*/
private boolean checkUserInterfaceAuth(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
String loginName = ObjectUtils.toString(session.getAttribute("loginname"));
String servletPath = request.getServletPath();
// // 从路径中截取页面号和方法名,例:/service/EDFA10/query
String[] servletPaths = servletPath.split("/");
// 异常请求不记录
if (servletPaths.length > 2 && "$src_url$".equals(servletPaths[2])) {
return true;
}
// length=3:接口
return this.checkInterfaceAuth(loginName, servletPaths, request, response);
}
/**
* 用户接口权限校验
* servletPaths.length=3:接口
*
* @param loginName
* @param servletPaths
* @param request
* @param response
*/
private boolean checkInterfaceAuth(String loginName, String[] servletPaths, HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
if (servletPaths.length != 4) {
return true;
}
// 从配置中读取需要验证的模块
String interfaceAuth = PlatApplicationContext.getProperty("iplat4j.interface.auth.module");
if (StringUtils.isBlank(interfaceAuth)) {
return true;
}
// 检查模块是否需要管理员权限
String moduleName = ServletTools.getModule(request);
if (!StringUtils.startsWithAny(moduleName, interfaceAuth.split(";"))) {
return true;
}
// 是超级管理员
if (LoginUserDetails.isUserAdmin(loginName)) {
return true;
}
ServletTools.dispatcherError(EPCodeConstant.ES001, request.getServletPath(), request, response);
return false;
}
}
package com.baosight.hpjx.core.interceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author:songx
* @date:2023/11/23,11:13
*/
@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {
/**
* 配置拦截规则与注入拦截器
*
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// addPathPattern 添加拦截规则 /** 拦截所有包括静态资源
// excludePathPattern 排除拦截规则 所以我们需要放开静态资源的拦截
registry.addInterceptor(new MyHandlerInterceptor())
.addPathPatterns("/service/**")
.addPathPatterns("/web/**")
.addPathPatterns("/**")
// .excludePathPatterns("/")
.excludePathPatterns("/login")
.excludePathPatterns("/css/**", "/fonts/**", "/images/**", "/js/**");
}
}
...@@ -7,6 +7,7 @@ import com.baosight.iplat4j.core.ei.EiInfo; ...@@ -7,6 +7,7 @@ import com.baosight.iplat4j.core.ei.EiInfo;
import com.baosight.iplat4j.core.exception.PlatException; import com.baosight.iplat4j.core.exception.PlatException;
import com.baosight.iplat4j.core.service.soa.XLocalManager; import com.baosight.iplat4j.core.service.soa.XLocalManager;
import com.baosight.iplat4j.core.web.threadlocal.UserSession; import com.baosight.iplat4j.core.web.threadlocal.UserSession;
import com.baosight.xservices.xs.util.LoginUserDetails;
import org.apache.commons.collections.MapUtils; import org.apache.commons.collections.MapUtils;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
...@@ -20,6 +21,7 @@ public class UserSessionUtils extends UserSession { ...@@ -20,6 +21,7 @@ public class UserSessionUtils extends UserSession {
private static ConcurrentMap companyMap = new ConcurrentHashMap(); private static ConcurrentMap companyMap = new ConcurrentHashMap();
private static ConcurrentMap depMap = new ConcurrentHashMap(); private static ConcurrentMap depMap = new ConcurrentHashMap();
private static ConcurrentMap userAdminMap = new ConcurrentHashMap();
/** /**
* 获取用户信息 * 获取用户信息
...@@ -86,4 +88,22 @@ public class UserSessionUtils extends UserSession { ...@@ -86,4 +88,22 @@ public class UserSessionUtils extends UserSession {
return depCode; return depCode;
} }
/**
* 获取登录用户是否超级管理员
*
* @return
*/
public static boolean isUserAdmin() {
String loginName = getLoginName();
if (loginName == null) {
return false;
}
Boolean isUserAdmin = MapUtils.getBoolean(userAdminMap, loginName);
if (isUserAdmin == null) {
isUserAdmin = LoginUserDetails.isUserAdmin(loginName);
userAdminMap.put(loginName, isUserAdmin);
}
return isUserAdmin;
}
} }
package com.baosight.hpjx.core.tools;
import com.baosight.hpjx.util.StringUtils;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author:songx
* @date:2024/3/12,10:38
*/
public class ServletTools {
/**
* 获取模块名称
*
* @return
*/
public static String getModule(HttpServletRequest request) {
String servletPath = request.getServletPath();
if (StringUtils.isBlank(servletPath)) {
return "";
}
String[] servletPaths = servletPath.split("/");
if (servletPaths == null || servletPaths.length < 3) {
return servletPath;
}
return servletPaths[2];
}
/**
* 重定向到错误信息展示页面
*
* @param msgKey
* @param message
*/
public static void dispatcherError(String msgKey, String message, HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("iplat_msgKey", msgKey);
request.setAttribute("iplat_msg", message);
request.getRequestDispatcher("/EP/EP01.jsp").forward(request, response);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment