diff --git a/README.md b/README.md
index 4536257..82de28b 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,6 @@
# open-JSD-8075
-JSD-8075 自定义token单点
\ No newline at end of file
+JSD-8075 自定义token单点\
+免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\
+仅作为开发者学习参考使用!禁止用于任何商业用途!\
+为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系hugh处理。
\ No newline at end of file
diff --git a/plugin.xml b/plugin.xml
new file mode 100644
index 0000000..5ec3880
--- /dev/null
+++ b/plugin.xml
@@ -0,0 +1,19 @@
+
+ com.fr.plugin.nd.login
+
+ yes
+ 1.0.2
+ 10.0
+ 2020-07-31
+ fr.open
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/HttpUtils.java b/src/main/java/com/fr/plugin/HttpUtils.java
new file mode 100644
index 0000000..8fba4ab
--- /dev/null
+++ b/src/main/java/com/fr/plugin/HttpUtils.java
@@ -0,0 +1,265 @@
+package com.fr.plugin;
+
+import com.fr.base.FRContext;
+import com.fr.base.ServerConfig;
+import com.fr.base.TemplateUtils;
+import com.fr.log.FineLoggerFactory;
+import com.fr.stable.StringUtils;
+import com.fr.third.org.apache.commons.io.IOUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * http请求工具类
+ *
+ * @author fr.open
+ */
+public class HttpUtils {
+
+ /**
+ * 返回当前系统的回调地址
+ *
+ * @return
+ */
+ public static String getCallBackUrl(HttpServletRequest req) {
+ StringBuilder url = new StringBuilder();
+ try {
+ url.append(req.getScheme());
+ url.append("://");
+ url.append(req.getServerName());
+ if (req.getServerPort() != 80) {
+ url.append(":");
+ url.append(req.getServerPort());
+ }
+ url.append(TemplateUtils.render("${fineServletURL}"));
+ url.append("/url/authorizationCallback");
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ return url.toString();
+ }
+
+ /**
+ * 返回当前系统的根路径
+ *
+ * @return
+ */
+ public static String getDefaultUrl(HttpServletRequest req) {
+ StringBuilder url = new StringBuilder();
+ try {
+ url.append(req.getScheme());
+ url.append("://");
+ url.append(req.getServerName());
+ if (req.getServerPort() != 80) {
+ url.append(":");
+ url.append(req.getServerPort());
+ }
+ url.append(TemplateUtils.render("${fineServletURL}"));
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ return url.toString();
+ }
+
+ /**
+ * get请求方式
+ *
+ * @param path
+ * @return
+ */
+ public static String httpGet(String path,String token) {
+ StringBuffer buffer = new StringBuffer();
+ try {
+ URL url = new URL(path);
+ //打开和url之间的连接
+ HttpURLConnection conn = (HttpURLConnection) url.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)");
+ conn.setRequestProperty("Accept-Charset", "UTF-8");
+ conn.setRequestProperty("token", token);
+ conn.setRequestMethod("GET");
+ conn.connect();
+ //构造一个字符流缓存
+ BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
+ String line;
+ while ((line = reader.readLine()) != null) {
+ buffer.append(new String(line.getBytes(), "UTF-8"));
+ }
+ //关闭流
+ reader.close();
+ conn.disconnect();
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ return buffer.toString();
+ }
+
+ /**
+ * post请求方法
+ *
+ * @param path
+ * @param param
+ */
+ public static String httpPost(String path, Map param) {
+ String var3 = getParam(param, ServerConfig.getInstance().getServerCharset());
+ PrintWriter var4 = null;
+ BufferedReader var5 = null;
+ String var6 = "";
+ HttpURLConnection var8=null;
+ try {
+ URL var7 = new URL(path);
+ var8 = (HttpURLConnection) var7.openConnection();
+ var8.setRequestProperty("accept", "*/*");
+ var8.setRequestProperty("connection", "Keep-Alive");
+ var8.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
+ var8.setRequestProperty("Accept-Charset", "UTF-8");
+ var8.setRequestMethod("POST");
+ var8.setDoOutput(true);
+ var8.setDoInput(true);
+ var4 = new PrintWriter(var8.getOutputStream());
+ var4.print(var3);
+ var4.flush();
+
+ String var9;
+ for (var5 = new BufferedReader(new InputStreamReader(var8.getInputStream(), "UTF-8")); (var9 = var5.readLine()) != null; var6 = var6 + var9) {
+ ;
+ }
+ } catch (Exception var18) {
+ if (var8 != null) {
+ InputStream errorStream = var8.getErrorStream();
+ if (errorStream != null) {
+ try {
+ String s = IOUtils.toString(errorStream, StandardCharsets.UTF_8);
+ FineLoggerFactory.getLogger().error("resp logger :{}", s);
+ return s;
+ } catch (IOException ioException) {
+ ioException.printStackTrace();
+ }
+ }
+ }
+ } finally {
+ try {
+ if (var4 != null) {
+ var4.close();
+ }
+
+ if (var5 != null) {
+ var5.close();
+ }
+ } catch (Exception var17) {
+ ;
+ }
+
+ }
+
+ return var6;
+ }
+
+ /**
+ * 发送json 模式的请求
+ *
+ * @param url
+ * @param param
+ * @return
+ */
+ public static String sendJsonPost(String url, String param) {
+ FRContext.getLogger().info("请将后面的内容发送给开发者:" + new String(Base64.getUrlEncoder().encode(param.getBytes())));
+ StringBuilder sb = new StringBuilder();
+ PrintWriter out = null;
+ BufferedReader in = null;
+ HttpURLConnection conn = null;
+ try {
+ URL realUrl = new URL(url);
+ // 打开和URL之间的连接
+ conn = (HttpURLConnection) realUrl.openConnection();
+ FineLoggerFactory.getLogger().info("打开链接:" + conn.toString());
+ // 设置通用的请求属性
+ conn.setRequestProperty("accept", "*/*");
+ conn.setRequestMethod("POST");
+ conn.setRequestProperty("connection", "Keep-Alive");
+ conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
+ conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
+ // 发送POST请求必须设置如下两行
+ conn.setDoOutput(true);
+ conn.setDoInput(true);
+ // 获取URLConnection对象对应的输出流,设置utf-8编码
+ out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8));
+ // 发送请求参数
+ if (StringUtils.isNotBlank(param)) {
+ out.print(param);
+ }
+ FineLoggerFactory.getLogger().info("发送参数[{}]:" + out.toString(), param);
+ // flush输出流的缓冲
+ out.flush();
+ // 定义BufferedReader输入流来读取URL的响应
+ in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
+ String line;
+ sb = new StringBuilder();
+ while ((line = in.readLine()) != null) {
+ sb.append(line);
+ }
+ FineLoggerFactory.getLogger().info("接口返回值:" + sb.toString());
+ } catch (Exception e) {
+ if (conn != null) {
+ InputStream errorStream = ( conn).getErrorStream();
+ in = new BufferedReader(new InputStreamReader(errorStream));
+ sb = new StringBuilder();
+ String line;
+ try {
+ while ((line = in.readLine()) != null) {
+ sb.append(line);
+ }
+ } catch (Exception ee) {
+
+ }
+ System.out.println("错误响应:=======>>" + sb);
+ }
+ System.out.println("发送 POST 请求出现异常!" + e);
+ e.printStackTrace();
+ }
+ // 使用finally块来关闭输出流、输入流
+ finally {
+ try {
+ if (null != in) {
+ in.close();
+ }
+ if (out != null) {
+ out.close();
+ }
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+ return sb.toString();
+ }
+
+ private static String getParam(Map var0, String enc) {
+ String var1 = "";
+ Set var2 = var0.keySet();
+ Iterator var3 = var2.iterator();
+
+ while (var3.hasNext()) {
+ String var4 = (String) var3.next();
+ String var5 = var0.get(var4) + "";
+
+ try {
+ var1 = var1 + (var1.length() == 0 ? "" : "&") + URLEncoder.encode(var4, enc) + "=" + URLEncoder.encode(var5, enc);
+ } catch (Exception var7) {
+ ;
+ }
+ }
+
+ return var1;
+ }
+
+}
diff --git a/src/main/java/com/fr/plugin/NDConfig.java b/src/main/java/com/fr/plugin/NDConfig.java
new file mode 100644
index 0000000..e18d494
--- /dev/null
+++ b/src/main/java/com/fr/plugin/NDConfig.java
@@ -0,0 +1,70 @@
+package com.fr.plugin;
+
+import com.fr.config.*;
+import com.fr.config.holder.Conf;
+import com.fr.config.holder.factory.Holders;
+
+@Visualization(category = "单点配置")
+public class NDConfig extends DefaultConfiguration {
+
+ private static volatile NDConfig config = null;
+
+ public static NDConfig getInstance() {
+ if (config == null) {
+ config = ConfigContext.getConfigInstance(NDConfig.class);
+ }
+ return config;
+ }
+
+ @Identifier(value = "valAddr", name = "接口地址", description = "接口地址", status = Status.SHOW)
+ private Conf valAddr = Holders.simple("");
+ @Identifier(value = "frUrl", name = "报表地址", description = "报表地址", status = Status.HIDE)
+ private Conf frUrl = Holders.simple("");
+ @Identifier(value = "appId", name = "sysId", description = "sysId", status = Status.SHOW)
+ private Conf appId = Holders.simple("");
+ @Identifier(value = "clientSecret", name = "clientSecret", description = "clientSecret", status = Status.HIDE)
+ private Conf clientSecret = Holders.simple("");
+
+ public String getFrUrl() {
+ return frUrl.get();
+ }
+
+ public void setFrUrl(String frUrl) {
+ this.frUrl.set(frUrl);
+ }
+
+ public String getAppId() {
+ return appId.get();
+ }
+
+ public void setAppId(String appId) {
+ this.appId.set(appId);
+ }
+
+ public String getClientSecret() {
+ return clientSecret.get();
+ }
+
+ public void setClientSecret(String clientSecret) {
+ this.clientSecret.set(clientSecret);
+ }
+
+ public String getValAddr() {
+ return valAddr.get();
+ }
+
+ public void setValAddr(String valAddr) {
+ this.valAddr.set(valAddr);
+ }
+
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ NDConfig cloned = (NDConfig) super.clone();
+ cloned.valAddr = (Conf) valAddr.clone();
+ cloned.appId = (Conf) appId.clone();
+ cloned.clientSecret = (Conf) clientSecret.clone();
+ cloned.frUrl = (Conf) frUrl.clone();
+ return cloned;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/NDXloginFilter.java b/src/main/java/com/fr/plugin/NDXloginFilter.java
new file mode 100644
index 0000000..d2f63a1
--- /dev/null
+++ b/src/main/java/com/fr/plugin/NDXloginFilter.java
@@ -0,0 +1,107 @@
+package com.fr.plugin;
+
+import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
+import com.fr.decision.webservice.v10.login.LoginService;
+import com.fr.log.FineLoggerFactory;
+import com.fr.plugin.transform.ExecuteFunctionRecord;
+import com.fr.plugin.transform.FunctionRecorder;
+import com.fr.stable.StringUtils;
+import com.fr.web.utils.WebUtils;
+import org.json.JSONObject;
+
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+import java.util.Map;
+
+@FunctionRecorder(localeKey = "ffe")
+public class NDXloginFilter extends AbstractGlobalRequestFilterProvider {
+ @Override
+ public String filterName() {
+ return "ndLoginxxxxxxx";
+ }
+
+ @Override
+ public String[] urlPatterns() {
+ return new String[]{
+ "/dee"
+ };
+ }
+
+ @Override
+ public void init(FilterConfig filterConfig) {
+ NDConfig.getInstance();
+ FineLoggerFactory.getLogger().info("登录插件初始化");
+ super.init(filterConfig);
+ }
+
+ @Override
+ @ExecuteFunctionRecord
+ public void doFilter(HttpServletRequest request, HttpServletResponse httpServletResponse, FilterChain filterChain) {
+ try {
+ String token = WebUtils.getHTTPRequestParameter(request, "token");
+ if (StringUtils.isNotBlank(token)) {
+ NDConfig ndConfig = NDConfig.getInstance();
+ String url = String.format("%s?Token=%s&Sys=%s",ndConfig.getValAddr(),token,ndConfig.getAppId());
+ Map params = new HashMap<>();
+ params.put("Token", token);
+ params.put("Sys", ndConfig.getAppId());
+ String json = HttpUtils.httpPost(url, params);
+ if (StringUtils.isNotBlank(json)) {
+ JSONObject jsonObject = new JSONObject(json);
+ String result = jsonObject.getString("result");
+ if (StringUtils.equals(result,"True")) {
+ String empNo = jsonObject.getString("empNo");
+ login(request, httpServletResponse, empNo);
+ }
+ }
+ FineLoggerFactory.getLogger().info("登录认证,收到token :", token);
+ }
+ filterChain.doFilter(request, httpServletResponse);
+ } catch (IOException | ServletException e) {
+ printException2FrLog(e);
+ } catch (Exception e) {
+ printException2FrLog(e);
+ }
+ }
+
+ public static void printException2FrLog(Throwable e) {
+ StringWriter writer = new StringWriter();
+ e.printStackTrace(new PrintWriter(writer));
+ String s = writer.toString();
+ FineLoggerFactory.getLogger().error("错误:{}", s);
+ }
+
+ private void sendRedirect(HttpServletResponse res, String url) {
+ res.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
+ res.setHeader("Location", url);
+ }
+
+
+ private void login(HttpServletRequest req, HttpServletResponse res, String username) {
+ String token = null;
+ try {
+ token = LoginService.getInstance().login(req, res, username);
+ req.setAttribute("fine_auth_token", token);
+ FineLoggerFactory.getLogger().error("login success");
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ FineLoggerFactory.getLogger().error("login failed");
+ }
+ }
+
+ private boolean isLogin(HttpServletRequest req) {
+ return LoginService.getInstance().isLogged(req);
+ }
+
+
+}
diff --git a/src/main/java/com/fr/plugin/XGlobalRequestFilterPlaceHolder.java b/src/main/java/com/fr/plugin/XGlobalRequestFilterPlaceHolder.java
new file mode 100644
index 0000000..b2f356d
--- /dev/null
+++ b/src/main/java/com/fr/plugin/XGlobalRequestFilterPlaceHolder.java
@@ -0,0 +1,110 @@
+package com.fr.plugin;
+
+import com.fr.decision.ExtraDecisionClassManager;
+import com.fr.decision.fun.GlobalRequestFilterProvider;
+import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
+import com.fr.event.Event;
+import com.fr.event.EventDispatcher;
+import com.fr.event.Listener;
+import com.fr.log.FineLoggerFactory;
+import com.fr.plugin.context.PluginContext;
+import com.fr.plugin.injectable.PluginModule;
+import com.fr.plugin.observer.PluginEventType;
+import com.fr.stable.StringUtils;
+
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Set;
+
+/**
+ * @author fr.open
+ */
+public class XGlobalRequestFilterPlaceHolder extends AbstractGlobalRequestFilterProvider {
+ private static final String CURRENT_PLUGIN_ID = "com.fr.plugin.nd.login";//需要求个这两个配置
+ private static final String CURRENT_FILTER_NAME = "ndLoginxxxxxxx";
+ private static GlobalRequestFilterProvider PLACE_HOLDER_IMPL_FILTER;
+
+ @Override
+ public void init(FilterConfig filterConfig) {
+ Set providers = ExtraDecisionClassManager.getInstance().getArray(GlobalRequestFilterProvider.MARK_STRING);
+ if (providers != null) {
+ for (GlobalRequestFilterProvider provider : providers) {
+ String filterName = provider.filterName();
+ if (StringUtils.isNotEmpty(filterName) && CURRENT_FILTER_NAME.equals(filterName)) {
+ PLACE_HOLDER_IMPL_FILTER = provider;
+ break;
+ }
+ }
+ }
+
+ com.fr.stable.Filter filter = new com.fr.stable.Filter() {
+ @Override
+ public boolean accept(PluginContext context) {
+ String pluginId = context.getID();
+ return context.contain(PluginModule.ExtraDecision, GlobalRequestFilterProvider.MARK_STRING) && CURRENT_PLUGIN_ID.equals(pluginId);
+ }
+ };
+ Listener listener = new Listener() {
+ @Override
+ public void on(Event event, PluginContext context) {
+ Set providers = context.getRuntime().get(PluginModule.ExtraDecision, GlobalRequestFilterProvider.MARK_STRING);
+ if (providers != null) {
+ for (GlobalRequestFilterProvider provider : providers) {
+ String filterName = provider.filterName();
+ if (StringUtils.isNotEmpty(filterName) && CURRENT_FILTER_NAME.equals(filterName)) {
+ PLACE_HOLDER_IMPL_FILTER = provider;
+ break;
+ }
+ }
+ }
+ }
+ };
+ EventDispatcher.listen(PluginEventType.AfterRun, listener, filter);
+ EventDispatcher.listen(PluginEventType.AfterActive, listener, filter);
+ EventDispatcher.listen(PluginEventType.BeforeStop, new Listener() {
+ @Override
+ public void on(Event event, PluginContext context) {
+ PLACE_HOLDER_IMPL_FILTER = null;
+ }
+ }, filter);
+ }
+
+ @Override
+ public String filterName() {
+ return "GlobalRequestFilterPlaceHolder";
+ }
+
+ @Override
+ public String[] urlPatterns() {
+ return new String[]{
+ "/*"
+ };
+ }
+
+ @Override
+ public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) {
+ try {
+ process(request, response, filterChain);
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e, e.getMessage());
+ try {
+ filterChain.doFilter(request, response);
+ } catch (Exception ex) {
+ FineLoggerFactory.getLogger().error(ex, ex.getMessage());
+ }
+ }
+ }
+
+ public void process(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws Exception {
+ if (PLACE_HOLDER_IMPL_FILTER == null) {
+ if(FineLoggerFactory.getLogger().isDebugEnabled()) {
+ FineLoggerFactory.getLogger().debug("[GlobalRequestFilterPlaceHolder] placeHolderImplFilter 为 null");
+ }
+ filterChain.doFilter(request, response);
+ } else {
+ PLACE_HOLDER_IMPL_FILTER.doFilter(request, response, filterChain);
+ }
+ }
+}
diff --git a/src/main/resources/com/fr/plugin/demo.properties b/src/main/resources/com/fr/plugin/demo.properties
new file mode 100644
index 0000000..9bc5f29
--- /dev/null
+++ b/src/main/resources/com/fr/plugin/demo.properties
@@ -0,0 +1 @@
+Plugin-Test_Function_Abs=Test ABS
\ No newline at end of file
diff --git a/src/main/resources/com/fr/plugin/demo_zh_CN.properties b/src/main/resources/com/fr/plugin/demo_zh_CN.properties
new file mode 100644
index 0000000..aa910e8
--- /dev/null
+++ b/src/main/resources/com/fr/plugin/demo_zh_CN.properties
@@ -0,0 +1 @@
+Plugin-Test_Function_Abs=测试ABS函数
\ No newline at end of file
diff --git a/技术文档.docx b/技术文档.docx
new file mode 100644
index 0000000..05be856
Binary files /dev/null and b/技术文档.docx differ