全局权限控制
Posted IT的鱼
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了全局权限控制相关的知识,希望对你有一定的参考价值。
public class AppContext
private static ThreadLocal<User> currentUserHolder = new ThreadLocal<>();
private static void setCurrentUser(User user)
currentUserHolder.set(user);
public static User getCurrentUser()
return currentUserHolder.get();
public static void clearAll()
currentUserHolder.remove();
/**
* 注意 千万不要注释此代码,涉及安全性相关
*/
public static void checkAndminRole()
User currentUser = AppContext.getCurrentUser();
if (currentUser == null)
throw new BadRequestException("无权限访问此资源");
if (!"superadmin".equals(currentUser.getRoleId()))
throw new BadRequestException("无权限访问此资源");
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
//判断如果是APP请求,则直接通过
String requestURI = httpServletRequest.getRequestURI();
if (requestURI.startsWith("/e/welink") ||
requestURI.startsWith("/e/test/welink") ||
requestURI.startsWith("/e/approve/waitApprove") ||
requestURI.startsWith("/e/page/applicationPage") ||
requestURI.startsWith("/e/ows/user/listRole") ||
requestURI.endsWith(".ttf") ||
requestURI.endsWith(".woff") ||
requestURI.endsWith(".eot") ||
requestURI.endsWith(".woff2") ||
requestURI.endsWith(".css") ||
requestURI.endsWith(".js") ||
requestURI.endsWith(".png") ||
requestURI.endsWith(".jpg") ||
requestURI.endsWith(".wav") ||
requestURI.endsWith(".xlsx") ||
requestURI.endsWith(".svg") ||
requestURI.startsWith("/e/api/csp/") ||
requestURI.endsWith("/e/api/important_contact/all") ||
requestURI.contains("getRepOffAndIndustry") ||
requestURI.contains("getAllQcLine") ||
requestURI.contains("feginAsp") ||
requestURI.contains("/api/urgnetProblem") ||
requestURI.contains("/api/policystu") ||
requestURI.contains("/problemThroughTrain") ||
requestURI.contains("/clientIndex")
// requestURI.endsWith("/e/promotion/test")
)
chain.doFilter(request, response);
return;
if (requestURI.indexOf("/e/page") != -1)
if (isMSBrowser(httpServletRequest))
response.setCharacterEncoding("gbk");
PrintWriter out = response.getWriter();
out.println("<div>本系统不支持 IE EDGE 等浏览器,推荐使用 Google Chrome浏览器,谢谢。</div>");
return;
HttpSession session = httpServletRequest.getSession();
UserInfoBean uiBean = (UserInfoBean) session
.getAttribute(SsoConstants.SESSION_USER_INFO_KEY);
if (uiBean == null) //会话已经超时
if (CommonUtil.isAjax(httpServletRequest)) //ajax请求会话超时,filter不会进入统一异常拦截
Map<String, String> map = new HashMap<>();
map.put("code", "401");
response.setCharacterEncoding("utf-8");
response.getWriter().print(JSONObject.toJSON(map));
return;
try
// 从 sso 跳转回来 回到当前访问的 url
SsoUtil.loginAndRedirect2AppCurrentURL((HttpServletRequest) request,
(HttpServletResponse) response);
return;
catch (Exception e)
e.printStackTrace();
else
try
User token = null;
try (Jedis jedis = jedisPool.getResource())
String redisKey = "userInfo_" + uiBean.getUid();
String tokenStr = jedis.get(redisKey);
if (StringUtils.isNotBlank(tokenStr))
token = JSON.parseObject(tokenStr, User.class);
if (token == null) //|| token.getRootList().size() == 0
Result r = userService.login((HttpServletRequest) request,
(HttpServletResponse) response);
token = (User) r.getData();
if ("N".equals(token.getIsVaild()))
if (CommonUtil.isAjax(httpServletRequest)) //ajax请求会话超时,filter不会进入统一异常拦截
throw new BadRequestException("此账号已被禁用,如需开通,请联系系统管理员 王超伟 w00509928 !");
else
response.setCharacterEncoding("gbk");
response.getWriter().println("此账号已被禁用,如需开通,请联系系统管理员 王超伟 w00509928 !");
return;
// "审批"跳转流程
if (token.getIsExists())
// 用户表"存在"用户
Boolean redirect2ApplicationPage = approveLoginFilter.redirectWithUserExist(token);
if (redirect2ApplicationPage)
((HttpServletResponse) response).sendRedirect(((HttpServletRequest) request).getContextPath() + "/page/applicationPage?agentId=" + token.getUserAgentId());
return;
else
// 用户表"不存在"用户
Map<String, Object> newUserMap = approveLoginFilter.getNewUserByOldAgentId(token); // 查看是否更换账号
if (ObjectUtils.isEmpty(newUserMap))
// 没有更换账号,则表示完全为一个新的账户,按照正常的流程
approveLoginFilter.redirectWithUserNotExist(token);
((HttpServletResponse) response).sendRedirect(((HttpServletRequest) request).getContextPath() + "/page/applicationPage?agentId=" + token.getUserAgentId());
return;
else
// 更换了账号,则需要重新跳转至 用户表"存在"用户流程
User newUser = new User();
newUser.setId((String) newUserMap.get("ID"));
newUser.setUserAgentId((String) newUserMap.get("USER_AGENTID"));
newUser.setUserEmail((String) newUserMap.get("USER_EMAIL"));
newUser.setUserPhono((String) newUserMap.get("USER_PHONE"));
newUser.setCreateTime((Long) newUserMap.get("CREATE_DATE"));
newUser.setRoleId((String) newUserMap.get("ROLE_ID"));
newUser.setQc_line((String) newUserMap.get("QC_LINE"));
newUser.setRep_off((String) newUserMap.get("REP_OFF"));
Boolean redirect2ApplicationPage = approveLoginFilter.redirectWithUserExist(newUser);
if (redirect2ApplicationPage)
((HttpServletResponse) response).sendRedirect(((HttpServletRequest) request).getContextPath() + "/page/applicationPage?agentId=" + token.getUserAgentId());
return;
else
// 重新登录
Result loginResult = userService.login((HttpServletRequest) request, (HttpServletResponse) response);
token = (User) loginResult.getData();
// 加载整改配置角色
userService.setRectRole(token);
// 加载菜单、权限等
userService.loadUserResource(token);
// session.setAttribute("userInfo", token);
logUtils.log("登录", null, token.getUserAgentId(), token.getId());
dao.commit();
jedis.set(redisKey, JSON.toJSONString(token));
log.info("从数据库中加载用户信息");
// 设置过期时间 单位(秒)
jedis.expire(redisKey, EXP_TIME);
Method m = AppContext.class.getDeclaredMethod("setCurrentUser", User.class);
m.setAccessible(true);
m.invoke(null, token);
chain.doFilter(request, response);
catch (Exception ex)
log.error(ex.getMessage(), ex);
finally
AppContext.clearAll();
try
dao.close();
catch (Exception e)
e.printStackTrace();
log.error(e.getMessage(), e);
@Aspect
@Configuration
public class TransactionAop
private static TransactionAop transactionAop;
private Dao dao;
/**
* api与二级菜单对应关系
*/
private static LinkedListMultimap<String, String> URL_PID_MAPPING = LinkedListMultimap.create();
@Autowired
public void setDao(Dao dao) throws Exception
this.dao = dao;
transactionAop = this;
loadMapping();
/**
* api与二级菜单对应关系
*
* @throws Exception
*/
public static void loadMapping() throws Exception
String sql = "select t.*,t.rowid from t_ows_resource t where t.type=3 order by length(t.url) desc";
List<Map<String, Object>> list =
transactionAop.dao.queryListBySql(sql, null);
for (Map<String, Object> stringObjectMap : list)
URL_PID_MAPPING.put((String) stringObjectMap.get("URL"),
(String) stringObjectMap.get("PID"));
@Pointcut("execution(public * e.itr..*Controller.*(..))")
public void exeController()
@Pointcut("execution(public * e.itr..*Task.*(..))")
public void exeTask()
@Around("exeController()")
public Object doControllerAround1(ProceedingJoinPoint pjp) throws Throwable
return this.doTransaction(pjp);
@Around("exeTask()")
public Object doTaskAround(ProceedingJoinPoint pjp) throws Throwable
return this.doTaskTransaction(pjp);
private Object doTaskTransaction(ProceedingJoinPoint pjp) throws Throwable
Object result = null;
try
// result的值就是被拦截方法的返回值
result = pjp.proceed();
dao.commit();
catch (Exception ex)
dao.rollback();
throw ex;
finally
dao.close();
return result;
private Object doTransaction(ProceedingJoinPoint pjp) throws Throwable
Object result = null;
try
checkApiRight(pjp);
// result的值就是被拦截方法的返回值
result = pjp.proceed();
dao.commit();
catch (Exception ex)
dao.rollback();
throw ex;
finally
dao.close();
return result;
private void checkApiRight(ProceedingJoinPoint pjp) throws Exception
Class<?> classTarget = pjp.getTarget().getClass();
RequestMapping rm1 = classTarget.getAnnotation(RequestMapping.class);
if (rm1 == null || rm1.value() == null ||
rm1.value().length == 0)
return;
String url = rm1.value()[0];
// 页面不拦截
if (url.startsWith("/page") || url.contains("welink"))
return;
// 拼接完整url
String methodName = pjp.getSignature().getName();
Class<?>[] par = ((MethodSignature) pjp.getSignature()).getParameterTypes();
Method objMethod = classTarget.getMethod(methodName, par);
if (objMethod.isAnnotationPresent(PostMapping.class))
PostMapping rm2 = objMethod.getAnnotation(PostMapping.class);
url += rm2.value()[0];
else if (objMethod.isAnnotationPresent(GetMapping.class))
GetMapping rm3 = objMethod.getAnnotation(GetMapping.class);
url += rm3.value()[0];
else if (objMethod.isAnnotationPresent(DeleteMapping.class))
DeleteMapping rm4 = objMethod.getAnnotation(DeleteMapping.class);
url += rm4.value()[0];
else if (objMethod.isAnnotationPresent(PutMapping.class))
PutMapping rm5 = objMethod.getAnnotation(PutMapping.class);
url += rm5.value()[0];
else if (objMethod.isAnnotationPresent(RequestMapping.class))
RequestMapping rm6 = objMethod.getAnnotation(RequestMapping.class);
url += rm6.value()[0];
System.out.println(url);
// 不检查的url
if ("/ows/file/play/name".equals(url))
return;
if ("/ows/user/listRole".equals(url))
return;
if (url.startsWith("/approve"))
return;
if (url.startsWith("/feginAsp"))
return;
if (url.startsWith("/api/urgnetProblem"))
return;
if (url.contains("/problemThroughTrain"))
return;
if (url.contains("/clientIndex"))
return;
if (url.contains("/policystu/data"))
return;
if (AppContext.getCurrentUser() == null)
throw new BadRequestException("未登录访问[" + url + "]");
String agentId = AppContext.getCurrentUser().getUserAgentId();
//判断用户是否有相关的二级菜单
Set<String> secondMenus = AppContext.getCurrentUser().getSecondMenus();
List<String> matchPids = null;
for (String ks : URL_PID_MAPPING.keySet())
if (url.startsWith(ks))
matchPids = URL_PID_MAPPING.get(ks);
break;
// 未配置的api 忽略
if (matchPids == null || matchPids.size() == 0)
// throw new BadRequestException(agentId + " 未配置的api [" + url + "]");
return;
boolean isMatch = false;
for (String matchPid : matchPids)
if (secondMenus.contains(matchPid))
isMatch = true;
break;
if (!isMatch)
throw new BadRequestException(agentId + " 无权限访问! [" + url + "]");
public class XSSFilter implements Filter
@Override
public void init(FilterConfig filterConfig) throws ServletException
@Override
public void destroy()
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException
chain.doFilter(new XSSRequestWrapper((HttpServletRequest) request), response);
public class XSSRequestWrapper extends HttpServletRequestWrapper
public XSSRequestWrapper(HttpServletRequest servletRequest)
super(servletRequest);
@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] = stripXSS(values[i]);
return encodedValues;
@Override
public String getParameter(String parameter)
String value = super.getParameter(parameter);
return stripXSS(value);
@Override
public String getHeader(String name)
String value = super.getHeader(name);
return stripXSS(value);
// 对值进行html实体编码
private String stripXSS(String value)
if (value != null)
value = HtmlUtils.htmlEscape(value);
return value;
以上是关于全局权限控制的主要内容,如果未能解决你的问题,请参考以下文章
net core体系-web应用程序-4asp.net core2.0 项目实战-13基于OnActionExecuting全局过滤器,页面操作权限过滤控制到按钮级