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