JSD-7963 复合单点登录+登录时增量更新用户组织和权限信息
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

647 lines
29 KiB

package com.fr.plugin;
import com.fr.decision.authority.AuthorityContext;
import com.fr.decision.authority.base.constant.type.operation.ManualOperationType;
import com.fr.decision.authority.controller.CustomRoleController;
import com.fr.decision.authority.controller.DepartmentController;
import com.fr.decision.authority.controller.PostController;
import com.fr.decision.authority.controller.UserController;
import com.fr.decision.authority.data.CustomRole;
import com.fr.decision.authority.data.Department;
import com.fr.decision.authority.data.Post;
import com.fr.decision.authority.data.User;
import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
import com.fr.decision.privilege.encrpt.PasswordValidator;
import com.fr.decision.webservice.impl.user.type.UserProductType;
import com.fr.decision.webservice.utils.UserSourceFactory;
import com.fr.decision.webservice.v10.login.LoginService;
import com.fr.decision.webservice.v10.user.UserService;
import com.fr.general.ComparatorUtils;
import com.fr.general.IOUtils;
import com.fr.io.utils.ResourceIOUtils;
import com.fr.json.JSONArray;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.transform.FunctionRecorder;
import com.fr.plugin.util.LogUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.query.QueryFactory;
import com.fr.stable.query.restriction.RestrictionFactory;
import com.fr.web.utils.WebUtils;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.net.URLDecoder;
import java.util.*;
@FunctionRecorder(localeKey = "fr2")
public class LastloginFilter extends AbstractGlobalRequestFilterProvider {
@Override
public String filterName() {
return "lastLogin";
}
@Override
public String[] urlPatterns() {
return new String[]{
"/oookkkk"
};
}
@Override
public void init(FilterConfig filterConfig) {
FilterMeConfig.getInstance();
super.init(filterConfig);
}
@Override
public void doFilter(HttpServletRequest request, HttpServletResponse httpServletResponse, FilterChain filterChain) {
String uri = request.getRequestURI();
String ip = com.fr.plugin.IpUtils.getIp(request);
String header = request.getHeader("X-Context");
// try {
// FineLoggerFactory.getLogger().info("Context:{}", URLDecoder.decode(header, "utf-8"));
// } catch (UnsupportedEncodingException e) {
// e.printStackTrace();
// }
// printCookies(request);
// FineLoggerFactory.getLogger().info("请求url:{}", WebUtils.getOriginalURL(request));
if (isRemoteDesignRequest(request) || isResourceFileRequest(request)) {
try {
filterChain.doFilter(request, httpServletResponse);
} catch (IOException e) {
printException2FrLog(e);
} catch (ServletException e) {
printException2FrLog(e);
}
return;
}
if (!ipblackCheck(ip)) {
writerOurError(httpServletResponse);
return;
}
if (request.getMethod().equalsIgnoreCase("GET")) {
if (StringUtils.isNotBlank(header)) {
XContentRequestWrapper wrapper = new XContentRequestWrapper(request);
// wrapper.getParameterMap();
// String a = wrapper.getParameter("a");
// wrapper.getParameterNames();
// FineLoggerFactory.getLogger().error("获取的A :{} ", a);
if (isLogin(wrapper)) {
// String usrNm = wrapper.getParameter("usrNm");
//从2021-01-29开始的需求, SLN-6585开始修改用户名使用userNo代替
String usrNo = wrapper.getParameter("usrNo");
String instNo = wrapper.getParameter("instNo");
String realUserName = usrNo + "_" + instNo;
// FineLoggerFactory.getLogger().info("登录信息:{}", realUserName);
User logindUser = null;
try {
logindUser = UserService.getInstance().getUserByRequestCookie(request);
UserService instance = UserService.getInstance();
// FineLoggerFactory.getLogger().info("当前登录的用户名称:{}", logindUser.getUserName());
//如果登录过并且不是管理员就判断是否是同一个用户
if (!instance.isAdmin(logindUser.getId())) {
//如果登录的用户和content的中不一致则切换登录用户
if (!ComparatorUtils.equals(logindUser.getUserName(), realUserName)) {
FineLoggerFactory.getLogger().info("当前登录的用户和xcontent的不一致,切换用户为:{}", realUserName);
tokenLogin(request, httpServletResponse);
} else {
//如果一致则判断角色是否变化
try {
FineLoggerFactory.getLogger().info("当前用户已经登录,进行权限适配:{}", realUserName);
dealCustomRole(wrapper, logindUser.getId());
} catch (Exception e) {
printException2FrLog(e);
}
}
}
} catch (Exception e) {
printException2FrLog(e);
}
} else {
FineLoggerFactory.getLogger().info("xc1当前未登录开始登录");
tokenLogin(request, httpServletResponse);
}
try {
filterChain.doFilter(wrapper, httpServletResponse);
} catch (IOException e) {
printException2FrLog(e);
} catch (ServletException e) {
printException2FrLog(e);
}
return;
}
}
try {
filterChain.doFilter(request, httpServletResponse);
} catch (IOException e) {
printException2FrLog(e);
} catch (ServletException e) {
printException2FrLog(e);
}
}
// private void printCookies(HttpServletRequest request) {
// Cookie[] cookies = request.getCookies();
// if (null != cookies) {
// for (Cookie cookie : cookies) {
// FineLoggerFactory.getLogger().info("收到的cookies name {} value:{}", cookie.getName(), cookie.getValue());
// }
// }
// }
/**
* 判断是否是远程设计请求
*/
private boolean isRemoteDesignRequest(HttpServletRequest request) {
String pathInfo = request.getPathInfo();
return StringUtils.isNotEmpty(pathInfo) && pathInfo.startsWith("/remote/design");
}
private void adminLogin(HttpServletRequest request) {
}
/**
* 判断是否是资源文件请求
*/
private boolean isResourceFileRequest(HttpServletRequest request) {
String pathInfo = request.getPathInfo();
if (StringUtils.isEmpty(pathInfo)) {
return false;
}
return pathInfo.startsWith("/resources") || pathInfo.startsWith("/file");
}
public static void printException2FrLog(Throwable e) {
StringWriter writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
String s = writer.toString();
FineLoggerFactory.getLogger().error("错误:{}", s);
}
private void sendRedirect(HttpServletResponse res, String url) {
res.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
res.setHeader("Location", url);
}
private static void login(HttpServletRequest req, HttpServletResponse res, String username) {
HttpSession session = req.getSession(true);
String token = null;
try {
token = LoginService.getInstance().login(req, res, username);
req.setAttribute("fine_auth_token", token);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
FineLoggerFactory.getLogger().error("login failed");
}
FineLoggerFactory.getLogger().error("login success");
}
private boolean ipblackCheck(String ip) {
String[] blackIps = new String[]{};
try {
InputStream inputStream = ResourceIOUtils.read("/config-all/whitelist.properties");
if (inputStream != null) {
String lines = IOUtils.inputStream2String(inputStream);
blackIps = lines.split("\n");
}
} catch (IOException e) {
LogUtils.error(e.getMessage(), e);
}
if ("0:0:0:0:0:0:0:1".equals(ip)) {
// LogUtils.info("IP 地址为服务器本机 IPv6 地址: {},直接放行。", ip);
return true;
}
if ("127.0.0.1".equals(ip)) {
// LogUtils.info("IP 地址为服务器本机 IPv4 地址: {},直接放行。", ip);
return true;
}
for (String blackIp : blackIps) {
if (!blackIp.contains("-")) {
if (ip.equals(blackIp)) {
return true;
}
} else {
String trim = blackIp.trim();
String[] split = trim.split("-");
if (split.length > 1) {
if (com.fr.plugin.IpUtils.ipExistsInRange(ip, split[0], split[1])) {
return true;
}
}
}
}
return false;
}
private void writerOurError(HttpServletResponse httpServletResponse) {
try {
WebUtils.writeOutTemplate("/com/fr/plugin/error.html", httpServletResponse, new HashMap());
} catch (IOException e) {
e.printStackTrace();
}
}
private boolean isLogin(HttpServletRequest req) {
return LoginService.getInstance().isLogged(req);
}
// public void filter(HttpServletRequest request, HttpServletResponse httpServletResponse) throws IOException, ServletException {
// String uri = request.getRequestURI();
// String ip = IpUtils.getIp(request);
// if (!ipblackCheck(ip)) {
// writerOurError(httpServletResponse);
// return;
// }
// if (request.getMethod().equalsIgnoreCase("GET")) {
// String header = request.getHeader("X-Context");
// if (StringUtils.isNotBlank(header)) {
// XContentRequestWrapper wrapper = new XContentRequestWrapper(request);
//// String a = wrapper.getParameter("a");
//// FineLoggerFactory.getLogger().error("获取的A :{} ", a);
// if (isLogin(wrapper)) {
// String usrNm = wrapper.getParameter("usrNm");
// String userNameFromRequest = LoginService.getInstance().getUserNameFromRequestCookie(request);
// //如果登录的用户和content的中不一致则切换登录用户
// if (!ComparatorUtils.equals(userNameFromRequest, usrNm)) {
// tokenLogin(request, httpServletResponse);
// }
// } else {
// tokenLogin(request, httpServletResponse);
// return;
// }
//
// String loginUrl = request.getContextPath() + request.getServletPath() + "/login";
// String home = request.getContextPath() + request.getServletPath() + "?sendTwo=true";
// if (loginUrl.equals(uri)) {
// String manualOut = request.getParameter("manual");
// if (!ComparatorUtils.equals(manualOut, "true")) {
//// String header = request.getHeader("X-Context");
// if (StringUtils.isNotBlank(header) && !isLogin(request)) {
// tokenLogin(request, httpServletResponse);
// sendRedirect(httpServletResponse, home);
// }
// }
// }
// }
// }
// return;
// }
public static void tokenLogin(HttpServletRequest req, HttpServletResponse res) {
String header = req.getHeader("X-Context");
try {
header = URLDecoder.decode(header, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
FineLoggerFactory.getLogger().info("xf拦截器捕获一个请求 x-content :{}", header);
JSONObject entries = new JSONObject(header);
JSONArray rlNoList = entries.getJSONArray("rlNoList");
int size = rlNoList.size();
List<String> adminFlags = getAdminFlagsRolList();
boolean isAdmin = false;
for (int i = 0; i < size; i++) {
String adminPost = rlNoList.getString(i);
if (isAdminFlags(adminPost, adminFlags)) {
FineLoggerFactory.getLogger().info("本次使用rlNoList管理员登录 ");
isAdmin = true;
break;
}
}
List<String> adminFlagsNmList = getAdminFlagsNmList();
String usrNm = entries.getString("usrNm");
for (String adminName : adminFlagsNmList) {
if(StringUtils.equals(adminName,usrNm)){
FineLoggerFactory.getLogger().info("本次使用usrNm管理员登录 ");
isAdmin=true;
break;
}
}
if (isAdmin) {
FineLoggerFactory.getLogger().info("本次为管理员登录 ");
login(req, res, "admin");
return;
}
// String usrNm = entries.getString("usrNm");
//从 SLN-6585开始usrNm更新成userNo
//如果usrNo的用户名存在则把这个用户的userName改成realUserName
String usrNo = entries.getString("usrNo");
String instNo = entries.getString("instNo");//部门id
String realUserName = usrNo + "_" + instNo;//更改后的用户名
String fullName = entries.getString("fullName");
String alias = fullName + "(" + realUserName + ")";
try {
User user = UserService.getInstance().getUserByUserName(usrNo);
UserController userController = AuthorityContext.getInstance().getUserController();
if (user == null) {
//如果usrNo的用户不存在则检查realUserName的用户是否存在
user = UserService.getInstance().getUserByUserName(realUserName);
if (user == null) {
// FineLoggerFactory.getLogger().info("拦截器新增一个用户 用户名称 :{}", realUserName);
PasswordValidator passwordValidator = UserSourceFactory.getInstance().getUserSource(ManualOperationType.KEY).getPasswordValidator();
user = (new User()).userName(realUserName).userAlias(alias).realName(fullName).password(passwordValidator.encode(realUserName, UUID.randomUUID().toString()))
.creationType(ManualOperationType.KEY).lastOperationType(ManualOperationType.KEY).enable(true);
userController.add(user);
}
}
// FineLoggerFactory.getLogger().info(" 拦截的用户更新:{}", fullName);
user.setRealName(fullName);
user.setUserName(realUserName);
try {
userController.update(user);
} catch (Exception e) {
}
String userId = user.getId();
dealCustomRole(req, userId);
//在判断本地的角色是不是远程没有了,要移除掉
CustomRoleController customRoleController = AuthorityContext.getInstance().getCustomRoleController();
List<CustomRole> roles = customRoleController.findByUser(userId, QueryFactory.create());
List<String> designFlags = getDesignFlags();
boolean isDesignUser = false;
if (!designFlags.isEmpty()) {
for (CustomRole role : roles) {
String name = role.getName();
//如果是有
if (isAdminFlags(name, designFlags)) {
isDesignUser = true;
break;
}
}
}
try {
UserProductType userProductType = UserProductType.fromInteger(6);//数据处理用户
if (isDesignUser) {
// FineLoggerFactory.getLogger().info("查找到当前用户有对应角色的设计标志:");
userController.addUserProductType(userId, userProductType.transProductKey());
} else {
// FineLoggerFactory.getLogger().info("查找到当前用户有对应角色的设计标志:");
userController.removeUserProductType(userId, userProductType.transProductKey());
}
} catch (Exception e) {
// FineLoggerFactory.getLogger().error("数据处理配置出错:{}", e);
}
// if (isAdmin) {
// FineLoggerFactory.getLogger().info("本次为管理员登录 ");
// login(req, res, "admin");
// } else {
// FineLoggerFactory.getLogger().info("本次为普通用户登录:{}", usrNm);
// login(req, res, usrNm);
// }
// FineLoggerFactory.getLogger().info("本次为普通用户登录:{}", realUserName);
login(req, res, realUserName);
} catch (Exception e) {
e.printStackTrace();
}
}
private static void dealCustomRole(HttpServletRequest req, String userId) throws Exception {
UserController userController = AuthorityContext.getInstance().getUserController();
Boolean needflush = FilterMeConfig.getInstance().getNeedflush();
String header = req.getHeader("X-Context");
CustomRoleController customRoleController = AuthorityContext.getInstance().getCustomRoleController();
try {
header = URLDecoder.decode(header, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
FineLoggerFactory.getLogger().info("开始同步角色信息x-content :{}", header);
JSONObject entries = new JSONObject(header);
List<String> remoteRoles = new ArrayList<>();
String pstNo = entries.getString("pstNo");//角色id
String pstNm = entries.getString("pstNm");//角色名称
String realRoleName = pstNm + "(" + pstNo + ")";
remoteRoles.add(pstNo);
try {
//先判断传过来的的角色是不是本地都有,没有要加上
List<CustomRole> controllerOne = customRoleController.find(QueryFactory.create().addRestriction(RestrictionFactory.eq("id", pstNo)));
if (!controllerOne.isEmpty()) {
try {
// FineLoggerFactory.getLogger().info("传送过来的角色已存在开始更新,添加关联用户:{}", pstNo, userId);
CustomRole customRole = controllerOne.get(0);
customRole.setName(realRoleName);
customRole.setAlias(pstNo);
customRole.setEnable(true);
customRole.setDescription("通过xcontent添加");
customRoleController.update(customRole);
} catch (Exception e) {
}
} else {
// FineLoggerFactory.getLogger().info("传送过来的角色在本地不存在,添加到本地:{}", pstNo);
CustomRole addRole = new CustomRole();
addRole.setId(pstNo);
addRole.setName(realRoleName);
addRole.setAlias(pstNo);
addRole.setEnable(true);
addRole.setDescription("通过xcontent添加");
try {
customRoleController.add(addRole);
} catch (Exception e) {
}
}
//在判断本地的角色是不是远程没有了,要移除掉
if(needflush){
List<CustomRole> roles = customRoleController.findByUser(userId, QueryFactory.create());
for (CustomRole customRole : roles) {
if ("superusers".equals((customRole.getName()))) {
continue;
}
userController.removeUserFromCustomRole(userId, customRole.getId());
}
}
try {
userController.addUserToCustomRole(userId, pstNo);
// FineLoggerFactory.getLogger().info("添加{} 到新角色:{}", userId, pstNo);
} catch (Exception e) {
}
DepartmentController departmentController = AuthorityContext.getInstance().getDepartmentController();
//移除原来的部门
if(needflush){
List<Department> departmentList = departmentController.findByUser(userId, QueryFactory.create());
for (Department department : departmentList) {
userController.removeUserFromDepartment(userId, department.getId());
}
}
String instNm = entries.getString("instNm");
String instNo = entries.getString("instNo");//部门id
Department department = departmentController.findOne(QueryFactory.create().addRestriction(RestrictionFactory.eq("id", instNo)));
if (department == null) {
department = new Department();
department.setName(instNm + "(" + instNo + ")");
department.setId(instNo);
department.setEnable(true);
department.description("通过x-content创建");
departmentController.add(department);
// FineLoggerFactory.getLogger().info("新增部门,dep: {}: name {}", department.getId(), department.getName());
} else {
// department.setName(instNm + "(" + instNo + ")");
// department.setEnable(true);
// departmentController.update(department);
// FineLoggerFactory.getLogger().info("已存在部门,dep: {}: name {}", department.getId(), department.getName());
}
PostController postController = AuthorityContext.getInstance().getPostController();
List<Post> byUser = postController.findByUser(userId, QueryFactory.create());
//移除原来职位
if(needflush){
for (Post post : byUser) {
List<Department> byPost = departmentController.findByPost(post.getId(), QueryFactory.create());
for (Department department1 : byPost) {
// FineLoggerFactory.getLogger().info("---->>>>移除用户职位 职位id {} 部门id{}", post.getId(), department1.getId());
try {
userController.removeUserFromDepartmentAndPost(userId, department1.getId(), post.getId());
// FineLoggerFactory.getLogger().info("^^^^^^移除用户职位成功 职位id {} 部门id{}", post.getId(), department1.getId());
} catch (Exception e) {
// FineLoggerFactory.getLogger().info("vvvvvv移除用户职位失败 职位id {} 部门id{}", post.getId(), department1.getId());
}
}
}
}
Post post = postController.findOne(QueryFactory.create().addRestriction(RestrictionFactory.eq("id", pstNo)));
if (post == null) {
post = new Post();
post.setId(pstNo);
post.setName(pstNm + "(" + pstNo + ")");
post.setEnable(true);
postController.add(post);
// FineLoggerFactory.getLogger().info("新增职位,post: {}: name {}", post.getId(), post.getName());
} else {
// post.setName(pstNm + "(" + pstNo + ")");
// post.setEnable(true);
// postController.update(post);
// FineLoggerFactory.getLogger().info("已存在职位,post: {}: name {}", post.getId(), post.getName());
}
try {
// FineLoggerFactory.getLogger().info("添加职位到部门,post: {}: dep {}", pstNo, instNo);
postController.addPostToDepartment(pstNo, instNo);
} catch (Exception e) {
}
try {
// FineLoggerFactory.getLogger().info("添加用户到职位 到部门,post: {}: dep {},userId:{} ", pstNo, instNo, realRoleName);
userController.addUserToDepartmentAndPost(userId, instNo, pstNo);
} catch (Exception e) {
}
} catch (Exception e) {
printException2FrLog(e);
}
}
private static boolean isAdminFlags(String flag, List<String> flags) {
return flags.contains(flag);
}
private static List<String> getAdminFlagsRolList() {
String adminFlags = FilterMeConfig.getInstance().getAdminFlags();
FineLoggerFactory.getLogger().info("本地role管理员角色获取:{}", adminFlags);
if (StringUtils.isNotBlank(adminFlags)) {
String[] split = adminFlags.split(";");
return Arrays.asList(split);
}
return Collections.emptyList();
}
private static List<String> getAdminFlagsNmList() {
String adminFlags = FilterMeConfig.getInstance().getAdminFlagsNm();
FineLoggerFactory.getLogger().info("本地管理员Nm角色获取:{}", adminFlags);
if (StringUtils.isNotBlank(adminFlags)) {
String[] split = adminFlags.split(";");
return Arrays.asList(split);
}
return Collections.emptyList();
}
private static List<String> getDesignFlags() {
String adminFlags = FilterMeConfig.getInstance().getDesignFlags();
FineLoggerFactory.getLogger().info("本地设计角色获取:{}", adminFlags);
if (StringUtils.isNotBlank(adminFlags)) {
String[] split = adminFlags.split(";");
return Arrays.asList(split);
}
return Collections.emptyList();
}
private String getUrl(HttpServletRequest request) {
String url = "/";
try {
url = "http://" + request.getServerName()//服务器地址
+ ":"
+ request.getServerPort() + request.getRequestURI();
Enumeration<String> parameterNames = request.getParameterNames();
Map<String, String> reqParams = new HashMap<>();
while (parameterNames.hasMoreElements()) {
String key = parameterNames.nextElement();
reqParams.put(key, request.getParameter(key));
}
Map<String, String> parmas = header2url(request);
reqParams.putAll(parmas);
String header2url = map2String(reqParams);
// FineLoggerFactory.getLogger().info("转换之后的url参数:{}", header2url);
if (url.contains("?")) {
url += header2url;
} else {
url += "?a=1" + header2url;
}
} catch (Exception e) {
e.printStackTrace();
}
url += "&sendTwo=true";
return url;
}
private Map<String, String> header2url(HttpServletRequest request) {
Map<String, String> params = new HashMap<>();
String context = request.getHeader("X-Context");
if (StringUtils.isNotBlank(context)) {
try {
context = URLDecoder.decode(context, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
JSONObject jsonObject = new JSONObject(context);
String userNo = jsonObject.getString("usrNo");
String userNm = jsonObject.getString("usrNm");
String pstNo = jsonObject.getString("pstNo");
String instNo = jsonObject.getString("instNo");
String accInstNo = jsonObject.getString("accInstNo");
String admnInstNo = jsonObject.getString("admnInstNo");
params.put("usrNo", userNo);
params.put("usrNm", userNm);
params.put("pstNo", pstNo);
params.put("instNo", instNo);
params.put("accInstNo", accInstNo);
params.put("admnInstNo", admnInstNo);
}
params.put("sendTwo", "true");
return params;
}
private String map2String(Map<String, String> params) {
StringBuffer buffer = new StringBuffer();
Set<String> strings = params.keySet();
for (String key : strings) {
buffer.append("&").append(key).append("=").append(params.get(key));
}
return buffer.toString();
}
}