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.
 
 

347 lines
14 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.UserController;
import com.fr.decision.authority.data.CustomRole;
import com.fr.decision.authority.data.User;
import com.fr.decision.fun.impl.AbstractEmbedRequestFilterProvider;
import com.fr.decision.privilege.encrpt.PasswordValidator;
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.IpUtils;
import com.fr.plugin.transform.FunctionRecorder;
import com.fr.stable.StringUtils;
import com.fr.stable.query.QueryFactory;
import com.fr.web.utils.WebUtils;
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.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.UUID;
@FunctionRecorder(localeKey = "fr2")
public class FR2loginFilter extends AbstractEmbedRequestFilterProvider {
@Override
public void init(FilterConfig filterConfig) {
super.init(filterConfig);
}
private static String[] filterUrls = new String[]{
"v5/design/report/",
"view/report",
"view/form"
};
private void sendRedirect(HttpServletResponse res, String url) {
res.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
res.setHeader("Location", url);
}
private boolean needFilter(String url) {
if (StringUtils.isNotBlank(url)) {
for (String filterUrl : filterUrls) {
if (url.contains(filterUrl)) {
return true;
}
}
}
return false;
}
private 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 (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if ("0:0:0:0:0:0:0:1".equals(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);
}
@Override
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")) {
//直接return 就开始执行原来的逻辑
if (request.getParameter("sendTwo") != null) {
return;
}
//需要特殊处理的url按照特殊处理
if (needFilter(uri)) {
sendRedirect(httpServletResponse, getUrl(request));
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;
}
private 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("拦截器捕获一个请求 x-content :{}", header);
JSONObject entries = new JSONObject(header);
String usrNm = entries.getString("usrNm");
JSONArray rlNoList = entries.getJSONArray("rlNoList");
try {
User user = UserService.getInstance().getUserByUserName(usrNm);
UserController userController = AuthorityContext.getInstance().getUserController();
CustomRoleController customRoleController = AuthorityContext.getInstance().getCustomRoleController();
if (user == null) {
FineLoggerFactory.getLogger().info("拦截器新增一个用户 :{}", usrNm);
PasswordValidator passwordValidator = UserSourceFactory.getInstance().getUserSource(ManualOperationType.KEY).getPasswordValidator();
user = (new User()).userName(usrNm).realName(usrNm).password(passwordValidator.encode(usrNm, UUID.randomUUID().toString()))
.creationType(ManualOperationType.KEY).lastOperationType(ManualOperationType.KEY).enable(true);
userController.add(user);
}
String userId = user.getId();
List<CustomRole> roles = customRoleController.findByUser(userId, QueryFactory.create());
boolean isAdminRoleFlag = false;
List<String> adminFlags = getAdminFlags();
FineLoggerFactory.getLogger().info("当前的管理员标识符 :{}", adminFlags);
List<String> remoteRoles = new ArrayList<>();
try {
int size = rlNoList.size();
for (int i = 0; i < size; i++) {
String name = rlNoList.getString(i);
remoteRoles.add(name);
FineLoggerFactory.getLogger().info("传送过来的角色:{}", name);
if (isAdminFlags(name, adminFlags)) {
isAdminRoleFlag = true;
}
}
//先判断传过来的的角色是不是本地都有,没有要加上
for (String role : remoteRoles) {
boolean find = false;
for (CustomRole customRole : roles) {
if (ComparatorUtils.equals(customRole.getName(), role)) {
find = true;
}
}
if (!find) {
// FineLoggerFactory.getLogger().info("传送过来的角色在本地不存在,添加到本地:{}", role);
// List<CustomRole> roleList = customRoleController.find(QueryFactory.create().addRestriction(RestrictionFactory.eq("name", role)));
// FineLoggerFactory.getLogger().info("通过角色名称{} 查询出来的本地角色:{}", role, roleList.size());
// for (CustomRole customRole : roleList) {
// FineLoggerFactory.getLogger().info("给用户新增角色:{}", customRole.getId());
// userController.addUserToCustomRole(userId, customRole.getId());
// }
FineLoggerFactory.getLogger().info("传送过来的角色在本地不存在,添加到本地:{}", role);
CustomRole addRole = new CustomRole();
addRole.setName(role);
addRole.setAlias(role);
addRole.setId(UUID.randomUUID().toString());
addRole.setDescription("通过xcontent添加");
customRoleController.add(addRole);
userController.addUserToCustomRole(userId, addRole.getId());
}
}
//在判断本地的角色是不是远程没有了,要移除掉
for (CustomRole customRole : roles) {
if (!remoteRoles.contains(customRole.getName())) {
FineLoggerFactory.getLogger().info("远端没有的角色本地移除:{}", customRole.getName());
userController.removeUserFromCustomRole(userId, customRole.getId());
}
}
} catch (Exception e) {
e.printStackTrace();
}
//如果是管理员标志就直接登录admin账号
if (isAdminRoleFlag) {
FineLoggerFactory.getLogger().info("本次为管理员登录");
login(req, res, "admin");
} else {
FineLoggerFactory.getLogger().info("本次为普通用户登录:{}", usrNm);
login(req, res, usrNm);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static boolean isAdminFlags(String flag, List<String> flags) {
return flags.contains(flag);
}
private List<String> getAdminFlags() {
InputStream inputStream = ResourceIOUtils.read("/config-all/adminflag.properties");
if (inputStream != null) {
Properties properties = new Properties();
try {
properties.load(inputStream);
String adminflag = properties.getProperty("adminflag");
if (StringUtils.isNotBlank(adminflag)) {
String[] split = adminflag.split(",");
return Arrays.asList(split);
}
} catch (IOException e) {
e.printStackTrace();
}
}
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();
}
}