diff --git a/JSD-9434-需求确认书V1.docx b/JSD-9434-需求确认书V1.docx
new file mode 100644
index 0000000..423a4fa
Binary files /dev/null and b/JSD-9434-需求确认书V1.docx differ
diff --git a/README.md b/README.md
index e1ab08b..5ee7db1 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,6 @@
# open-JSD-9434
-JSD-9434 门户集成+消息推送
\ No newline at end of file
+JSD-9434 门户集成+消息推送\
+免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\
+仅作为开发者学习参考使用!禁止用于任何商业用途!\
+为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系hugh处理。
\ No newline at end of file
diff --git a/plugin.xml b/plugin.xml
new file mode 100644
index 0000000..3e6f21d
--- /dev/null
+++ b/plugin.xml
@@ -0,0 +1,28 @@
+
+
+ com.fr.plugin.xxxx.fymh.sso
+
+ yes
+ 1.7
+ 10.0
+ 2018-07-31
+ fr.open
+
+
+ [2021-01-06]【1.1】配置参数修改。
+ [2021-01-06]【1.2】接口调用修改。
+ [2021-01-07]【1.3】返回数据解析。
+ [2021-01-07]【1.4】跳转地址修改。
+ [2021-01-07]【1.5】日志打印。
+ [2021-01-07]【1.6】待办鉴权。
+ [2021-01-07]【1.6】增加回调地址。
+ ]]>
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/xxxx/fymh/sso/CommonUtils.java b/src/main/java/com/fr/plugin/xxxx/fymh/sso/CommonUtils.java
new file mode 100644
index 0000000..6c695b2
--- /dev/null
+++ b/src/main/java/com/fr/plugin/xxxx/fymh/sso/CommonUtils.java
@@ -0,0 +1,152 @@
+package com.fr.plugin.xxxx.fymh.sso;
+
+import com.fr.data.NetworkHelper;
+import com.fr.decision.authority.data.User;
+import com.fr.decision.mobile.terminal.TerminalHandler;
+import com.fr.decision.webservice.utils.DecisionServiceConstants;
+import com.fr.decision.webservice.utils.DecisionStatusService;
+import com.fr.decision.webservice.utils.WebServiceUtils;
+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.locale.InterProviderFactory;
+import com.fr.log.FineLoggerFactory;
+import com.fr.stable.StringUtils;
+import com.fr.stable.web.Device;
+import com.fr.web.utils.WebUtils;
+
+import javax.servlet.FilterChain;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * @author fr.open
+ * @since 2021/8/24
+ */
+public class CommonUtils {
+
+ public static String getProperty(Properties props, String key, String defaultValue, boolean allowBlank) {
+ String value = props.getProperty(key);
+ if (StringUtils.isNotBlank(value)) {
+ return value;
+ } else {
+ if (allowBlank) {
+ LogUtils.warn("Property[" + key + "] value is blank.");
+ return defaultValue;
+ } else {
+ throw new IllegalArgumentException("Property[" + key + "] cann't be blank.");
+ }
+ }
+ }
+
+ public static String getProperty(Properties props, String key, boolean allowBlank) {
+ return getProperty(props, key, null, allowBlank);
+ }
+
+ public static String getProperty(Properties props, String key) {
+ return getProperty(props, key, null, true);
+ }
+
+ public static boolean isLogin(HttpServletRequest request) {
+ String oldToken = TokenResource.COOKIE.getToken(request);
+ return oldToken != null && checkTokenValid(request, (String) oldToken);
+ }
+
+ private static 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;
+ }
+
+ /**
+ * 跳转到过滤器链中的下一个过滤器
+ *
+ * @param request
+ * @param response
+ * @param chain
+ */
+ public static void next(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {
+ try {
+ chain.doFilter(request, response);
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ }
+
+ public static void login(String username, HttpServletRequest request, HttpServletResponse response) {
+ try {
+ User user = UserService.getInstance().getUserByUserName(username);
+ if (user == null) {
+ throw new RuntimeException("系统未授权, 当前用户是\"" + username + "\"");
+ }
+ String token = LoginService.getInstance().login(request, response, user.getUserName());
+ request.setAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME, token);
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error("sso >> Failed to login with[" + username + "]", e);
+ throw new RuntimeException("用户\"" + username + "\"登录失败");
+ }
+ }
+
+ public static boolean isMobileDevice(HttpServletRequest request) {
+ if (WebUtils.getDevice(request).isMobile()) {
+ LogUtils.debug4plugin("current request is is mobile request ,url is {}", request.getRequestURI());
+ return true;
+ }
+ String requestHeader = request.getHeader("user-agent");
+ String[] deviceArray = new String[]{"android", "iphone", "ipad", "ios", "windows phone", "wechat"};
+ if (requestHeader == null) {
+ return false;
+ }
+ requestHeader = requestHeader.toLowerCase();
+ for (int i = 0; i < deviceArray.length; i++) {
+ if (requestHeader.toLowerCase().contains(deviceArray[i])) {
+ LogUtils.debug4plugin("current request:{} is mobile request!", request.getRequestURI());
+ return true;
+ }
+ }
+ String op = WebUtils.getHTTPRequestParameter(request, "op");
+ return StringUtils.isNotBlank(op) && StringUtils.equals("h5", op);
+ }
+
+ public static void cacheParams(String key, Map values) {
+ try {
+ DecisionStatusService.originUrlStatusService().put(key, values);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static String getCachedParam(String key, String name) {
+ try {
+ Map values = DecisionStatusService.originUrlStatusService().get(key);
+ return values.get(name);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void setError(HttpServletResponse res, String reason) {
+ try {
+ PrintWriter printWriter = WebUtils.createPrintWriter(res);
+ Map map = new HashMap<>();
+ map.put("result", InterProviderFactory.getProvider().getLocText("Fine-Engine_Error_Page_Result"));
+ map.put("reason", reason);
+ map.put("solution", InterProviderFactory.getProvider().getLocText("Fine-Engine_Please_Contact_Platform_Admin"));
+ String page = WebServiceUtils.parseWebPageResourceSafe("com/fr/web/controller/decision/entrance/resources/unavailable.html", map);
+ printWriter.write(page);
+ printWriter.flush();
+ printWriter.close();
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ }
+
+}
diff --git a/src/main/java/com/fr/plugin/xxxx/fymh/sso/FeiYuSsoConfig.java b/src/main/java/com/fr/plugin/xxxx/fymh/sso/FeiYuSsoConfig.java
new file mode 100644
index 0000000..7a00662
--- /dev/null
+++ b/src/main/java/com/fr/plugin/xxxx/fymh/sso/FeiYuSsoConfig.java
@@ -0,0 +1,128 @@
+package com.fr.plugin.xxxx.fymh.sso;
+
+import com.fr.config.*;
+import com.fr.config.holder.Conf;
+import com.fr.config.holder.factory.Holders;
+import com.fr.stable.StringUtils;
+
+
+/**
+ * @author fr.open
+ * @since 2021/12/04
+ */
+@Visualization(category = "门户配置")
+public class FeiYuSsoConfig extends DefaultConfiguration {
+
+ private static volatile FeiYuSsoConfig config = null;
+
+ public static FeiYuSsoConfig getInstance() {
+ if (config == null) {
+ config = ConfigContext.getConfigInstance(FeiYuSsoConfig.class);
+ }
+ return config;
+ }
+
+ @Identifier(value = "debugSwitch", name = "插件调试开关", description = "日志调试模式", status = Status.SHOW)
+ private Conf debugSwitch = Holders.simple(true);
+
+ public Boolean getDebugSwitch() {
+ return this.debugSwitch.get();
+ }
+
+ public void setDebugSwitch(Boolean debugSwitch) {
+ this.debugSwitch.set(debugSwitch);
+ }
+
+ @Identifier(value = "authUser", name = "授权账户", description = "授权账户", status = Status.SHOW)
+ private Conf authUser = Holders.simple(StringUtils.EMPTY);
+
+ public String getAuthUser() {
+ return this.authUser.get();
+ }
+
+ public void setAuthUser(String authUser) {
+ this.authUser.set(authUser);
+ }
+
+ @Identifier(value = "authPass", name = "授权密码", description = "授权密码", status = Status.SHOW)
+ private Conf authPass = Holders.simple(StringUtils.EMPTY);
+
+ public String getAuthPass() {
+ return this.authPass.get();
+ }
+
+ public void setAuthPass(String authPass) {
+ this.authPass.set(authPass);
+ }
+
+ @Identifier(value = "infoUrl", name = "用户信息接口地址", description = "用户信息接口地址", status = Status.SHOW)
+ private Conf infoUrl = Holders.simple(StringUtils.EMPTY);
+
+ public String getInfoUrl() {
+ return this.infoUrl.get();
+ }
+
+ public void setInfoUrl(String infoUrl) {
+ this.infoUrl.set(infoUrl);
+ }
+
+ @Identifier(value = "clientId", name = "客⼾端ID", description = "客⼾端ID", status = Status.SHOW)
+ private Conf clientId = Holders.simple(StringUtils.EMPTY);
+
+ public String getClientId() {
+ return this.clientId.get();
+ }
+
+ public void setClientId(String clientId) {
+ this.clientId.set(clientId);
+ }
+
+ @Identifier(value = "clientSecret", name = "客⼾端密钥", description = "客⼾端密钥", status = Status.SHOW)
+ private Conf clientSecret = Holders.simple(StringUtils.EMPTY);
+
+ public String getClientSecret() {
+ return this.clientSecret.get();
+ }
+
+ public void setClientSecret(String clientSecret) {
+ this.clientSecret.set(clientSecret);
+ }
+
+ @Identifier(value = "tokenUrl", name = "获取token的地址", description = "获取token的地址⼾端密钥", status = Status.SHOW)
+ private Conf tokenUrl = Holders.simple(StringUtils.EMPTY);
+
+ public String getTokenUrl() {
+ return this.tokenUrl.get();
+ }
+
+ public void setTokenUrl(String tokenUrl) {
+ this.tokenUrl.set(tokenUrl);
+ }
+
+ @Identifier(value = "todoUrl", name = "推送待办地址", description = "推送待办地址", status = Status.SHOW)
+ private Conf todoUrl = Holders.simple(StringUtils.EMPTY);
+
+ public String getTodoUrl() {
+ return this.todoUrl.get();
+ }
+
+ public void setTodoUrl(String todoUrl) {
+ this.todoUrl.set(todoUrl);
+ }
+
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ FeiYuSsoConfig cloned = (FeiYuSsoConfig) super.clone();
+ cloned.debugSwitch = (Conf) debugSwitch.clone();
+ cloned.authUser = (Conf) authUser.clone();
+ cloned.authPass = (Conf) authPass.clone();
+ cloned.infoUrl = (Conf) infoUrl.clone();
+ cloned.clientId = (Conf) clientId.clone();
+ cloned.clientSecret = (Conf) clientSecret.clone();
+ cloned.tokenUrl = (Conf) tokenUrl.clone();
+ cloned.todoUrl = (Conf) todoUrl.clone();
+ return cloned;
+ }
+
+
+}
diff --git a/src/main/java/com/fr/plugin/xxxx/fymh/sso/HttpUtil.java b/src/main/java/com/fr/plugin/xxxx/fymh/sso/HttpUtil.java
new file mode 100644
index 0000000..e9e9459
--- /dev/null
+++ b/src/main/java/com/fr/plugin/xxxx/fymh/sso/HttpUtil.java
@@ -0,0 +1,337 @@
+package com.fr.plugin.xxxx.fymh.sso;
+
+import com.fr.json.JSONObject;
+import com.fr.log.FineLoggerFactory;
+import com.fr.stable.StringUtils;
+import com.fr.third.org.apache.http.HttpResponse;
+import com.fr.third.org.apache.http.HttpStatus;
+import com.fr.third.org.apache.http.NameValuePair;
+import com.fr.third.org.apache.http.client.HttpClient;
+import com.fr.third.org.apache.http.client.entity.UrlEncodedFormEntity;
+import com.fr.third.org.apache.http.client.methods.HttpPost;
+import com.fr.third.org.apache.http.config.Registry;
+import com.fr.third.org.apache.http.config.RegistryBuilder;
+import com.fr.third.org.apache.http.conn.socket.ConnectionSocketFactory;
+import com.fr.third.org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import com.fr.third.org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import com.fr.third.org.apache.http.impl.client.HttpClients;
+import com.fr.third.org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import com.fr.third.org.apache.http.message.BasicNameValuePair;
+import com.fr.third.org.apache.http.util.EntityUtils;
+
+import javax.net.ssl.*;
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.security.cert.CertificateException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @Author fr.open
+ * @Date 2020/12/05
+ * @Description
+ **/
+public class HttpUtil {
+
+ private static HostnameVerifier hv = new HostnameVerifier() {
+ @Override
+ public boolean verify(String urlHostName, SSLSession session) {
+ System.out.println("Warning: URL Host: " + urlHostName + " vs. "
+ + session.getPeerHost());
+ return true;
+ }
+ };
+
+ /**
+ * 发送get请求
+ *
+ * @param url
+ * @param param
+ * @param header
+ * @return
+ * @throws IOException
+ */
+ public static String sendGet(String url, Map param, Map header) {
+ String result = "";
+ BufferedReader in = null;
+ String urlNameString = url;
+ try {
+ if (param != null) {
+ urlNameString += "?";
+ urlNameString += param.entrySet()
+ .stream()
+ .map(entry -> entry.getKey() + "=" + entry.getValue())
+ .collect(Collectors.joining("&"));
+ }
+
+ URL realUrl = new URL(urlNameString);
+ // 打开和URL之间的连接
+ HttpURLConnection connection;
+ if (url.startsWith("https")) {
+ trustAllHttpsCertificates();
+ HttpsURLConnection.setDefaultHostnameVerifier(hv);
+ connection = (HttpURLConnection) realUrl.openConnection();
+ } else {
+ connection = (HttpURLConnection) realUrl.openConnection();
+ }
+ //设置超时时间
+ connection.setDoInput(true);
+ connection.setRequestMethod("GET");
+ connection.setConnectTimeout(5000);
+ connection.setReadTimeout(15000);
+ // 设置通用的请求属性
+ if (header != null) {
+ Iterator> it = header.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry entry = it.next();
+ System.out.println(entry.getKey() + ":::" + entry.getValue());
+ connection.setRequestProperty(entry.getKey(), entry.getValue());
+ }
+ }
+ connection.setRequestProperty("accept", "*/*");
+ connection.setRequestProperty("connection", "Keep-Alive");
+ connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
+ // 建立实际的连接
+ connection.connect();
+ // 定义 BufferedReader输入流来读取URL的响应,设置utf8防止中文乱码
+ in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));
+ String line;
+ while ((line = in.readLine()) != null) {
+ result += line;
+ }
+ if (in != null) {
+ in.close();
+ }
+ }catch (Exception e){
+ FineLoggerFactory.getLogger().error(e,"get url error ,url is:{},error is {}",urlNameString,e.getMessage());
+ }
+ return result;
+ }
+
+ public static String doFormPost(String url, Map header, Map map, String chartset) {
+ //声明返回结果
+ String result = "";
+ UrlEncodedFormEntity entity = null;
+ HttpResponse httpResponse = null;
+ HttpClient httpClient = null;
+ try {
+ // 创建连接
+ httpClient = HttpClients.createDefault();
+ ;
+ if (url.startsWith("https")) {
+ SSLContext sslcontext = createIgnoreVerifySSL();
+ Registry socketFactoryRegistry = RegistryBuilder.create()
+ .register("http", PlainConnectionSocketFactory.INSTANCE)
+ .register("https", new SSLConnectionSocketFactory(sslcontext))
+ .build();
+ PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
+ HttpClients.custom().setConnectionManager(connManager);
+ httpClient = HttpClients.custom().setConnectionManager(connManager).build();
+ }
+ // 设置请求头和报文
+ HttpPost httpPost = new HttpPost(url);
+ if (header != null) {
+ header.forEach((k, v) -> {
+ httpPost.setHeader(k, String.valueOf(v));
+ });
+ }
+ //设置参数
+ List list = new ArrayList();
+ Iterator iterator = map.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Map.Entry elem = (Map.Entry) iterator.next();
+ list.add(new BasicNameValuePair(elem.getKey(), elem.getValue()));
+ }
+ entity = new UrlEncodedFormEntity(list, chartset == null ? "UTF-8" : chartset);
+ httpPost.setEntity(entity);
+ //执行发送,获取相应结果
+ httpResponse = httpClient.execute(httpPost);
+ if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
+ result = EntityUtils.toString(httpResponse.getEntity());
+ } else {
+ FineLoggerFactory.getLogger().error("Http post form code is {},message is {}", httpResponse.getStatusLine().getStatusCode(), EntityUtils.toString(httpResponse.getEntity()));
+ }
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ return result;
+
+ }
+
+ public static String sendPost(String url,Map header, JSONObject body) {
+ PrintWriter out = null;
+ BufferedReader in = null;
+ String result = StringUtils.EMPTY;
+ String res = StringUtils.EMPTY;
+ try {
+ String urlNameString = url;
+
+ URL realUrl = new URL(urlNameString);
+ // 打开和URL之间的连接
+ HttpURLConnection conn;
+ if (url.startsWith("https")) {
+ trustAllHttpsCertificates();
+ HttpsURLConnection.setDefaultHostnameVerifier(hv);
+ conn = (HttpURLConnection) realUrl.openConnection();
+ } else {
+ conn = (HttpURLConnection) realUrl.openConnection();
+ }
+ // 设置通用的请求属性
+ conn.setRequestProperty("accept", "*/*");
+ conn.setRequestProperty("connection", "Keep-Alive");
+ conn.setRequestProperty("user-agent",
+ "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
+ if(body != null && !body.isEmpty()){
+ conn.setRequestProperty("Content-Type","application/json;;charset=UTF-8");
+ }
+ //conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=----footfoodapplicationrequestnetwork");
+ if(header != null){
+ header.forEach((k, v) -> {
+ conn.setRequestProperty(k, v);
+ });
+ }
+ // 发送POST请求必须设置如下两行
+ conn.setDoOutput(true);
+ conn.setDoInput(true);
+ //获取请求头
+
+ // 获取URLConnection对象对应的输出流
+ out = new PrintWriter(conn.getOutputStream());
+ StringBuffer buffer = new StringBuffer();
+ /*param.forEach((k,v)->{
+ buffer.append("------footfoodapplicationrequestnetwork\r\n");
+ buffer.append("Content-Disposition: form-data; name=\"");
+ buffer.append(k);
+ buffer.append("\"\r\n\r\n");
+ buffer.append(v);
+ buffer.append("\r\n");
+ });
+ buffer.append("------footfoodapplicationrequestnetwork--\r\n");
+ out.print(buffer.toString());*/
+ // 发送请求参数
+ if(body != null){
+ out.print(body.toString());
+ }
+ // flush输出流的缓冲
+ out.flush();
+ // 定义BufferedReader输入流来读取URL的响应
+ in = new BufferedReader(
+ new InputStreamReader(conn.getInputStream()));
+ String line;
+ while ((line = in.readLine()) != null) {
+ result += line;
+ }
+ res = result;
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(),e);
+ }
+ //使用finally块来关闭输出流、输入流
+ finally{
+ try{
+ if(out!=null){
+ out.close();
+ }
+ if(in!=null){
+ in.close();
+ }
+ }
+ catch(IOException e){
+ FineLoggerFactory.getLogger().error(e.getMessage(),e);
+ }
+ }
+ return res;
+ }
+
+ private static void trustAllHttpsCertificates() throws Exception {
+ TrustManager[] trustAllCerts = new TrustManager[1];
+ TrustManager tm = new miTM();
+ trustAllCerts[0] = tm;
+ SSLContext sc = SSLContext.getInstance("SSL","SunJSSE");
+ sc.init(null, trustAllCerts, null);
+ HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
+ }
+
+
+ /**
+ * encode url by UTF-8
+ * @param url url before encoding
+ * @return url after encoding
+ */
+ public static String encodeUrl(String url){
+ String eurl = url;
+ try {
+ eurl = URLEncoder.encode(url,"UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ }
+ return eurl;
+ }
+
+ private static class miTM implements TrustManager,
+ X509TrustManager {
+ @Override
+ public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+
+ public boolean isServerTrusted(
+ java.security.cert.X509Certificate[] certs) {
+ return true;
+ }
+
+ public boolean isClientTrusted(
+ java.security.cert.X509Certificate[] certs) {
+ return true;
+ }
+
+ @Override
+ public void checkServerTrusted(
+ java.security.cert.X509Certificate[] certs, String authType)
+ throws CertificateException {
+ return;
+ }
+
+ @Override
+ public void checkClientTrusted(
+ java.security.cert.X509Certificate[] certs, String authType)
+ throws CertificateException {
+ return;
+ }
+ }
+
+ public static SSLContext createIgnoreVerifySSL() {
+ try {
+ SSLContext sc = SSLContext.getInstance("SSLv3");
+
+ // 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法
+ X509TrustManager trustManager = new X509TrustManager() {
+ @Override
+ public void checkClientTrusted(
+ java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
+ String paramString) throws CertificateException {
+ }
+
+ @Override
+ public void checkServerTrusted(
+ java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
+ String paramString) throws CertificateException {
+ }
+
+ @Override
+ public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+ };
+
+ sc.init(null, new TrustManager[]{trustManager}, null);
+ return sc;
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/com/fr/plugin/xxxx/fymh/sso/LRGT.java b/src/main/java/com/fr/plugin/xxxx/fymh/sso/LRGT.java
new file mode 100644
index 0000000..cef2f9a
--- /dev/null
+++ b/src/main/java/com/fr/plugin/xxxx/fymh/sso/LRGT.java
@@ -0,0 +1,27 @@
+package com.fr.plugin.xxxx.fymh.sso;
+
+import com.fr.plugin.context.PluginContext;
+import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor;
+
+/**
+ * 配置信息初始化
+ */
+
+public class LRGT extends AbstractPluginLifecycleMonitor {
+ @Override
+ public void afterRun(PluginContext pluginContext) {
+ FeiYuSsoConfig.getInstance();
+ }
+
+ @Override
+ public void beforeStop(PluginContext pluginContext) {
+ }
+
+ @Override
+ public void beforeUninstall(PluginContext pluginContext) {
+ }
+
+ @Override
+ public void afterInstall(PluginContext var1) {
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/xxxx/fymh/sso/LogUtils.java b/src/main/java/com/fr/plugin/xxxx/fymh/sso/LogUtils.java
new file mode 100644
index 0000000..99d70db
--- /dev/null
+++ b/src/main/java/com/fr/plugin/xxxx/fymh/sso/LogUtils.java
@@ -0,0 +1,120 @@
+package com.fr.plugin.xxxx.fymh.sso;
+
+import com.fr.log.FineLoggerFactory;
+import com.fr.log.FineLoggerProvider;
+import com.fr.plugin.context.PluginContexts;
+import com.fr.stable.StringUtils;
+
+/**
+ * @author fr.open
+ * @since 2021/12/04
+ */
+public final class LogUtils {
+ private static final String DEBUG_PREFIX = "[插件调试] ";
+ private static String LOG_PREFIX = PluginConstants.PLUGIN_NAME;
+ private static final String PLUGIN_VERSION;
+
+ private static final FineLoggerProvider LOGGER = FineLoggerFactory.getLogger();
+
+ static {
+ String version = PluginContexts.currentContext().getMarker().getVersion();
+ if (StringUtils.isNotBlank(version)) {
+ PLUGIN_VERSION = "[v" + version + "] ";
+ } else {
+ PLUGIN_VERSION = "[unknown version] ";
+ }
+
+ LOG_PREFIX = LOG_PREFIX + PLUGIN_VERSION;
+ }
+
+ public static void setPrefix(String prefix) {
+ if (prefix != null) {
+ LOG_PREFIX = prefix;
+ }
+ }
+
+ public static boolean isDebugEnabled() {
+ return LOGGER.isDebugEnabled();
+ }
+
+ public static void debug(String s) {
+ LOGGER.debug(LOG_PREFIX + s);
+ }
+
+ public static void debug(String s, Object... objects) {
+ LOGGER.debug(LOG_PREFIX + s, objects);
+ }
+
+ public static void debug(String s, Throwable throwable) {
+ LOGGER.debug(LOG_PREFIX + s, throwable);
+ }
+
+ public static void debug4plugin(String s) {
+ if (FeiYuSsoConfig.getInstance().getDebugSwitch()) {
+ LOGGER.error(DEBUG_PREFIX + LOG_PREFIX + s);
+ } else {
+ LOGGER.debug(LOG_PREFIX + s);
+ }
+ }
+
+ public static void debug4plugin(String s, Object... objects) {
+ if (FeiYuSsoConfig.getInstance().getDebugSwitch()) {
+ LOGGER.error(DEBUG_PREFIX + LOG_PREFIX + s, objects);
+ } else {
+ LOGGER.debug(LOG_PREFIX + s, objects);
+ }
+ }
+
+ public static void debug4plugin(String s, Throwable throwable) {
+ if (FeiYuSsoConfig.getInstance().getDebugSwitch()) {
+ LOGGER.error(DEBUG_PREFIX + LOG_PREFIX + s, throwable);
+ } else {
+ LOGGER.debug(LOG_PREFIX + s, throwable);
+ }
+ }
+
+
+ public static boolean isInfoEnabled() {
+ return LOGGER.isInfoEnabled();
+ }
+
+ public static void info(String s) {
+ LOGGER.info(LOG_PREFIX + s);
+ }
+
+ public static void info(String s, Object... objects) {
+ LOGGER.info(LOG_PREFIX + s, objects);
+ }
+
+ public static void warn(String s) {
+ LOGGER.warn(LOG_PREFIX + s);
+ }
+
+ public static void warn(String s, Object... objects) {
+ LOGGER.warn(LOG_PREFIX + s, objects);
+ }
+
+ public static void warn(String s, Throwable throwable) {
+ LOGGER.warn(LOG_PREFIX + s, throwable);
+ }
+
+ public static void warn(Throwable throwable, String s, Object... objects) {
+ LOGGER.warn(throwable, LOG_PREFIX + s, objects);
+ }
+
+ public static void error(String s) {
+ LOGGER.error(LOG_PREFIX + s);
+ }
+
+ public static void error(String s, Object... objects) {
+ LOGGER.error(LOG_PREFIX + s, objects);
+ }
+
+ public static void error(String s, Throwable throwable) {
+ LOGGER.error(LOG_PREFIX + s, throwable);
+ }
+
+ public static void error(Throwable throwable, String s, Object... objects) {
+ LOGGER.error(throwable, LOG_PREFIX + s, objects);
+ }
+}
diff --git a/src/main/java/com/fr/plugin/xxxx/fymh/sso/LoginFilter.java b/src/main/java/com/fr/plugin/xxxx/fymh/sso/LoginFilter.java
new file mode 100644
index 0000000..2091b29
--- /dev/null
+++ b/src/main/java/com/fr/plugin/xxxx/fymh/sso/LoginFilter.java
@@ -0,0 +1,94 @@
+package com.fr.plugin.xxxx.fymh.sso;
+
+import com.fr.base.TemplateUtils;
+import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
+import com.fr.json.JSONObject;
+import com.fr.plugin.context.PluginContexts;
+import com.fr.plugin.transform.FunctionRecorder;
+import com.fr.stable.StringUtils;
+import com.fr.stable.fun.Authorize;
+import com.fr.third.org.apache.commons.codec.binary.Base64;
+
+
+import javax.servlet.FilterChain;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.nio.charset.Charset;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @Author fr.open
+ * @Date 2022/1/3
+ * @Description
+ **/
+@FunctionRecorder
+@Authorize(callSignKey = PluginConstants.PLUGIN_ID)
+public class LoginFilter extends AbstractGlobalRequestFilterProvider {
+ @Override
+ public String filterName() {
+ return "xxxx";
+ }
+
+ @Override
+ public String[] urlPatterns() {
+ if (PluginContexts.currentContext().isAvailable()) {
+ return new String[]{"/decision/QPaaS"};
+ } else {
+ return new String[0];
+ }
+ }
+
+ @Override
+ public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) {
+ String code = req.getParameter("code");
+ if (StringUtils.isBlank(code)) {
+ CommonUtils.setError(res, "code is not null");
+ return;
+ }
+ String appid = req.getParameter("appid");
+ if (StringUtils.isBlank(appid)) {
+ CommonUtils.setError(res, "appid is not null");
+ return;
+ }
+ LogUtils.debug4plugin("get request code is {}", code);
+ LogUtils.debug4plugin("get request appid is {}", appid);
+ FeiYuSsoConfig instance = FeiYuSsoConfig.getInstance();
+ if (StringUtils.isBlank(instance.getAuthUser()) || StringUtils.isBlank(instance.getAuthPass()) || StringUtils.isBlank(instance.getInfoUrl())) {
+ CommonUtils.setError(res, "config is not null");
+ return;
+ }
+ Map header = new HashMap<>();
+ header.put("Authorization", getHeader(instance.getAuthUser(), instance.getAuthPass()));
+ String url = String.format("%s?code=%s&appid=%s", instance.getInfoUrl(), code, appid);
+ LogUtils.debug4plugin("header is {}",header);
+ String result = HttpUtil.sendGet(url, null, header);
+ LogUtils.debug4plugin("info url res is {} by url {}", result, url);
+ JSONObject object = new JSONObject(result);
+ if (!object.has("data") || !object.getJSONObject("data").has("adUserNo")) {
+ CommonUtils.setError(res, "the adUserNo not exist form result : " + result);
+ return;
+ }
+ CommonUtils.login(object.getJSONObject("data").getString("adUserNo"), req, res);
+ try {
+ String redirect = req.getParameter("redirect");
+ LogUtils.debug4plugin("redirect url {}", redirect);
+ if(StringUtils.isBlank(redirect)){
+ String root = TemplateUtils.render("${fineServletURL}");
+ res.sendRedirect(root + "/url/mobile");
+ }else {
+ res.sendRedirect(redirect);
+ }
+ } catch (Exception e) {
+ LogUtils.error(e.getMessage(), e);
+ }
+ }
+
+ private String getHeader(String user, String pass) {
+ String auth = user + ":" + pass;
+ byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(Charset.forName("US-ASCII")));
+ String authHeader = "Basic " + new String(encodedAuth);
+ return authHeader;
+ }
+
+}
diff --git a/src/main/java/com/fr/plugin/xxxx/fymh/sso/PluginConstants.java b/src/main/java/com/fr/plugin/xxxx/fymh/sso/PluginConstants.java
new file mode 100644
index 0000000..2302c9c
--- /dev/null
+++ b/src/main/java/com/fr/plugin/xxxx/fymh/sso/PluginConstants.java
@@ -0,0 +1,13 @@
+package com.fr.plugin.xxxx.fymh.sso;
+
+/**
+ * @author fr.open
+ * @since 2021/12/04
+ */
+public class PluginConstants {
+
+ public static final String PLUGIN_ID = "com.fr.plugin.xxxx.fymh.sso";
+
+ public static final String PLUGIN_NAME = "门户";
+
+}
diff --git a/src/main/java/com/fr/plugin/xxxx/fymh/sso/handler/HandleRequestHandlerBridge.java b/src/main/java/com/fr/plugin/xxxx/fymh/sso/handler/HandleRequestHandlerBridge.java
new file mode 100644
index 0000000..0463bb7
--- /dev/null
+++ b/src/main/java/com/fr/plugin/xxxx/fymh/sso/handler/HandleRequestHandlerBridge.java
@@ -0,0 +1,19 @@
+package com.fr.plugin.xxxx.fymh.sso.handler;
+
+import com.fr.decision.fun.HttpHandler;
+import com.fr.decision.fun.impl.AbstractHttpHandlerProvider;
+
+/**
+ * @Author fr.open
+ * @Date 2021/11/16
+ * @Description
+ **/
+public class HandleRequestHandlerBridge extends AbstractHttpHandlerProvider {
+
+ @Override
+ public HttpHandler[] registerHandlers() {
+ return new HttpHandler[]{
+ new SendHandler(),
+ };
+ }
+}
diff --git a/src/main/java/com/fr/plugin/xxxx/fymh/sso/handler/HandleRequestURLAliasBridge.java b/src/main/java/com/fr/plugin/xxxx/fymh/sso/handler/HandleRequestURLAliasBridge.java
new file mode 100644
index 0000000..6a5539b
--- /dev/null
+++ b/src/main/java/com/fr/plugin/xxxx/fymh/sso/handler/HandleRequestURLAliasBridge.java
@@ -0,0 +1,19 @@
+package com.fr.plugin.xxxx.fymh.sso.handler;
+
+import com.fr.decision.fun.impl.AbstractURLAliasProvider;
+import com.fr.decision.webservice.url.alias.URLAlias;
+import com.fr.decision.webservice.url.alias.URLAliasFactory;
+
+/**
+ * @Author fr.open
+ * @Date 2021/11/16
+ * @Description
+ **/
+public class HandleRequestURLAliasBridge extends AbstractURLAliasProvider {
+ @Override
+ public URLAlias[] registerAlias() {
+ return new URLAlias[]{
+ URLAliasFactory.createPluginAlias("/todo", "/todo", true),
+ };
+ }
+}
diff --git a/src/main/java/com/fr/plugin/xxxx/fymh/sso/handler/SendHandler.java b/src/main/java/com/fr/plugin/xxxx/fymh/sso/handler/SendHandler.java
new file mode 100644
index 0000000..66fedd4
--- /dev/null
+++ b/src/main/java/com/fr/plugin/xxxx/fymh/sso/handler/SendHandler.java
@@ -0,0 +1,112 @@
+package com.fr.plugin.xxxx.fymh.sso.handler;
+
+import com.fr.decision.fun.impl.BaseHttpHandler;
+import com.fr.ftp.util.Base64;
+import com.fr.json.JSONObject;
+import com.fr.log.FineLoggerFactory;
+import com.fr.plugin.xxxx.fymh.sso.FeiYuSsoConfig;
+import com.fr.plugin.xxxx.fymh.sso.HttpUtil;
+import com.fr.plugin.xxxx.fymh.sso.LogUtils;
+import com.fr.stable.StringUtils;
+import com.fr.third.springframework.web.bind.annotation.RequestMethod;
+import com.fr.web.utils.WebUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedReader;
+import java.io.PrintWriter;
+import java.nio.charset.Charset;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @Author fr.open
+ * @Date 2021/11/16
+ * @Description
+ **/
+public class SendHandler extends BaseHttpHandler {
+ @Override
+ public RequestMethod getMethod() {
+ return RequestMethod.POST;
+ }
+
+ @Override
+ public String getPath() {
+ return "/todo";
+ }
+
+ @Override
+ public boolean isPublic() {
+ return true;
+ }
+
+ @Override
+ public void handle(HttpServletRequest req, HttpServletResponse res) throws Exception {
+ String clientId = FeiYuSsoConfig.getInstance().getClientId();
+ String clientSecret = FeiYuSsoConfig.getInstance().getClientSecret();
+ String tokenUrl = FeiYuSsoConfig.getInstance().getTokenUrl();
+ String todoUrl = FeiYuSsoConfig.getInstance().getTodoUrl();
+ String user = FeiYuSsoConfig.getInstance().getAuthUser();
+ String pass = FeiYuSsoConfig.getInstance().getAuthPass();
+ if (StringUtils.isBlank(clientId) || StringUtils.isBlank(clientSecret)
+ || StringUtils.isBlank(tokenUrl) || StringUtils.isBlank(todoUrl)) {
+ setError(res, "config is not null");
+ return;
+ }
+ JSONObject object = getBody(req);
+ if (object == null) {
+ setError(res, "body is not null");
+ return;
+ }
+ Map header = new HashMap<>();
+ header.put("Authorization", getHeader(user, pass));
+ String tokenSend = String.format("%s?clientId=%s&clientSecret=%s", tokenUrl, clientId, clientSecret);
+ LogUtils.debug4plugin("header is {}",header);
+ String tokenRes = HttpUtil.sendGet(tokenSend, null, header);
+ LogUtils.debug4plugin("token res is {} by url {}", tokenRes, tokenSend);
+ if (StringUtils.isBlank(tokenRes)) {
+ setError(res, "token res is null");
+ return;
+ }
+ JSONObject tokenJSON = new JSONObject(tokenRes);
+ header.put("token", tokenJSON.getJSONObject("data").getString("token"));
+ String todoRes = HttpUtil.sendPost(todoUrl, header, object);
+ LogUtils.debug4plugin("todo url :{} res: {} by header:{}", todoUrl, todoRes, header);
+ PrintWriter writer = WebUtils.createPrintWriter(res);
+ writer.print(todoRes);
+ writer.flush();
+ writer.close();
+ }
+
+ public JSONObject getBody(HttpServletRequest req) {
+ try {
+ BufferedReader br = req.getReader();
+ String str = "";
+ String listString = "";
+ while ((str = br.readLine()) != null) {
+ listString += str;
+ }
+ JSONObject jsonObject = new JSONObject(listString);
+ return jsonObject;
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ return null;
+ }
+
+ private void setError(HttpServletResponse res, String mess) {
+ try {
+ WebUtils.printAsJSON(res, JSONObject.create().put("error", mess));
+ } catch (Exception ex) {
+ LogUtils.error(ex.getMessage(), ex);
+ }
+ }
+
+ private String getHeader(String user, String pass) {
+ String auth = user + ":" + pass;
+ byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(Charset.forName("US-ASCII")));
+ String authHeader = "Basic " + new String(encodedAuth);
+ return authHeader;
+ }
+
+}