全局权限控制
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;
}
}
以上是关于全局权限控制的主要内容,如果未能解决你的问题,请参考以下文章
C#-WebForm-★内置对象简介★Request-获取请求对象Response相应请求对象Session全局变量(私有)Cookie全局变量(私有)Application全局公共变量Vi(代码片段
Android 逆向Linux 文件权限 ( Linux 权限简介 | 系统权限 | 用户权限 | 匿名用户权限 | 读 | 写 | 执行 | 更改组 | 更改用户 | 粘滞 )(代码片段