diff --git a/README.md b/README.md index 1313839..75e76ec 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ # open-JSD-7889 -JSD-7889 开源任务材料 \ No newline at end of file +JSD-7889 开源任务材料\ +免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ +仅作为开发者学习参考使用!禁止用于任何商业用途!\ +为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系hugh处理。 \ No newline at end of file diff --git a/lib/finekit-10.0.jar b/lib/finekit-10.0.jar new file mode 100644 index 0000000..611c8f5 Binary files /dev/null and b/lib/finekit-10.0.jar differ diff --git a/plugin.xml b/plugin.xml new file mode 100644 index 0000000..e6f4f8f --- /dev/null +++ b/plugin.xml @@ -0,0 +1,17 @@ + + + com.fr.plugin.third.party.jsd7889 + + yes + 0.2 + 10.0 + 2019-01-01 + fr.open + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/third/party/jsdhiij/RSAEncrypt.java b/src/main/java/com/fr/plugin/third/party/jsdhiij/RSAEncrypt.java new file mode 100644 index 0000000..d26e444 --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdhiij/RSAEncrypt.java @@ -0,0 +1,50 @@ +package com.fr.plugin.third.party.jsdhiij; + +import java.security.KeyFactory; +import java.security.PublicKey; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; + +import javax.crypto.Cipher; + +public class RSAEncrypt { + + /**Token的Key为FRToken + * 解析后的内容为Json格式,类似{"UserNo":"W08709","ExpiredTime":"2021-05-31 13:28:19"} + * 其中UserNo为工号,ExpiredTime为有效时长,若超时,请判官为非法访问 + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + + + String cryToken="XXX"; + String pubKey="XXX"; + String decryToken=decryptByPub(cryToken,pubKey); + System.out.print(decryToken);//输出结果为{"UserNo":"W08709","ExpiredTime":"2021-05-31 13:28:19"} + } + /** + * RSA私钥解密 + * + * @param str + * 加密字符串 + * @param publicKey + * 私钥 + * @return 铭文 + * @throws Exception + * 解密过程中的异常信息 + */ + public static String decryptByPub(String str, String publicKey) throws Exception{ + //64位解码加密后的字符串 + byte[] inputByte = Base64.getDecoder().decode(str.getBytes("UTF-8")); + //base64编码的私钥 + byte[] decoded = Base64.getDecoder().decode(publicKey); + PublicKey pubKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded)); + //RSA解密 + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.DECRYPT_MODE, pubKey); + String outStr = new String(cipher.doFinal(inputByte)); + return outStr; + } + +} \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/third/party/jsdhiij/config/CustomDataConfig.java b/src/main/java/com/fr/plugin/third/party/jsdhiij/config/CustomDataConfig.java new file mode 100644 index 0000000..efeda76 --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdhiij/config/CustomDataConfig.java @@ -0,0 +1,45 @@ +package com.fr.plugin.third.party.jsdhiij.config; + + +import com.fr.config.*; +import com.fr.config.holder.Conf; +import com.fr.config.holder.factory.Holders; + +/** + * 配置数据保存 + */ +@Visualization(category = "单点登录配置") +public class CustomDataConfig extends DefaultConfiguration { + public String getNameSpace() { + return this.getClass().getName(); + } + + private static volatile CustomDataConfig config = null; + + public static CustomDataConfig getInstance() { + if (config == null) { + config = ConfigContext.getConfigInstance(CustomDataConfig.class); + } + return config; + } + + + @Identifier(value = "userKey", name = "密钥", description = "", status = Status.SHOW) + private Conf userKey = Holders.simple("XXX"); + + + public String getUserKey() { + return userKey.get(); + } + + public void setUserKey(String userKey) { + this.userKey.set(userKey); + } + + @Override + public Object clone() throws CloneNotSupportedException { + CustomDataConfig cloned = (CustomDataConfig) super.clone(); + cloned.userKey = (Conf) userKey.clone(); + return cloned; + } +} diff --git a/src/main/java/com/fr/plugin/third/party/jsdhiij/config/DataConfigInitializeMonitor.java b/src/main/java/com/fr/plugin/third/party/jsdhiij/config/DataConfigInitializeMonitor.java new file mode 100644 index 0000000..c98c914 --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdhiij/config/DataConfigInitializeMonitor.java @@ -0,0 +1,19 @@ +package com.fr.plugin.third.party.jsdhiij.config; + +import com.fr.plugin.context.PluginContext; +import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor; + +/** + * 配置信息初始化 + */ +public class DataConfigInitializeMonitor extends AbstractPluginLifecycleMonitor { + @Override + public void afterRun(PluginContext pluginContext) { + CustomDataConfig.getInstance(); + } + + @Override + public void beforeStop(PluginContext pluginContext) { + + } +} \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/third/party/jsdhiij/http/SessionGlobalRequestFilterProvider.java b/src/main/java/com/fr/plugin/third/party/jsdhiij/http/SessionGlobalRequestFilterProvider.java new file mode 100644 index 0000000..b6840ee --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdhiij/http/SessionGlobalRequestFilterProvider.java @@ -0,0 +1,186 @@ +package com.fr.plugin.third.party.jsdhiij.http; + +import com.fanruan.api.log.LogKit; +import com.fanruan.api.util.StringKit; +import com.fr.data.NetworkHelper; +import com.fr.decision.authority.data.User; +import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider; +import com.fr.decision.mobile.terminal.TerminalHandler; +import com.fr.decision.webservice.v10.login.LoginService; +import com.fr.decision.webservice.v10.login.TokenResource; +import com.fr.decision.webservice.v10.user.UserService; +import com.fr.general.ComparatorUtils; +import com.fr.intelli.record.Focus; +import com.fr.intelli.record.Original; +import com.fr.json.JSONObject; +import com.fr.log.FineLoggerFactory; +import com.fr.plugin.third.party.jsdhiij.RSAEncrypt; +import com.fr.plugin.third.party.jsdhiij.config.CustomDataConfig; +import com.fr.record.analyzer.EnableMetrics; + +import javax.servlet.FilterChain; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Map; + +@EnableMetrics +public class SessionGlobalRequestFilterProvider extends AbstractGlobalRequestFilterProvider { + @Override + public String filterName() { + return "com.fr.plugin.third.party.jsd7889"; + } + + @Override + public String[] urlPatterns() { + return new String[]{"/decision", "/decision/*"}; + } + + @Override + @Focus(id = "com.fr.plugin.third.party.jsd7889", text = "plugin-jsd-7889", source = Original.PLUGIN) + public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) { + try { + String fullUrl = getRequestFullUrl(req); + String method = req.getMethod(); + LogKit.info("单点登录,记录访问地址:" + method + " " + fullUrl); + //boolean option = isLogged(req); + //if (option) { + //filterChain.doFilter(req, res); + // return; + //} + + String loginUsername = getUsernameByCookie(req); + if (StringKit.isEmpty(loginUsername)) { + filterChain.doFilter(req, res); + return; + } + LogKit.info("单点登录集成,用户名:" + loginUsername ); + User user = UserService.getInstance().getUserByUserName(loginUsername); + boolean tipsOption = false; + if (user == null) { + tipsOption = true; + LogKit.info("单点登录集成,用户名:" + loginUsername + "在报表平台不存在"); + } else if (!user.isEnable()) { + tipsOption = true; + LogKit.info("单点登录集成,用户名:" + loginUsername + "在报表平台上被禁用"); + } + if (tipsOption) { + filterChain.doFilter(req, res); + return; + } + String loginToken = LoginService.getInstance().login(req, res, loginUsername); + req.setAttribute("fine_auth_token", loginToken); + + + filterChain.doFilter(req, res); + } catch (Exception e) { + FineLoggerFactory.getLogger().error("单点登录出错," + e.getMessage(), e); + } + } + + private synchronized String getUsernameByCookie(HttpServletRequest req) { + String userId = ""; + try { + String frToken = getCookieValue(req, "FRToken"); + if (StringKit.isEmpty(frToken)) { + return ""; + } + String decryToken = RSAEncrypt.decryptByPub(frToken, CustomDataConfig.getInstance().getUserKey()); + JSONObject jsonObject = new JSONObject(decryToken); + userId = jsonObject.getString("UserNo"); + } catch (Exception e) { + LogKit.error("单点登录:" + e.getMessage(), e); + userId = ""; + } + return userId; + } + + private String getCookieValue(HttpServletRequest req, String key) { + Cookie[] cookies = req.getCookies(); + if ((cookies == null) || (cookies.length <= 0)) { + return ""; + } + + Cookie cookie; + for (int i = 0, max = cookies.length - 1; i <= max; i++) { + cookie = cookies[i]; + if (StringKit.equals(key, cookie.getName())) { + return cookie.getValue(); + } + } + return ""; + } + + + private String getRequestUrl(HttpServletRequest req) { + String fullUrl = req.getRequestURL().toString(); + Map paraMap = req.getParameterMap(); + String paraName; + String[] paraValues; + String loginTypeParaName = "token"; + String queryStr = ""; + for (Map.Entry entry : paraMap.entrySet()) { + paraName = entry.getKey(); + if (ComparatorUtils.equals(paraName, loginTypeParaName)) { + continue; + } + paraValues = entry.getValue(); + queryStr = addParaToQuery(queryStr, paraName, paraValues); + } + if (StringKit.isEmpty(queryStr)) { + return fullUrl; + } + fullUrl = fullUrl + "?" + queryStr; + return fullUrl; + } + + private String addParaToQuery(String query, String paraName, String[] paraValues) { + if (StringKit.isEmpty(paraName)) { + return query; + } + String fullQuery = query; + if ((paraValues == null) || (paraValues.length <= 0)) { + if (StringKit.isNotEmpty(fullQuery)) { + fullQuery = fullQuery + "&"; + } + fullQuery = paraName + "="; + return fullQuery; + } + for (int i = 0, max = paraValues.length - 1; i <= max; i++) { + if (StringKit.isNotEmpty(fullQuery)) { + fullQuery = fullQuery + "&"; + } + fullQuery = fullQuery + paraName + "=" + paraValues[i]; + } + return fullQuery; + } + + + private String getRequestFullUrl(HttpServletRequest req) { + if (req == null) { + return ""; + } + String query = req.getQueryString(); + if ("null".equalsIgnoreCase(query) || StringKit.isEmpty(query)) { + query = ""; + } else { + query = "?" + query; + } + String url = req.getRequestURL().toString() + query; + return url; + } + + public boolean isLogged(HttpServletRequest req) { + boolean logged = true; + + try { + String token = TokenResource.COOKIE.getToken(req); + LoginService.getInstance().loginStatusValid(token, TerminalHandler.getTerminal(req, NetworkHelper.getDevice(req))); + } catch (Exception var4) { + logged = false; + } + + return logged; + } + +}