From 373b8c4a237828a6375c045dd0e25af2481600d7 Mon Sep 17 00:00:00 2001 From: "LAPTOP-SB56SG4Q\\86185" Date: Mon, 9 Aug 2021 13:54:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E5=BC=80=E6=BA=90=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E6=9D=90=E6=96=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- JSD-7492 -需求确认书V1.docx | Bin 0 -> 62044 bytes README.md | 5 +- plugin.xml | 16 ++ readme.txt | 9 + .../com/fr/plugin/ctfo/sso/Oauth2Filter.java | 204 ++++++++++++++++++ src/main/resources/xplatform.properties | 5 + xplatform.properties | 5 + 7 files changed, 243 insertions(+), 1 deletion(-) create mode 100644 JSD-7492 -需求确认书V1.docx create mode 100644 plugin.xml create mode 100644 readme.txt create mode 100644 src/main/java/com/fr/plugin/ctfo/sso/Oauth2Filter.java create mode 100644 src/main/resources/xplatform.properties create mode 100644 xplatform.properties diff --git a/JSD-7492 -需求确认书V1.docx b/JSD-7492 -需求确认书V1.docx new file mode 100644 index 0000000000000000000000000000000000000000..5bd7b28f9584c339143aad8b246d894599bf9ba4 GIT binary patch literal 62044 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 literal 0 HcmV?d00001 diff --git a/README.md b/README.md index 242d5c0..be60685 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ # open-JSD-7942 -JSD-7942 开源任务材料 \ No newline at end of file +JSD-7942 开源任务材料\ +免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ +仅作为开发者学习参考使用!禁止用于任何商业用途!\ +为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系hugh处理。 \ No newline at end of file diff --git a/plugin.xml b/plugin.xml new file mode 100644 index 0000000..ce711ed --- /dev/null +++ b/plugin.xml @@ -0,0 +1,16 @@ + + + com.fr.plugin.ctfo.sso + + yes + 1.2 + 10.0 + 2018-07-31 + fr.open + + + + + + + \ No newline at end of file diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..edf4a67 --- /dev/null +++ b/readme.txt @@ -0,0 +1,9 @@ + +此次完成功能如下 + a、单点登录 + +1、将压缩文件解压后的xplatform.properties配置文件拷贝至 %部署路径%/WEB-INF/resources, 并修改对应配置 + +2、安装本插件,插件安装见连接http://help.finereport.com/doc-view-2198.html + +3、进入系统测试单点登录,访问地址为http://ip:port/webroot/decision \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/ctfo/sso/Oauth2Filter.java b/src/main/java/com/fr/plugin/ctfo/sso/Oauth2Filter.java new file mode 100644 index 0000000..40fd5fd --- /dev/null +++ b/src/main/java/com/fr/plugin/ctfo/sso/Oauth2Filter.java @@ -0,0 +1,204 @@ +package com.fr.plugin.ctfo.sso; + +import com.fr.base.PropertiesUtils; +import com.fr.common.util.Assert; +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.utils.DecisionServiceConstants; +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.http.HttpToolbox; +import com.fr.json.JSONObject; +import com.fr.log.FineLoggerFactory; +import com.fr.plugin.transform.FunctionRecorder; +import com.fr.stable.StringUtils; +import com.fr.stable.web.Device; + +import javax.servlet.FilterChain; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.net.URLEncoder; +import java.time.Instant; +import java.util.Collections; +import java.util.Properties; +import java.util.stream.Stream; + +/** + * @author fr.open + * @since 2021/5/25 + */ +@FunctionRecorder +public class Oauth2Filter extends AbstractGlobalRequestFilterProvider { + + private static final String[] NOT_FILTER = { + "/decision/file", + "/decision/resources", + "/system", + "/materials.min.js.map", + "/remote", + "/login", + "/login/config", + }; + + private final String apiAuthorize; + + private final String apiAppKey; + + private final String apiAppSecret; + + private final String apiGetToken; + + private final String apiGetUser; + + public Oauth2Filter() { + Properties props = PropertiesUtils.getProperties("xplatform"); + apiAuthorize = getValue(props, "api.authorize"); + apiAppKey = getValue(props, "api.app-key"); + apiAppSecret = getValue(props, "api.app-secret"); + apiGetToken = getValue(props, "api.get-token"); + apiGetUser = getValue(props, "api.get-user"); + } + + private String getValue(Properties props, String key) { + String value = props.getProperty(key); + Assert.hasText(value, "配置项[" + key + "]不能为空"); + return value; + } + + @Override + public String filterName() { + return "ctfoOauth2"; + } + + @Override + public String[] urlPatterns() { + return new String[]{"/*"}; + } + + @Override + public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) { + final String url = request.getRequestURL().toString(); + FineLoggerFactory.getLogger().info("sso >> URL of this request => {}", url); + try { + if (isLogin(request) || Stream.of(NOT_FILTER).anyMatch(url::contains)) { + FineLoggerFactory.getLogger().info("sso >> 已登录或默认可放行的请求地址"); + chain.doFilter(request, response); + return; + } + + String code = request.getParameter("code"); + if (StringUtils.isBlank(code)) { + FineLoggerFactory.getLogger().info("sso >> Parameter['code'] 值为空, 跳转到登录页"); + toAuthorize(request, response); + return; + } + + FineLoggerFactory.getLogger().info("sso >> Parameter['code'] => [{}]", code); + String token; + try { + token = getAccessToken(request, code); + } catch (Exception e) { + FineLoggerFactory.getLogger().error("sso >> 获取access token失败", e); + chain.doFilter(request, response); + return; + } + + FineLoggerFactory.getLogger().info("sso >> AccessToken => [{}]", token); + String username; + try { + username = getUsername(token); + } catch (Exception e) { + FineLoggerFactory.getLogger().error("sso >> 获取用户名失败", e); + chain.doFilter(request, response); + return; + } + + FineLoggerFactory.getLogger().info("sso >> username => [{}]", token); + login(username, request, response); + chain.doFilter(request, response); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private void toAuthorize(HttpServletRequest request, HttpServletResponse response) throws IOException { + String urlPattern = "%s?response_type=code&client_id=%s&redirect_uri=%s&oauth_timestamp=%s"; + String rURI = request.getRequestURL().toString(); +// if (request.getQueryString() != null) { +// rURI += "?" + request.getQueryString(); +// } + rURI = URLEncoder.encode(rURI, "utf-8"); + String url = String.format(urlPattern, apiAuthorize, apiAppKey, rURI, Instant.now().toEpochMilli()); + FineLoggerFactory.getLogger().info("sso >> 登录认证地址 => [{}]", url); + response.sendRedirect(url); + } + + private String getAccessToken(HttpServletRequest request, String code) throws IOException, IllegalAccessException { + String api = "%s?grant_type=authorization_code&oauth_timestamp=%s&client_id=%s&client_secret=%s&code=%s&redirect_uri=%s"; + String rURI = request.getRequestURL().toString(); + rURI = URLEncoder.encode(rURI, "utf-8"); +// if (request.getQueryString() != null) { +// rURI += "?" + request.getQueryString(); +// } + api = String.format(api, apiGetToken, Instant.now().toEpochMilli(), apiAppKey, apiAppSecret, code, rURI); + FineLoggerFactory.getLogger().info("sso >> CODE换取AccessToken的接口地址 => [{}]", api); + String response = HttpToolbox.post(api, Collections.emptyMap()); + FineLoggerFactory.getLogger().info("sso >> CODE换取AccessToken的接口返回内容 => [{}]", response); + JSONObject res = new JSONObject(response); + if (res.has("access_token") && StringUtils.isNotBlank(res.getString("access_token"))) { + return res.getString("access_token"); + } + throw new IllegalAccessException(); + } + + private String getUsername(String token) throws IOException, IllegalAccessException { + String api = String.format("%s?access_token=%s", apiGetUser, token); + FineLoggerFactory.getLogger().info("sso >> 获取用户信息接口地址 => [{}]", api); + String response = HttpToolbox.get(api); + FineLoggerFactory.getLogger().info("sso >> 获取用户信息接口地址返回内容 => [{}]", response); + JSONObject res = new JSONObject(response); + if (res.has("attributes")) { + JSONObject attrs = res.getJSONObject("attributes"); + if (attrs.has("account_no") && StringUtils.isNotBlank(attrs.getString("account_no"))) { + return attrs.getString("account_no"); + } + } + throw new IllegalAccessException(); + } + + private void login(String username, HttpServletRequest request, HttpServletResponse response) { + try { + User user = UserService.getInstance().getUserByUserName(username); + if (user == null) { + FineLoggerFactory.getLogger().error("sso >> User \"{}\" does not exist", username); + return; + } + FineLoggerFactory.getLogger().info("sso >> Getted user: {}", user); + String token = LoginService.getInstance().login(request, response, username); + FineLoggerFactory.getLogger().info("sso >> Getted login token: {}", token); + request.setAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME, token); + FineLoggerFactory.getLogger().info("sso >> User[{}] login successfully", username); + } catch (Exception e) { + FineLoggerFactory.getLogger().error("sso >> Failed to login with[" + username + "]", e); + } + } + + private boolean isLogin(HttpServletRequest request) { + String oldToken = TokenResource.COOKIE.getToken(request); + return oldToken != null && checkTokenValid(request, (String) oldToken); + } + + private boolean checkTokenValid(HttpServletRequest req, String token) { + try { + Device device = NetworkHelper.getDevice(req); + LoginService.getInstance().loginStatusValid(token, TerminalHandler.getTerminal(req, device)); + return true; + } catch (Exception ignore) { + } + return false; + } +} diff --git a/src/main/resources/xplatform.properties b/src/main/resources/xplatform.properties new file mode 100644 index 0000000..013c523 --- /dev/null +++ b/src/main/resources/xplatform.properties @@ -0,0 +1,5 @@ +api.app-key=1238912731982 +api.app-secret=1293102832190380 +api.authorize=http://114.242.227.113:10000/login/esc-sso/oauth2.0/authorize +api.get-token=http://114.242.227.113:10000/login/esc-sso/oauth2.0/accessToken +api.get-user=http://114.242.227.113:10000/login/esc-sso/oauth2.0/profile \ No newline at end of file diff --git a/xplatform.properties b/xplatform.properties new file mode 100644 index 0000000..d14a7d5 --- /dev/null +++ b/xplatform.properties @@ -0,0 +1,5 @@ +api.app-key= +api.app-secret= +api.authorize=xxx/oauth2.0/authorize +api.get-token=xxx/oauth2.0/accessToken +api.get-user=xxxo/oauth2.0/profile \ No newline at end of file