commit e9c1f8cd21b62b50413e48bcb7e2c9aa6ae3fd2a Author: pioneer Date: Mon Jun 13 20:08:59 2022 +0800 open diff --git a/JSD-9009-需求确认书.docx b/JSD-9009-需求确认书.docx new file mode 100644 index 0000000..4554ae1 Binary files /dev/null and b/JSD-9009-需求确认书.docx differ diff --git a/lib/bamboocloud_Codec-0.0.1.jar b/lib/bamboocloud_Codec-0.0.1.jar new file mode 100755 index 0000000..0f2e63d Binary files /dev/null and b/lib/bamboocloud_Codec-0.0.1.jar differ diff --git a/lib/finekit-10.0.jar b/lib/finekit-10.0.jar new file mode 100755 index 0000000..611c8f5 Binary files /dev/null and b/lib/finekit-10.0.jar differ diff --git a/lib/jackson-annotations-2.11.0.jar b/lib/jackson-annotations-2.11.0.jar new file mode 100755 index 0000000..2c34567 Binary files /dev/null and b/lib/jackson-annotations-2.11.0.jar differ diff --git a/lib/jackson-core-2.11.0.jar b/lib/jackson-core-2.11.0.jar new file mode 100755 index 0000000..6ed89ba Binary files /dev/null and b/lib/jackson-core-2.11.0.jar differ diff --git a/lib/jackson-databind-2.11.0.jar b/lib/jackson-databind-2.11.0.jar new file mode 100755 index 0000000..458e1d3 Binary files /dev/null and b/lib/jackson-databind-2.11.0.jar differ diff --git a/lib/java-jwt-3.18.2.jar b/lib/java-jwt-3.18.2.jar new file mode 100755 index 0000000..d45c80f Binary files /dev/null and b/lib/java-jwt-3.18.2.jar differ diff --git a/lib/signtool.jar b/lib/signtool.jar new file mode 100755 index 0000000..9c0a107 Binary files /dev/null and b/lib/signtool.jar differ diff --git a/plugin.xml b/plugin.xml new file mode 100755 index 0000000..88e62c1 --- /dev/null +++ b/plugin.xml @@ -0,0 +1,17 @@ + + + com.fr.plugin.third.party.jsdjaaj + + yes + 0.6 + 10.0 + 2019-01-01 + fr.open + + + + + + + + \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..462e913 --- /dev/null +++ b/readme.md @@ -0,0 +1,6 @@ +# open-JSD-9009 + +JSD-9009 用户单点认证,需要FR可以跟这个应用进行单点集成,应用集成的是RDFA框架\ +免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ +仅作为开发者学习参考使用!禁止用于任何商业用途!\ +为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系【自己的英文名】处理。 \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/third/party/jsdjaaj/Utils.java b/src/main/java/com/fr/plugin/third/party/jsdjaaj/Utils.java new file mode 100755 index 0000000..f08234a --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdjaaj/Utils.java @@ -0,0 +1,156 @@ +package com.fr.plugin.third.party.jsdjaaj; + +import com.fanruan.api.log.LogKit; +import com.fanruan.api.util.StringKit; +import com.fr.general.IOUtils; +import com.fr.third.org.apache.http.HttpEntity; +import com.fr.third.org.apache.http.HttpStatus; +import com.fr.third.org.apache.http.client.config.RequestConfig; +import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; +import com.fr.third.org.apache.http.client.methods.HttpGet; +import com.fr.third.org.apache.http.client.methods.HttpPost; +import com.fr.third.org.apache.http.conn.ssl.NoopHostnameVerifier; +import com.fr.third.org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import com.fr.third.org.apache.http.entity.StringEntity; +import com.fr.third.org.apache.http.impl.client.CloseableHttpClient; +import com.fr.third.org.apache.http.impl.client.HttpClients; +import com.fr.third.org.apache.http.ssl.SSLContextBuilder; +import com.fr.third.org.apache.http.ssl.TrustStrategy; +import com.fr.third.org.apache.http.util.EntityUtils; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +public class Utils { + public static String DEFAULT_USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36"; + public static RequestConfig REQUEST_CONFIG = RequestConfig.custom() + .setConnectionRequestTimeout(30000) + .setSocketTimeout(30000) // 服务端相应超时 + .setConnectTimeout(30000) // 建立socket链接超时时间 + .build(); + + public static CloseableHttpClient createSSLClientDefault() { + try { + SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() { + + @Override + public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { + return true; + } + }).build(); + HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE; + SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, hostnameVerifier); + return HttpClients.custom().setSSLSocketFactory(sslsf).build(); + } catch (Exception e) { + LogKit.error(e.getMessage(), e); + } + return HttpClients.createDefault(); + } + + public static synchronized CloseableHttpClient createHttpClient(String url) { + CloseableHttpClient httpClient = null; + if (StringKit.isEmpty(url)) { + httpClient = HttpClients.createDefault(); + return httpClient; + } + + if (url.startsWith("https://")) { + httpClient = createSSLClientDefault(); + return httpClient; + } + httpClient = HttpClients.createDefault(); + return httpClient; + } + + public static synchronized String createHttpGetContent(CloseableHttpClient httpClient, String url) throws IOException { + if ((httpClient == null) || (StringKit.isEmpty(url))) { + return ""; + } + + HttpGet httpGet = new HttpGet(url); + httpGet.addHeader("User-Agent", Utils.DEFAULT_USER_AGENT); + httpGet.setConfig(Utils.REQUEST_CONFIG); + CloseableHttpResponse response = httpClient.execute(httpGet); + int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode != HttpStatus.SC_OK) { + response.close(); + LogKit.info("http请求出错,http status:" + statusCode); + return ""; + } + + HttpEntity httpEntity = response.getEntity(); + if (httpEntity == null) { + response.close(); + LogKit.info("http请求出错,http响应内容为空"); + return ""; + } + String responseContent = EntityUtils.toString(httpEntity, "UTF-8"); + response.close(); + if (StringKit.isEmpty(responseContent)) { + LogKit.info("http请求出错,http响应内容为空1"); + return ""; + } + return responseContent; + } + + public static synchronized String createHttpPostContent(CloseableHttpClient httpClient, String url, String bodyContent) throws IOException { + if ((httpClient == null) || (StringKit.isEmpty(url)) || (StringKit.isEmpty(bodyContent))) { + return ""; + } + + HttpPost httpPost = new HttpPost(url); + httpPost.addHeader("User-Agent", Utils.DEFAULT_USER_AGENT); + httpPost.setConfig(Utils.REQUEST_CONFIG); + StringEntity bodyEntity = new StringEntity(bodyContent, "UTF-8"); + httpPost.setEntity(bodyEntity); + CloseableHttpResponse response = httpClient.execute(httpPost); + int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode != HttpStatus.SC_OK) { + response.close(); + LogKit.info("http请求出错,http status:" + statusCode); + return ""; + } + + HttpEntity httpEntity = response.getEntity(); + if (httpEntity == null) { + response.close(); + LogKit.info("http请求出错,http响应内容为空"); + return ""; + } + String responseContent = EntityUtils.toString(httpEntity, "UTF-8"); + response.close(); + if (StringKit.isEmpty(responseContent)) { + LogKit.info("http请求出错,http响应内容为空1"); + return ""; + } + return responseContent; + } + + /** + * 获取请求主体内容 + * @param req + * @return + * @throws IOException + */ + public static String getHttpRequestBody(HttpServletRequest req) throws IOException { + if (req == null) { + return ""; + } + ServletInputStream inputStream = req.getInputStream(); + if (inputStream == null) { + return ""; + } + String content = IOUtils.inputStream2String(inputStream); + if (StringKit.isEmpty(content)) { + return ""; + } + return content; + } + + +} diff --git a/src/main/java/com/fr/plugin/third/party/jsdjaaj/config/CustomDataConfig.java b/src/main/java/com/fr/plugin/third/party/jsdjaaj/config/CustomDataConfig.java new file mode 100755 index 0000000..1321162 --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdjaaj/config/CustomDataConfig.java @@ -0,0 +1,256 @@ +package com.fr.plugin.third.party.jsdjaaj.config; + + +import com.fr.config.*; +import com.fr.config.holder.Conf; +import com.fr.config.holder.factory.Holders; + +import java.util.HashMap; +import java.util.Map; + +/** + * 配置数据保存 + */ +@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; + } + + private static volatile Map URL_MAP = new HashMap<>(); + + public synchronized static void addMapUrl(String key, String url) { + URL_MAP.put(key, url); + } + + public synchronized static String getMapUrl(String key) { + if (!URL_MAP.containsKey(key)) { + return ""; + } + String url = URL_MAP.get(key); + URL_MAP.remove(key); + return url; + } + + @Identifier(value = "searchUserUrl", name = "根据员工编号获取用户信息接口地址", description = "", status = Status.SHOW) + private Conf searchUserUrl = Holders.simple("https://xxx/search/user"); + + @Identifier(value = "appSecret", name = "接入密钥", description = "", status = Status.SHOW) + private Conf appSecret = Holders.simple("xxx"); + + @Identifier(value = "frUrl", name = "报表地址", description = "", status = Status.SHOW) + private Conf frUrl = Holders.simple("https://xxx/webroot/decision"); + + + @Identifier(value = "loginTypeNameParameter", name = "登录类型参数名称", description = "", status = Status.HIDE) + private Conf loginTypeNameParameter = Holders.simple("xxx"); + + @Identifier(value = "loginTypeValue", name = "登录类型值", description = "", status = Status.HIDE) + private Conf loginTypeValue = Holders.simple("xxx"); + + + @Identifier(value = "tokenUrl", name = "根据token单点地址", description = "", status = Status.HIDE) + private Conf tokenUrl = Holders.simple("https://xxx/userCenter/enn/uc/userInfo"); + + @Identifier(value = "esbAppKey", name = "ESB应用签名秘钥(appkey)", description = "", status = Status.HIDE) + private Conf esbAppKey = Holders.simple("xxx"); + + + @Identifier(value = "clientId", name = "应用唯一标识", description = "", status = Status.HIDE) + private Conf clientId = Holders.simple("xxx"); + + @Identifier(value = "clientSecret", name = "应用密钥", description = "", status = Status.HIDE) + private Conf clientSecret = Holders.simple("xxx"); + + @Identifier(value = "authorizeUrl", name = "请求用户授权地址", description = "", status = Status.HIDE) + private Conf authorizeUrl = Holders.simple("https://xxx/idp/oauth2/authorize"); + + @Identifier(value = "accessTokenUrl", name = "获取授权Token地址", description = "", status = Status.HIDE) + private Conf accessTokenUrl = Holders.simple("https://xxx/idp/oauth2/getToken"); + + @Identifier(value = "profileUrl", name = "获取用户信息地址", description = "", status = Status.HIDE) + private Conf profileUrl = Holders.simple("https://xxx/idp/oauth2/getUserInfo"); + + + @Identifier(value = "adminUserId", name = "管理员账号", description = "", status = Status.HIDE) + private Conf adminUserId = Holders.simple("xxx"); + + @Identifier(value = "logoutUrl", name = "单点登出地址", description = "", status = Status.HIDE) + private Conf logoutUrl = Holders.simple(""); + + @Identifier(value = "passwordKey", name = "签名加盐key", description = "", status = Status.HIDE) + private Conf passwordKey = Holders.simple(""); + + @Identifier(value = "logoutToUrl", name = "退出跳转地址", description = "", status = Status.HIDE) + private Conf logoutToUrl = Holders.simple(""); + + @Identifier(value = "userSyncKey", name = "用户同步接口信息密钥", description = "", status = Status.HIDE) + private Conf userSyncKey = Holders.simple(""); + + public String getSearchUserUrl() { + return searchUserUrl.get(); + } + + public void setSearchUserUrl(String searchUserUrl) { + this.searchUserUrl.set(searchUserUrl); + } + + public String getAppSecret() { + return appSecret.get(); + } + + public void setAppSecret(String appSecret) { + this.appSecret.set(appSecret); + } + + public String getTokenUrl() { + return tokenUrl.get(); + } + + public void setTokenUrl(String tokenUrl) { + this.tokenUrl.set(tokenUrl); + } + + public String getEsbAppKey() { + return esbAppKey.get(); + } + + public void setEsbAppKey(String esbAppKey) { + this.esbAppKey.set(esbAppKey); + } + + public String getAdminUserId() { + return adminUserId.get(); + } + + public void setAdminUserId(String adminUserId) { + this.adminUserId.set(adminUserId); + } + + + public String getUserSyncKey() { + return userSyncKey.get(); + } + + public void setUserSyncKey(String userSyncKey) { + this.userSyncKey.set(userSyncKey); + } + + public String getLogoutToUrl() { + return logoutToUrl.get(); + } + + public void setLogoutToUrl(String logoutToUrl) { + this.logoutToUrl.set(logoutToUrl); + } + + public String getClientId() { + return clientId.get(); + } + + public void setClientId(String clientId) { + this.clientId.set(clientId); + } + + public String getClientSecret() { + return clientSecret.get(); + } + + public void setClientSecret(String clientSecret) { + this.clientSecret.set(clientSecret); + } + + public String getAuthorizeUrl() { + return authorizeUrl.get(); + } + + public void setAuthorizeUrl(String authorizeUrl) { + this.authorizeUrl.set(authorizeUrl); + } + + public String getAccessTokenUrl() { + return accessTokenUrl.get(); + } + + public void setAccessTokenUrl(String accessTokenUrl) { + this.accessTokenUrl.set(accessTokenUrl); + } + + public String getProfileUrl() { + return profileUrl.get(); + } + + public void setProfileUrl(String profileUrl) { + this.profileUrl.set(profileUrl); + } + + public String getLogoutUrl() { + return logoutUrl.get(); + } + + public void setLogoutUrl(String logoutUrl) { + this.logoutUrl.set(logoutUrl); + } + + public String getFrUrl() { + return frUrl.get(); + } + + public void setFrUrl(String frUrl) { + this.frUrl.set(frUrl); + } + + public String getPasswordKey() { + return passwordKey.get(); + } + + public void setPasswordKey(String passwordKey) { + this.passwordKey.set(passwordKey); + } + + public String getLoginTypeNameParameter() { + return loginTypeNameParameter.get(); + } + + public void setLoginTypeNameParameter(String loginTypeNameParameter) { + this.loginTypeNameParameter.set(loginTypeNameParameter); + } + + public String getLoginTypeValue() { + return loginTypeValue.get(); + } + + public void setLoginTypeValue(String loginTypeValue) { + this.loginTypeValue.set(loginTypeValue); + } + + @Override + public Object clone() throws CloneNotSupportedException { + CustomDataConfig cloned = (CustomDataConfig) super.clone(); + cloned.searchUserUrl = (Conf) searchUserUrl.clone(); + cloned.appSecret = (Conf) appSecret.clone(); + cloned.tokenUrl = (Conf) tokenUrl.clone(); + cloned.esbAppKey = (Conf) esbAppKey.clone(); + cloned.adminUserId = (Conf) adminUserId.clone(); + cloned.frUrl = (Conf) frUrl.clone(); + cloned.passwordKey = (Conf) passwordKey.clone(); + cloned.clientId = (Conf) clientId.clone(); + cloned.clientSecret = (Conf) clientSecret.clone(); + cloned.authorizeUrl = (Conf) authorizeUrl.clone(); + cloned.accessTokenUrl = (Conf) accessTokenUrl.clone(); + cloned.profileUrl = (Conf) profileUrl.clone(); + cloned.logoutUrl = (Conf) logoutUrl.clone(); + cloned.loginTypeNameParameter = (Conf) loginTypeNameParameter.clone(); + cloned.loginTypeValue = (Conf) loginTypeValue.clone(); + return cloned; + } +} diff --git a/src/main/java/com/fr/plugin/third/party/jsdjaaj/config/DataConfigInitializeMonitor.java b/src/main/java/com/fr/plugin/third/party/jsdjaaj/config/DataConfigInitializeMonitor.java new file mode 100755 index 0000000..6123c0d --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdjaaj/config/DataConfigInitializeMonitor.java @@ -0,0 +1,24 @@ +package com.fr.plugin.third.party.jsdjaaj.config; + +import com.fr.intelli.record.Focus; +import com.fr.intelli.record.Original; +import com.fr.plugin.context.PluginContext; +import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor; +import com.fr.record.analyzer.EnableMetrics; + +/** + * 配置信息初始化 + */ +@EnableMetrics +public class DataConfigInitializeMonitor extends AbstractPluginLifecycleMonitor { + @Override + @Focus(id = "com.fr.plugin.third.party.jsdjaaj", text = "plugin-jsdjaaj", source = Original.PLUGIN) + 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/jsdjaaj/http/SessionGlobalRequestFilterProvider.java b/src/main/java/com/fr/plugin/third/party/jsdjaaj/http/SessionGlobalRequestFilterProvider.java new file mode 100755 index 0000000..f6ea5c8 --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdjaaj/http/SessionGlobalRequestFilterProvider.java @@ -0,0 +1,384 @@ +package com.fr.plugin.third.party.jsdjaaj.http; + +import com.auth0.jwt.JWT; +import com.auth0.jwt.interfaces.Claim; +import com.auth0.jwt.interfaces.DecodedJWT; +import com.fanruan.api.log.LogKit; +import com.fanruan.api.util.StringKit; +import com.fr.decision.authority.AuthorityContext; +import com.fr.decision.authority.data.User; +import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider; +import com.fr.decision.webservice.v10.login.LoginService; +import com.fr.decision.webservice.v10.user.UserService; +import com.fr.general.ComparatorUtils; +import com.fr.json.JSONArray; +import com.fr.json.JSONObject; +import com.fr.plugin.third.party.jsdjaaj.Utils; +import com.fr.plugin.third.party.jsdjaaj.config.CustomDataConfig; +import com.fr.stable.StringUtils; +import com.fr.stable.query.QueryFactory; +import com.fr.third.org.apache.commons.codec.digest.DigestUtils; +import com.fr.third.org.apache.http.HttpEntity; +import com.fr.third.org.apache.http.HttpStatus; +import com.fr.third.org.apache.http.NameValuePair; +import com.fr.third.org.apache.http.client.config.RequestConfig; +import com.fr.third.org.apache.http.client.entity.UrlEncodedFormEntity; +import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; +import com.fr.third.org.apache.http.client.methods.HttpGet; +import com.fr.third.org.apache.http.client.methods.HttpPost; +import com.fr.third.org.apache.http.impl.client.CloseableHttpClient; +import com.fr.third.org.apache.http.message.BasicNameValuePair; +import com.fr.third.org.apache.http.util.EntityUtils; +import com.fr.web.utils.WebUtils; + +import javax.servlet.FilterChain; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.*; + + +public class SessionGlobalRequestFilterProvider extends AbstractGlobalRequestFilterProvider { + private static String DEFAULT_USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36"; + private static RequestConfig requestConfig = RequestConfig.custom() + .setConnectionRequestTimeout(10000) + .setSocketTimeout(10000) // 服务端相应超时 + .setConnectTimeout(10000) // 建立socket链接超时时间 + .build(); + @Override + public String filterName() { + return "com.fr.plugin.third.party.jsdjaaj"; + } + + @Override + public String[] urlPatterns() { + return new String[]{"/decision", "/decision/*"}; + } + + @Override + public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) { + try { + String fullUrl = req.getRequestURL().toString(); + String queryUrl = req.getQueryString(); + if ((queryUrl == null) || "null".equalsIgnoreCase(queryUrl)) { + queryUrl = ""; + } else { + queryUrl = "?" + queryUrl; + } + + String fullUrl1 = fullUrl + queryUrl; + String method = req.getMethod(); + LogKit.info("登录集成,记录访问地址:" + method + " " + fullUrl1); + if (!"GET".equalsIgnoreCase(method)) { + filterChain.doFilter(req, res); + return; + } + + if (fullUrl.indexOf("/remote/") >= 0) { + filterChain.doFilter(req, res); + return; + } + + if (fullUrl.indexOf("terminal=H5") >= 0) { + filterChain.doFilter(req, res); + return; + } + + if (fullUrl.indexOf("__device__=") >= 0) { + filterChain.doFilter(req, res); + return; + } + + if (fullUrl.indexOf("/weixin/") >= 0) { + filterChain.doFilter(req, res); + return; + } + + + if (fullUrl.indexOf("/dingtalk/") >= 0) { + filterChain.doFilter(req, res); + return; + } + + // boolean option = isLogged(req); + //if (option) { + // filterChain.doFilter(req, res); + // return; + //} + String token = WebUtils.getHTTPRequestParameter(req, "token"); + if (StringKit.isEmpty(token)) { + filterChain.doFilter(req, res); + return; + } + LogKit.info("登录集成,token:" + token); + + String currentFrUrl = StringKit.trim(WebUtils.getHTTPRequestParameter(req, "frUrl")); + if (StringKit.isEmpty(currentFrUrl)) { + currentFrUrl = CustomDataConfig.getInstance().getFrUrl(); + } + + String loginUsername = getUserNameByJwt(token); + if (StringKit.isEmpty(loginUsername)) { + filterChain.doFilter(req, res); + return; + } + LogKit.info("登录集成,用户名:" + loginUsername); + + User user = UserService.getInstance().getUserByUserName(loginUsername); + boolean tipsOption = false; + String tipsContent = ""; + if (user == null) { + tipsOption = true; + LogKit.info("登录集成,用户名:" + loginUsername + "在报表平台不存在"); + tipsContent = "在报表服务器上不存在"; + } else if (!user.isEnable()) { + tipsOption = true; + LogKit.info("登录集成,用户名:" + loginUsername + "在报表平台上被禁用"); + tipsContent = "在报表平台上被禁用"; + } + + if (tipsOption) { + String jumpContent = "\n" + + "\n" + + " \n" + + " 提示\n" + + "\t\n" + + "\t\n" + + "\n" + + "\n" + + "
\n" + + " \n" + + "
\n" + + "\n" + + ""; + res.setContentType("text/html;charset=UTF-8"); + WebUtils.printAsString(res, jumpContent); + res.setStatus(200); + return; + } + + loginUsername = user.getUserName(); + LogKit.info("登录集成,报表平台用户名:" + loginUsername); + + //添加认证 + /*if (!PluginContexts.currentContext().isAvailable()) { + LogKit.error("登录集成插件试用过期, 请购买许可证"); + filterChain.doFilter(req, res); + return; + }*/ + + String loginToken = LoginService.getInstance().login(req, res, loginUsername); + req.setAttribute("fine_auth_token", loginToken); + + String reqUrl = getRealUrl(getRequestUrl(req),currentFrUrl); + if (StringKit.isNotEmpty(reqUrl)) { + LogKit.info("登录集成,跳转正式地址:" + reqUrl); + sendRedirect(res, reqUrl); + return; + } + + filterChain.doFilter(req, res); + } catch (Exception e) { + LogKit.error("登录集成出错," + e.getMessage(), e); + } + } + + + private String getRealUrl(String url,String frUrl) { + if (StringKit.isEmpty(url)) { + return url; + } + int index = url.indexOf("/decision"); + if (index < 0) { + return url; + } + String tempUrl = frUrl + url.substring(index + "/decision".length()); + return tempUrl; + } + + + + /** + * 解析jwt获取用户名,挂载在好气网 + * + * @param token + * @return + */ + private String getUserNameByJwt(String token) { + if (StringKit.isEmpty(token)) { + return ""; + } + String empNo = ""; + try { + DecodedJWT decodedJWT = JWT.decode(token); + Claim claim = decodedJWT.getClaim("username"); + String username = claim.asString(); + if (StringKit.isEmpty(username)) { + LogKit.info("登录集成,JWT解析未获取到username"); + return ""; + } + + String searchUserUrl = CustomDataConfig.getInstance().getSearchUserUrl(); + if (!searchUserUrl.endsWith("/")) { + searchUserUrl = searchUserUrl + "/"; + } + String userUrl = searchUserUrl + username; + LogKit.info("登录集成,获取用户信息请求地址:" + userUrl); + HttpGet httpGet = new HttpGet(userUrl); + httpGet.setConfig(requestConfig); + httpGet.addHeader("appSecret", CustomDataConfig.getInstance().getAppSecret()); + CloseableHttpClient httpClient = Utils.createHttpClient(userUrl); + CloseableHttpResponse response = httpClient.execute(httpGet); + int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode != HttpStatus.SC_OK) { + response.close(); + httpClient.close(); + LogKit.info("登录集成,获取用户信息请求出错,http status:" + statusCode); + return ""; + } + + HttpEntity httpEntity = response.getEntity(); + if (httpEntity == null) { + response.close(); + httpClient.close(); + LogKit.info("登录集成,获取用户信息请求出错,http响应内容为空"); + return ""; + } + String responseContent = EntityUtils.toString(httpEntity, "UTF-8"); + response.close(); + httpClient.close(); + if (StringKit.isEmpty(responseContent)) { + LogKit.info("登录集成,获取用户信息请求出错,http响应内容为空1"); + return ""; + } + + LogKit.info("登录集成,获取用户信息请求,http响应内容\n" + responseContent); + empNo = getEmpNo(responseContent); + } catch (Exception e) { + return ""; + } + + return empNo; + } + + private String getEmpNo(String content) { + if (StringKit.isEmpty(content)) { + return ""; + } + JSONObject contentJson = new JSONObject(content); + int code = contentJson.getInt("code"); + if (code != 200) { + return ""; + } + if (!contentJson.has("data")) { + return ""; + } + + JSONObject dataJson = contentJson.getJSONObject("data"); + if (!dataJson.has("empNo")) { + return ""; + } + String empNo = dataJson.getString("empNo"); + if (StringKit.isEmpty(empNo)) { + return ""; + } + return empNo; + } + + + private String getUserId(String content) { + if (StringKit.isEmpty(content)) { + return ""; + } + + /* + { + "grantCode": "", + "loginCode": "", + "userId": "" +} + * */ + + String loginName; + JSONObject contentJson = new JSONObject(content); + if (!contentJson.containsKey("userId")) { + return ""; + } + loginName = contentJson.getString("userId"); + return loginName; + } + + + private void sendRedirect(HttpServletResponse res, String url) { + res.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); + res.setHeader("Location", url); + } + + private String getRequestUrl(HttpServletRequest req) { + String fullUrl = req.getRequestURL().toString(); + Map paraMap = req.getParameterMap(); + String paraName; + String[] paraValues; + String loginTypeParaName = CustomDataConfig.getInstance().getLoginTypeNameParameter(); + String queryStr = ""; + for (Map.Entry entry : paraMap.entrySet()) { + paraName = entry.getKey(); + if (ComparatorUtils.equals(paraName, loginTypeParaName)) { + continue; + } + if (ComparatorUtils.equals(paraName, "token")) { + 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 boolean isAllowLoginWithParameter(HttpServletRequest req) { + if (req == null) { + return false; + } + String loginTypeNameParameter = CustomDataConfig.getInstance().getLoginTypeNameParameter(); + String loginTypeConfigValue = CustomDataConfig.getInstance().getLoginTypeValue(); + if (StringKit.isEmpty(loginTypeNameParameter) || StringKit.isEmpty(loginTypeConfigValue)) { + return false; + } + String loginTypeValue = WebUtils.getHTTPRequestParameter(req, loginTypeNameParameter); + return ComparatorUtils.equalsIgnoreCase(loginTypeConfigValue, loginTypeValue); + } + + +} diff --git a/src/main/java/com/fr/plugin/third/party/jsdjaaj/http/UrlResponseWrapper.java b/src/main/java/com/fr/plugin/third/party/jsdjaaj/http/UrlResponseWrapper.java new file mode 100755 index 0000000..16bb58a --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdjaaj/http/UrlResponseWrapper.java @@ -0,0 +1,91 @@ +package com.fr.plugin.third.party.jsdjaaj.http; + +import javax.servlet.ServletOutputStream; +import javax.servlet.WriteListener; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpServletResponseWrapper; +import java.io.*; + +public class UrlResponseWrapper extends HttpServletResponseWrapper { + private ByteArrayOutputStream buffer = null; + private ServletOutputStream out = null; + private PrintWriter writer = null; + + public UrlResponseWrapper(HttpServletResponse resp) throws IOException { + super(resp); + buffer = new ByteArrayOutputStream();// 真正存储数据的流 + out = new WapperedOutputStream(buffer); + writer = new PrintWriter(new OutputStreamWriter(buffer)); + } + + @Override + public ServletOutputStream getOutputStream() throws IOException { + return out; + } + + @Override + public PrintWriter getWriter() throws UnsupportedEncodingException { + return writer; + } + + @Override + public void flushBuffer() throws IOException { + if (out != null) { + out.flush(); + } + if (writer != null) { + writer.flush(); + } + } + + @Override + public void reset() { + buffer.reset(); + } + + public byte[] getResponseData() throws IOException { + flushBuffer(); + return buffer.toByteArray(); + } + + public String getContent() throws IOException{ + flushBuffer(); + return buffer.toString(); + } + + private class WapperedOutputStream extends ServletOutputStream { + private ByteArrayOutputStream bos = null; + + public WapperedOutputStream(ByteArrayOutputStream stream) throws IOException { + bos = stream; + } + + @Override + public void write(int b) throws IOException { + bos.write(b); + } + + @Override + public void write(byte[] b) throws IOException { + bos.write(b, 0, b.length); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + bos.write(b, off, len); + } + + + @Override + public boolean isReady() { + return false; + } + + @Override + public void setWriteListener(WriteListener writeListener) { + + } + + + } +} diff --git a/src/main/java/com/fr/plugin/third/party/jsdjaaj/http/UserUtils.java b/src/main/java/com/fr/plugin/third/party/jsdjaaj/http/UserUtils.java new file mode 100755 index 0000000..2ed6ccd --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdjaaj/http/UserUtils.java @@ -0,0 +1,341 @@ +package com.fr.plugin.third.party.jsdjaaj.http; + +import com.banboocloud.Codec.AESCipher; +import com.fanruan.api.log.LogKit; +import com.fanruan.api.util.StringKit; +import com.fr.decision.authority.AuthorityContext; +import com.fr.decision.authority.base.constant.type.operation.OperationType; +import com.fr.decision.authority.data.Department; +import com.fr.decision.webservice.bean.user.RoleBean; +import com.fr.decision.webservice.bean.user.UserAdditionBean; +import com.fr.decision.webservice.bean.user.UserAvailableFilter; +import com.fr.decision.webservice.v10.user.CustomRoleService; +import com.fr.decision.webservice.v10.user.UserService; +import com.fr.json.JSONArray; +import com.fr.json.JSONObject; +import com.fr.plugin.third.party.jsdjaaj.config.CustomDataConfig; +import com.fr.stable.query.QueryFactory; +import com.fr.stable.query.condition.QueryCondition; +import com.fr.stable.query.restriction.Restriction; +import com.fr.stable.query.restriction.RestrictionFactory; +import com.fr.web.utils.WebUtils; +import com.utils.SignHelper; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class UserUtils { + public static JSONObject getOrgErrorJson(String resultCode, String message) { + String content = "{\n" + + " \"result\": \"F\",\n" + + " \"Parameters\": {\n" + + " \"分发主键\": \"失败原因\",\n" + + " \"" + resultCode + "\": \"" + message + "\"\n" + + " }\n" + + "}"; + JSONObject jsonObject = new JSONObject(content); + return jsonObject; + } + + public static JSONObject getOrgSuccessJson() { + String content = "{\"result\":\"S\"}"; + JSONObject jsonObject = new JSONObject(content); + return jsonObject; + } + + public static JSONObject getErrorJson(String bimRequestId, String resultCode, String message) { + JSONObject errorJson = new JSONObject(); + errorJson.put("bimRequestId", bimRequestId); + errorJson.put("resultCode", resultCode); + errorJson.put("message", message); + return errorJson; + } + + public static JSONObject getSuccessJson(String bimRequestId) { + JSONObject errorJson = new JSONObject(); + errorJson.put("bimRequestId", bimRequestId); + errorJson.put("resultCode", "0"); + errorJson.put("message", "success"); + return errorJson; + } + + public static String getAdminUserId() throws Exception { + List adminUserIds = UserService.getInstance().getAdminUserIdList(); + if (adminUserIds.size() >= 1) { + return adminUserIds.get(0); + } + return ""; + } + + + /** + * 根据部门编号判断是否存在部门 + * + * @param deptId + * @return + * @throws Exception + */ + public static boolean isExistDepartmentById(String deptId) throws Exception { + if (StringKit.isEmpty(deptId)) { + return false; + } + QueryCondition queryCondition = QueryFactory.create().addRestriction(RestrictionFactory.and(new Restriction[]{RestrictionFactory.eq("id", deptId)})); + Department department = (Department) AuthorityContext.getInstance().getDepartmentController().findOne(queryCondition); + if (department != null) { + return true; + } + return false; + } + + /** + * 根据角色编号判断是否存在角色 + * + * @param roleId + * @return + * @throws Exception + */ + public static boolean isExistRoleById(String roleId) throws Exception { + if (StringKit.isEmpty(roleId)) { + return false; + } + RoleBean roleBean = CustomRoleService.getInstance().getCustomRole(roleId); + if (roleBean != null) { + return true; + } + return false; + } + + public static boolean isExistRoleByIds(String[] roleIds) throws Exception { + if ((roleIds == null) || (roleIds.length <= 0)) { + return false; + } + String tempValue; + for (int i = 0, max = roleIds.length - 1; i <= max; i++) { + tempValue = roleIds[i]; + if (!isExistRoleById(tempValue)) { + return false; + } + } + return true; + } + + + /** + * 获取用户列表 + * + * @return + * @throws Exception + */ + public static List getUserIds() throws Exception { + List userIds = new ArrayList<>(); + List adminUserIds = UserService.getInstance().getAdminUserNameList(); + if ((adminUserIds == null) || (adminUserIds.size() <= 0)) { + return userIds; + } + String adminUserId = adminUserIds.get(0); + Map userMap = UserService.getInstance().getAllUsers(adminUserId, 1, 100000, "", "userAlias", true, "", UserAvailableFilter.parse(-1), new OperationType[0]); + List userBeans = (List) userMap.get("items"); + if ((userBeans == null) || (userBeans.size() <= 0)) { + return userIds; + } + + String userId = ""; + UserAdditionBean userBean; + for (int i = 0, max = userBeans.size() - 1; i <= max; i++) { + userBean = userBeans.get(i); + userId = userBean.getId(); + if (StringKit.equalsIgnoreCase(userBean.getUsername(), CustomDataConfig.getInstance().getAdminUserId())) { + continue; + } + userIds.add(userId); + } + return userIds; + } + + /** + * 获取部门列表 + * + * @return + * @throws Exception + */ + public static List getDeptIds() throws Exception { + List deptIds = new ArrayList<>(); + List adminUserIds = UserService.getInstance().getAdminUserNameList(); + if ((adminUserIds == null) || (adminUserIds.size() <= 0)) { + return deptIds; + } + String adminUserId = adminUserIds.get(0); + List departments = AuthorityContext.getInstance().getDepartmentController().find(QueryFactory.create()); + //ControllerFactory.getInstance().getDepartmentController(adminUserId).getDepartmentTree(adminUserId); + if ((departments == null) || (departments.size() <= 0)) { + return deptIds; + } + + String deptId = ""; + Department department; + for (int i = 0, max = departments.size() - 1; i <= max; i++) { + department = departments.get(i); + if (department == null) { + continue; + } + deptId = department.getId(); + deptIds.add(deptId); + } + return deptIds; + } + + + private static AESCipher aesCipher = new AESCipher(); + public static String USER_SYNC_DECRYPT_ERROR = "jsdhgie_user_sync_decrypt_error"; + + /** + * 解密内容 + * + * @param value + * @return + */ + public static String decryptContent(String value) { + if (StringKit.isEmpty(value)) { + return ""; + } + try { + String key = CustomDataConfig.getInstance().getUserSyncKey(); + String tempValue = aesCipher.decrypt(value, key); + return tempValue; + } catch (Exception e) { + LogKit.info("xxxx登录集成及用户同步,解密用户同步信息出错," + e.getMessage()); + } + return USER_SYNC_DECRYPT_ERROR; + } + + public static void printAsJSON(HttpServletResponse res, JSONObject json) throws Exception { + if (json == null) { + WebUtils.printAsString(res, ""); + return; + } + printAsString(res, json.toString()); + } + + + public static void printAsString(HttpServletResponse res, String value) throws Exception { + if (StringKit.isEmpty(value)) { + WebUtils.printAsString(res, ""); + return; + } + //String key = CustomDataConfig.getInstance().getUserSyncKey(); + //String tempValue = aesCipher.encrypt(value, key); + String tempValue = value; + WebUtils.printAsString(res, tempValue); + } + + + public static boolean isValidSign(HttpServletRequest req, String reqContent) { + if (true) { + return true; + } + try { + if (req == null) { + return false; + } + + //appid:应用标识 + //timestamp:加签验签系统时间毫秒数 + //sign:参数签名 + String appId = req.getHeader("appid"); + String timestamp = req.getHeader("timestamp"); + String sign = req.getHeader("sign"); + + LogKit.info("登录集成及用户同步,验签 appid:" + appId); + LogKit.info("登录集成及用户同步,验签 timestamp:" + timestamp); + LogKit.info("登录集成及用户同步,验签 sign:" + sign); + + if (StringKit.isEmpty(appId) || StringKit.isEmpty(sign) || StringKit.isEmpty(timestamp)) { + return false; + } + + String appKey = CustomDataConfig.getInstance().getEsbAppKey(); + + String tempSign = SignHelper.genSign(appId, appKey, reqContent, timestamp); + if (StringKit.equals(tempSign, sign)) { + return true; + } + } catch (Exception e) { + + } + return false; + } + + + public static String getOrgCode(String userId) throws Exception { + List depts = AuthorityContext.getInstance().getDepartmentController().findByUser(userId, QueryFactory.create()); + if ((depts == null) || (depts.size() <= 0)) { + return ""; + } + String value = depts.get(0).getId(); + return value; + } + + + public static JSONObject getResultJson(String message, String code, String resultCode, String bimRequestId, String key, String value, String arrayKey, List values, String jsonKey, JSONObject valueJson) { + JSONObject json = new JSONObject(); + json.put("message", message); + json.put("code", code); + + + JSONObject dataJson = new JSONObject(); + dataJson.put("bimRequestId", bimRequestId); + dataJson.put("resultCode", resultCode); + dataJson.put("message", message); + if (StringKit.isNotEmpty(key)) { + dataJson.put(key, value); + } + + if (StringKit.isNotEmpty(arrayKey) && (values != null)) { + JSONArray arrayJson = new JSONArray(); + for (int i = 0, max = values.size() - 1; i <= max; i++) { + arrayJson.add(values.get(i)); + } + dataJson.put(arrayKey, arrayJson); + } + + if (StringKit.isNotEmpty(jsonKey)) { + dataJson.put(jsonKey, valueJson); + } + + JSONArray datasJson = new JSONArray(); + datasJson.add(dataJson); + json.put("data", datasJson); + + return json; + } + + public static JSONObject getSuccessResultJsonWithJson(String bimRequestId, String key, JSONObject valueJson) { + JSONObject json = getResultJson("success", "200", "0", bimRequestId, "", "", "", null, key, valueJson); + return json; + } + + public static JSONObject getSuccessResultJsonWithArray(String bimRequestId, String key, List values) { + JSONObject json = getResultJson("success", "200", "0", bimRequestId, "", "", key, values, "", null); + return json; + } + + public static JSONObject getSuccessResultJson(String bimRequestId, String key, String value) { + JSONObject json = getResultJson("success", "200", "0", bimRequestId, key, value, "", null, "", null); + return json; + } + + public static JSONObject getSuccessResultJson(String bimRequestId) { + JSONObject json = getResultJson("success", "200", "0", bimRequestId, "", "", "", null, "", null); + return json; + } + + + public static JSONObject getErrorResultJson(String message, String code, String bimRequestId) { + JSONObject json = getResultJson(message, code, code, bimRequestId, "", "", "", null, "", null); + return json; + } + +} diff --git a/src/main/java/com/fr/plugin/third/party/jsdjaaj/readme.md b/src/main/java/com/fr/plugin/third/party/jsdjaaj/readme.md new file mode 100644 index 0000000..7a96e97 --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdjaaj/readme.md @@ -0,0 +1,6 @@ +# open-JSD-xxxx + +JSD-xxxx 一句话简介该插件的功能和场景\ +免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ +仅作为开发者学习参考使用!禁止用于任何商业用途!\ +为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系【自己的英文名】处理。 \ No newline at end of file diff --git a/src/main/resources/com/fr/plugin/third/party/jsdijfc/web/main.js b/src/main/resources/com/fr/plugin/third/party/jsdijfc/web/main.js new file mode 100755 index 0000000..da29879 --- /dev/null +++ b/src/main/resources/com/fr/plugin/third/party/jsdijfc/web/main.js @@ -0,0 +1,16 @@ +$(function () { + var url = Dec.fineServletURL + "/url/jsd7969/oauth/config"; + $.post(url, + function (data, status) { + if (status == "success") { + debugger; + var a = Dec.Logout; + var logoutUrl = data.loginUrl; + Dec.Logout = function () { + //window.location.href = logoutUrl; + $.get(logoutUrl); + a(); + } + } + }, "json"); +}); \ No newline at end of file