diff --git a/JSD-8061需求确认书.docx b/JSD-8061需求确认书.docx new file mode 100644 index 0000000..5e94d8e Binary files /dev/null and b/JSD-8061需求确认书.docx differ diff --git a/README.md b/README.md index 95d9e67..55ebff7 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ # open-JSD-8061 -JSD-8061 OAuth2单点 \ No newline at end of file +JSD-8061 OAuth2单点\ +免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ +仅作为开发者学习参考使用!禁止用于任何商业用途!\ +为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系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..3716327 --- /dev/null +++ b/plugin.xml @@ -0,0 +1,17 @@ + + + com.fr.plugin.third.party.jsd8061 + + yes + 0.4 + 10.0 + 2019-01-01 + fr.open + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/third/party/jsdiagb/Utils.java b/src/main/java/com/fr/plugin/third/party/jsdiagb/Utils.java new file mode 100644 index 0000000..54755fb --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdiagb/Utils.java @@ -0,0 +1,134 @@ +package com.fr.plugin.third.party.jsdiagb; + +import com.fanruan.api.log.LogKit; +import com.fanruan.api.util.StringKit; +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 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; + } + + + + +} diff --git a/src/main/java/com/fr/plugin/third/party/jsdiagb/config/CustomDataConfig.java b/src/main/java/com/fr/plugin/third/party/jsdiagb/config/CustomDataConfig.java new file mode 100644 index 0000000..104ac2b --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdiagb/config/CustomDataConfig.java @@ -0,0 +1,164 @@ +package com.fr.plugin.third.party.jsdiagb.config; + + +import com.fr.config.*; +import com.fr.config.holder.Conf; +import com.fr.config.holder.factory.Holders; + +import java.util.concurrent.ConcurrentHashMap; + +/** + * 配置数据保存 + */ +@Visualization(category = "SSO登录集成配置") +public class CustomDataConfig extends DefaultConfiguration { + public String getNameSpace() { + return this.getClass().getName(); + } + + private static ConcurrentHashMap URL_MAP = new ConcurrentHashMap(); + + /** + * 添加链接 + * @param key + * @param url + */ + public static void addUrl(String key, String url) { + URL_MAP.put(key, url); + } + + /** + * 获取链接并销毁保存 + * @param key + * @return + */ + public static String getUrlAndDestroy(String key) { + String url = URL_MAP.get(key); + URL_MAP.remove(key); + return url; + } + + + private static volatile CustomDataConfig config = null; + + public static CustomDataConfig getInstance() { + if (config == null) { + config = ConfigContext.getConfigInstance(CustomDataConfig.class); + } + return config; + } + + + @Identifier(value = "idmClientId", name = "客户端id(client_id)", description = "", status = Status.SHOW) + private Conf idmClientId = Holders.simple(""); + + + @Identifier(value = "idmClientSecret", name = "客户端密钥(client_secret)", description = "", status = Status.SHOW) + private Conf idmClientSecret = Holders.simple(""); + + + @Identifier(value = "frUrl", name = "报表地址(redirect_uri)", description = "", status = Status.SHOW) + private Conf frUrl = Holders.simple(""); + + + @Identifier(value = "oAuthCodeUrl", name = "获取OAuth Code地址", description = "", status = Status.SHOW) + private Conf oAuthCodeUrl = Holders.simple(""); + + + @Identifier(value = "accessTokenUrl", name = "获取Access Token地址", description = "", status = Status.SHOW) + private Conf accessTokenUrl = Holders.simple(""); + + + @Identifier(value = "userUrl", name = "获取用户信息地址", description = "", status = Status.SHOW) + private Conf userUrl = Holders.simple(""); + + + @Identifier(value = "loginTypeNameParameter", name = "登录类型参数名称", description = "", status = Status.SHOW) + private Conf loginTypeNameParameter = Holders.simple("loginType"); + + + @Identifier(value = "loginTypeValue", name = "登录类型值", description = "", status = Status.SHOW) + private Conf loginTypeValue = Holders.simple("OAUTH"); + + + + + public String getIdmClientId() { + return idmClientId.get(); + } + + public void setIdmClientId(String idmClientId) { + this.idmClientId.set(idmClientId); + } + + public String getIdmClientSecret() { + return idmClientSecret.get(); + } + + public void setIdmClientSecret(String idmClientSecret) { + this.idmClientSecret.set(idmClientSecret); + } + + public String getFrUrl() { + return frUrl.get(); + } + + public void setFrUrl(String frUrl) { + this.frUrl.set(frUrl); + } + + public String getoAuthCodeUrl() { + return oAuthCodeUrl.get(); + } + + public void setoAuthCodeUrl(String oAuthCodeUrl) { + this.oAuthCodeUrl.set(oAuthCodeUrl); + } + + public String getAccessTokenUrl() { + return accessTokenUrl.get(); + } + + public void setAccessTokenUrl(String accessTokenUrl) { + this.accessTokenUrl.set(accessTokenUrl); + } + + public String getUserUrl() { + return userUrl.get(); + } + + public void setUserUrl(String userUrl) { + this.userUrl.set(userUrl); + } + + 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.idmClientId = (Conf) idmClientId.clone(); + cloned.idmClientSecret = (Conf) idmClientSecret.clone(); + cloned.frUrl = (Conf) frUrl.clone(); + cloned.oAuthCodeUrl = (Conf) oAuthCodeUrl.clone(); + cloned.accessTokenUrl = (Conf) accessTokenUrl.clone(); + cloned.userUrl = (Conf) userUrl.clone(); + cloned.loginTypeNameParameter = (Conf) loginTypeNameParameter.clone(); + cloned.loginTypeValue = (Conf) loginTypeValue.clone(); + return cloned; + } +} diff --git a/src/main/java/com/fr/plugin/third/party/jsdiagb/config/DataConfigInitializeMonitor.java b/src/main/java/com/fr/plugin/third/party/jsdiagb/config/DataConfigInitializeMonitor.java new file mode 100644 index 0000000..81076c7 --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdiagb/config/DataConfigInitializeMonitor.java @@ -0,0 +1,24 @@ +package com.fr.plugin.third.party.jsdiagb.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.jsd8061", text = "plugin-jsd-8061", 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/jsdiagb/http/CustomUserInfo.java b/src/main/java/com/fr/plugin/third/party/jsdiagb/http/CustomUserInfo.java new file mode 100644 index 0000000..1a299b7 --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdiagb/http/CustomUserInfo.java @@ -0,0 +1,53 @@ +package com.fr.plugin.third.party.jsdiagb.http; + +public class CustomUserInfo { + private boolean valid = false; + private String userId; + private String username; + private String email; + private String phone; + + public CustomUserInfo() { + setValid(false); + } + + public boolean isValid() { + return valid; + } + + public void setValid(boolean valid) { + this.valid = valid; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } +} diff --git a/src/main/java/com/fr/plugin/third/party/jsdiagb/http/SessionGlobalRequestFilterProvider.java b/src/main/java/com/fr/plugin/third/party/jsdiagb/http/SessionGlobalRequestFilterProvider.java new file mode 100644 index 0000000..830885f --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdiagb/http/SessionGlobalRequestFilterProvider.java @@ -0,0 +1,464 @@ +package com.fr.plugin.third.party.jsdiagb.http; + +import com.fanruan.api.log.LogKit; +import com.fanruan.api.util.StringKit; +import com.fr.data.NetworkHelper; +import com.fr.decision.authority.AuthorityContext; +import com.fr.decision.authority.base.constant.type.operation.ManualOperationType; +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.privilege.encrpt.PasswordValidator; +import com.fr.decision.webservice.utils.UserSourceFactory; +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.json.JSONObject; +import com.fr.log.FineLoggerFactory; +import com.fr.plugin.third.party.jsdiagb.Utils; +import com.fr.plugin.third.party.jsdiagb.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.HttpHeaders; +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.util.*; + + +public class SessionGlobalRequestFilterProvider extends AbstractGlobalRequestFilterProvider { + //private static CloseableHttpClient httpClient = HttpClients.createDefault(); + 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"; + + @Override + public String filterName() { + return "com.fr.plugin.third.party.jsd8061"; + } + + @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("SSO登录集成登录,记录访问地址:" + method + " " + fullUrl1); + if (fullUrl.indexOf("/remote/") >= 0) { + filterChain.doFilter(req, res); + return; + } + + if (!"GET".equalsIgnoreCase(method)) { + filterChain.doFilter(req, res); + return; + } + + // boolean option = isLogged(req); + //if (option) { + // filterChain.doFilter(req, res); + // return; + //} + + if (isAllowIdmOAuthLogin(req)) { + String state = getUuid(); + String requestUrl = getRequestUrl(req); + LogKit.info("SSO登录集成登录,访问地址," + requestUrl); + //CustomDataConfig.addUrl(state, requestUrl); + String locationUrl = getOAuthCodeUrl(state); + res.sendRedirect(locationUrl); + return; + } + + CustomUserInfo customUserInfo = getIdmOAuthUsername(req); + String loginUsername = customUserInfo.getUserId(); + if (StringKit.isEmpty(loginUsername)) { + filterChain.doFilter(req, res); + return; + } + + LogKit.info("SSO登录集成登录, OAuth 用户名:" + loginUsername); + //User user = getUserByUserNameIgnoreCase(loginUsername); + //loginUsername = loginUsername.toLowerCase(); + User user = UserService.getInstance().getUserByUserName(loginUsername); + boolean tipsOption = false; + String tipsContent = ""; + if (user == null) { + //tipsOption = true; + LogKit.info("SSO登录集成登录,用户名:" + loginUsername + "在报表平台不存在"); + //tipsContent = "在报表服务器上不存在"; + PasswordValidator passwordValidator = UserSourceFactory.getInstance().getUserSource(ManualOperationType.KEY).getPasswordValidator(); + User record = (new User()).userName(customUserInfo.getUserId()).realName(customUserInfo.getUsername()).password(passwordValidator.encode(customUserInfo.getUserId(), "111111")).email(customUserInfo.getEmail()).mobile(customUserInfo.getPhone()).creationType(ManualOperationType.KEY).lastOperationType(ManualOperationType.KEY).enable(true); + AuthorityContext.getInstance().getUserController().add(record); + } else if (!user.isEnable()) { + tipsOption = true; + LogKit.info("SSO登录集成登录,用户名:" + loginUsername + "在报表平台上被禁用"); + tipsContent = "在报表平台上被禁用"; + } + + if (tipsOption) { + String jumpContent = "\n" + + "\n" + + " \n" + + " 提示\n" + + "\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("中金SSO登录集成登录,报表平台用户名:" + loginUsername); + + LogKit.info("SSO登录集成登录,报表平台用户名:" + loginUsername+"生成 login token"); + String loginToken = LoginService.getInstance().login(req, res, loginUsername); + req.setAttribute("fine_auth_token", loginToken); + /* if (pcOption) { + String state = WebUtils.getHTTPRequestParameter(req, "state"); + String url = CustomDataConfig.getUrlAndDestroy(state); + LogKit.info("中金SSO登录集成登录,用户名:" + loginUsername + "在报表平台,state url:" + url); + url = changeUrlScheme(url); + if (StringKit.isNotEmpty(url)) { + LogKit.info("中金SSO登录集成登录,用户名:" + loginUsername + "在报表平台," + url); + res.sendRedirect(url); + return; + } + }*/ + filterChain.doFilter(req, res); + } catch (Exception e) { + FineLoggerFactory.getLogger().error("SSO登录集成登录出错," + e.getMessage(), e); + } + } + + private String changeUrlScheme(String url) { + if (StringKit.isEmpty(url)) { + return ""; + } + if ((!url.startsWith("http://")) && (!url.startsWith("https://"))) { + return url; + } + + String frUrl = CustomDataConfig.getInstance().getFrUrl(); + if (StringKit.isEmpty(frUrl)) { + return url; + } + + if ((url.startsWith("http://")) && (frUrl.startsWith("http://"))) { + return url; + } + if ((url.startsWith("https://")) && (frUrl.startsWith("https://"))) { + return url; + } + String tempUrl = url; + if ((url.startsWith("http://")) && (frUrl.startsWith("https://"))) { + tempUrl = "https://" + url.substring(7); + } + + if ((url.startsWith("https://")) && (frUrl.startsWith("http://"))) { + tempUrl = "http://" + url.substring(8); + } + return tempUrl; + } + + + 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; + } + + private String getOAuthCodeUrl(String state) { + String url = CustomDataConfig.getInstance().getoAuthCodeUrl() + "?client_id=" + CustomDataConfig.getInstance().getIdmClientId() + "&scope=user_info&redirect_uri=" + CustomDataConfig.getInstance().getFrUrl() + "&response_type=code&access_type=offline&include_granted_scopes=true&state=" + state; + LogKit.info("SSO登录集成登录,SSO请求授权API url:" + url); + return url; + } + + private String getUuid() { + String uuid = UUID.randomUUID().toString().replace("-", ""); + return uuid; + } + + + /** + * 判断app是否允许登录IDM OAuth + * + * @param req + * @return + */ + private boolean isAllowIdmOAuthLogin(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.equals(loginTypeConfigValue, loginTypeValue); + } + + + /** + * 判断字符串是否全是数字 + * + * @param str + * @return + */ + public static boolean isNumeric(String str) { + if (StringKit.isEmpty(str)) { + return false; + } + for (int i = str.length(); --i >= 0; ) { + if (!Character.isDigit(str.charAt(i))) { + + return false; + + } + } + return true; + } + + + /** + * 获取IDM OAuth 用户名 + * + * @param req + * @return + */ + private CustomUserInfo getIdmOAuthUsername(HttpServletRequest req) { + try { + if (req == null) { + return new CustomUserInfo(); + } + String oAuthCode = WebUtils.getHTTPRequestParameter(req, "code"); + if (StringKit.isEmpty(oAuthCode)) { + return new CustomUserInfo(); + } + LogKit.info("SSO登录集成登录,OAuth Code:" + oAuthCode); + + RequestConfig requestConfig = RequestConfig.custom() + .setConnectionRequestTimeout(10000) + .setSocketTimeout(10000) // 服务端相应超时 + .setConnectTimeout(10000) // 建立socket链接超时时间 + .build(); + + //获取Access Token + //环境地址/getTokens + String accessTokenUrl = CustomDataConfig.getInstance().getAccessTokenUrl(); + LogKit.info("SSO登录集成登录,获取access_toke url:" + accessTokenUrl); + HttpPost httpPost = new HttpPost(accessTokenUrl); + httpPost.addHeader("User-Agent", DEFAULT_USER_AGENT); + + List params = new ArrayList(); + NameValuePair redirectUriNameValuePair = new BasicNameValuePair("redirect_uri", CustomDataConfig.getInstance().getFrUrl()); + NameValuePair codeNameValuePair = new BasicNameValuePair("code", oAuthCode); + NameValuePair grantTypeNameValuePair = new BasicNameValuePair("grant_type", "authorization_code"); + NameValuePair clientIdValuePair = new BasicNameValuePair("client_id", CustomDataConfig.getInstance().getIdmClientId()); + NameValuePair clientSecretValuePair = new BasicNameValuePair("client_secret", CustomDataConfig.getInstance().getIdmClientSecret()); + params.add(redirectUriNameValuePair); + params.add(codeNameValuePair); + params.add(grantTypeNameValuePair); + params.add(clientIdValuePair); + params.add(clientSecretValuePair); + httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8")); + httpPost.setHeader("Content-type", "application/x-www-form-urlencoded"); + /* + String auth = CustomDataConfig.getInstance().getIdmClientId() + ":" + CustomDataConfig.getInstance().getIdmClientSecret(); + String tempAuthValue = Base64.getEncoder().encodeToString(auth.getBytes()); + + */ + + + httpPost.setConfig(requestConfig); + CloseableHttpClient httpClient = Utils.createHttpClient(accessTokenUrl); + CloseableHttpResponse response = httpClient.execute(httpPost); + int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode != HttpStatus.SC_OK) { + response.close(); + httpClient.close(); + LogKit.info("SSO登录集成登录,获取Access Token请求出错,http status:" + statusCode); + return new CustomUserInfo(); + } + + HttpEntity httpEntity = response.getEntity(); + if (httpEntity == null) { + response.close(); + httpClient.close(); + LogKit.info("SSO登录集成登录,获取Access Token请求出错,http响应内容为空"); + return new CustomUserInfo(); + } + String responseContent = EntityUtils.toString(httpEntity, "UTF-8"); + response.close(); + if (StringKit.isEmpty(responseContent)) { + httpClient.close(); + LogKit.info("SSO登录集成登录,获取Access Token请求出错,http响应内容为空1"); + return new CustomUserInfo(); + } + LogKit.info("SSO登录集成登录,获取Access Token请求,http响应内容\n" + responseContent); + + String accessToken = getAccessToken(responseContent); + if (StringKit.isEmpty(accessToken)) { + httpClient.close(); + LogKit.info("SSO登录集成登录,获取Access Token请求出错,access_token为空"); + return new CustomUserInfo(); + } + LogKit.info("SSO登录集成登录,Access Token:" + accessToken); + + String userUrl = CustomDataConfig.getInstance().getUserUrl(); + + httpPost = new HttpPost(userUrl); + httpPost.setConfig(requestConfig); + String authValue = "Bearer " + accessToken; + httpPost.setHeader(HttpHeaders.AUTHORIZATION, authValue); + response = httpClient.execute(httpPost); + statusCode = response.getStatusLine().getStatusCode(); + if (statusCode != HttpStatus.SC_OK) { + response.close(); + httpClient.close(); + LogKit.info("SSO登录集成登录,获取用户信息请求出错,http status:" + statusCode); + return new CustomUserInfo(); + } + + httpEntity = response.getEntity(); + if (httpEntity == null) { + response.close(); + httpClient.close(); + LogKit.info("SSO登录集成登录,获取用户信息请求出错,http响应内容为空"); + return new CustomUserInfo(); + } + responseContent = EntityUtils.toString(httpEntity, "UTF-8"); + response.close(); + httpClient.close(); + if (StringKit.isEmpty(responseContent)) { + LogKit.info("SSO登录集成登录,获取用户信息请求出错,http响应内容为空1"); + return new CustomUserInfo(); + } + LogKit.info("SSO登录集成登录,获取用户信息请求,http响应内容\n" + responseContent); + JSONObject jsonObject = new JSONObject(responseContent); + String uid = jsonObject.getString("login_name"); + if (StringKit.isEmpty(uid)) { + LogKit.info("SSO登录集成登录,,获取用户信息请求出错,login_name为空"); + return new CustomUserInfo(); + } + LogKit.info("SSO登录集成登录,login_name:" + uid); + + CustomUserInfo customUserInfo = new CustomUserInfo(); + customUserInfo.setUserId(uid); + customUserInfo.setUsername(jsonObject.getString("user_name")); + customUserInfo.setEmail(jsonObject.getString("email_address")); + customUserInfo.setPhone(jsonObject.getString("phone")); + customUserInfo.setValid(true); + return customUserInfo; + } catch (Exception e) { + FineLoggerFactory.getLogger().error("SSO登录集成登录获取用户名出错," + e.getMessage(), e); + } + return new CustomUserInfo(); + } + + private String getAccessToken(String content) { + if (StringKit.isEmpty(content)) { + return ""; + } + JSONObject jsonObject = new JSONObject(content); + String token = jsonObject.getString("access_token"); + return token; + } + + + 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; + } + 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; + } + + +}