package com.huawei.e.itr.aop;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.huawei.e.itr.common.config.MyConstants;
import com.huawei.e.itr.common.context.AppContext;
import com.huawei.e.itr.common.dao.Dao;
import com.huawei.e.itr.common.entity.User;
import com.huawei.e.itr.common.exception.BadRequestException;
import com.huawei.e.itr.common.service.UserService;
import com.huawei.e.itr.common.utils.CommonUtil;
import com.huawei.e.itr.common.utils.LogUtils;
import com.huawei.e.itr.common.utils.Result;
import com.huawei.it.sso.filter.util.SsoConstants;
import com.huawei.it.sso.filter.util.SsoUtil;
import com.huawei.it.support.usermanage.helper.UserInfoBean;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
@Slf4j
public class LoginFilter implements Filter {
@Autowired
Dao dao;
@Autowired
UserService userService;
@Autowired
LogUtils logUtils;
@Autowired
JedisPool jedisPool;
private int EXP_TIME = 60 * 30; // redis 缓存过期时间 30分钟
@Override
public void init(FilterConfig fConfig) throws ServletException {
}
@Override
public void destroy() {
}
public boolean isMSBrowser(HttpServletRequest request) {
String[] IEBrowserSignals = {"MSIE", "Trident", "Edge"};
String userAgent = request.getHeader("User-Agent");
for (String signal : IEBrowserSignals) {
if (userAgent.contains(signal)) {
return true;
}
}
return false;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
//判断如果是APP请求,则直接通过
String requestURI = httpServletRequest.getRequestURI();
if (requestURI.endsWith(".ttf") ||
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")
) {
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 = "asp_" + 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 isChangeAccount = false;
// 本地不存在,看看是否是更换了新账号
String oldaccount =
userService.getOldW3AccountByNewW3Account(token.getUserAgentId());
if (oldaccount != null) {
Map<String, Object> p = new HashMap<>();
p.put("USER_AGENTID", oldaccount);
Map<String, Object> oldUser =
dao.findOne2Map(MyConstants.USER, p, null);
if (oldUser != null) { // 存在旧账号的用户信息,把用新账号替换旧账号
String oldAccount = (String) oldUser.get("USER_AGENTID");
oldUser.put("USER_AGENTID", token.getUserAgentId());
dao.saveOrUpdate(MyConstants.USER, oldUser);
dao.commit();
String data = oldAccount + " 替换为 " + token.getUserAgentId();
logUtils.log("更换W3账号", data, oldAccount, (String) oldUser.get("ID"));
// 重新登录
Result loginResult = userService.login((HttpServletRequest) request,
(HttpServletResponse) response);
token = (User) loginResult.getData();
isChangeAccount = true;
}
}
if (isChangeAccount == false) { // 本地不存在,也没有更改过账号,跳转到用户信息审批页面
// Map<String, Object> p = new HashMap<>();
// p.put("USER_AGENTID", token.getUserAgentId());
// Map<String, Object> saveData =
// dao.findOne2Map(R.T_OWS_WAIT_APPROVAL, p, null);
// if (saveData == null) {
// saveData = new HashMap<>();
// saveData.put("ID", UUID.randomUUID().toString());
// saveData.put("CREATE_DATE", System.currentTimeMillis());
// saveData.put("USER_NAME", token.getUserName());
// saveData.put("USER_EMAIL", token.getUserEmail());
// saveData.put("USER_PHONE", token.getUserPhono());
// saveData.put("USER_AGENTID", token.getUserAgentId());
// dao.saveOrUpdate(R.T_OWS_WAIT_APPROVAL, saveData);
// dao.commit();
// }
// ((HttpServletResponse) response).sendRedirect(((HttpServletRequest) request).getContextPath()
// + "/page/addUser?agentId=" + token.getUserAgentId());
// return;
Map newUser = new HashMap();
newUser.put("USER_AGENTID", token.getUserAgentId());
newUser.put("ROLE_ID", "98d3a0ad63bf4a4fa0d53de884118bdf"); //默认是 申请人角色
newUser.put("RECT_ROLE_ID", "98d3a0ad63bf4a4fa0d53de884118bdf"); //默认是 申请人角色
newUser.put("CREATE_TIME", System.currentTimeMillis());
newUser.put("USER_NAME", token.getUserName());
newUser.put("USER_EMAIL", token.getUserEmail());
newUser.put("USER_PHONE", token.getUserPhono());
dao.saveOrUpdate(MyConstants.USER, newUser);
dao.commit();
logUtils.log("新账号创建", JSON.toJSONString(newUser),
(String) newUser.get("USER_AGENTID"), (String) newUser.get("ID"));
// 重新登录
Result loginResult = userService.login((HttpServletRequest) request,
(HttpServletResponse) response);
token = (User) loginResult.getData();
}
}
// 加载整改配置角色
userService.setRectRole(token);
// 加载ASP角色
userService.setAspRole(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);
}
if (!requestURI.startsWith("/e/digital/web")) {
if (!requestURI.startsWith("/e/digital/msd/todotask")) {
if (!requestURI.startsWith("/e/digital/index")) {
if (!requestURI.startsWith("/e/digital/sys/common")) {
if (StringUtils.isEmpty(token.getCurrentRole())) {
((HttpServletResponse) response).sendRedirect(((HttpServletRequest) request).getContextPath() +
"/index/index");
return;
}
}
}
}
}
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);
}
}
}
}
}
package com.huawei.e.itr.aop;
import com.huawei.e.itr.annotaion.ApiCheck;
import com.huawei.e.itr.common.context.AppContext;
import com.huawei.e.itr.common.entity.User;
import com.huawei.e.itr.common.exception.BadRequestException;
import com.huawei.e.itr.entity.RoleType;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.Configuration;
import java.lang.reflect.Method;
/**
* @author xWX620347
* @date 2020-06-17
*/
@Aspect
@Configuration
public class ApiCheckAop {
// @Autowired
// Dao dao;
@Pointcut(value = "@annotation(com.huawei.e.itr.annotaion.ApiCheck)")
public void exeController() {
}
@Around("exeController()")
public Object doControllerAround(ProceedingJoinPoint pjp) throws Throwable {
return this.doCheckRight(pjp);
// return pjp.proceed();
}
private Object doCheckRight(ProceedingJoinPoint point) throws Throwable {
Object result = null;
User user = AppContext.getCurrentUser();
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
if (method.isAnnotationPresent(ApiCheck.class)) {
// Object[] args = point.getArgs();
ApiCheck apiCheck = method.getAnnotation(ApiCheck.class);
RoleType[] values = apiCheck.value();
boolean isAuthed = false;
for (RoleType value : values) {
if (value == RoleType.FSE) {
if (user.getIsFse()) {
isAuthed = true;
break;
}
} else if (value == RoleType.FSIP) {
if (user.getIsFsip()) {
isAuthed = true;
break;
}
} else if (value == RoleType.MSD) {
if (user.getIsMsd()) {
isAuthed = true;
break;
}
}
}
if (!isAuthed) {
/**
* 不要注释此句代码,请为你的API添加正确的注解
* @see ApiCheck
*/
throw new BadRequestException("无权限访问");
}
}
// result的值就是被拦截方法的返回值
result = point.proceed();
return result;
}
}