17 changed files with 564 additions and 1 deletions
@ -1,3 +1,6 @@
|
||||
# open-JSD-7660 |
||||
|
||||
JSD-7660 开源任务材料 |
||||
JSD-7660 开源任务代码\ |
||||
免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ |
||||
仅作为开发者学习参考使用!禁止用于任何商业用途!\ |
||||
为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系hugh处理。 |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><plugin> |
||||
<id>com.fr.plugin.zwddlogin</id> |
||||
<name><![CDATA[政务钉钉单点]]></name> |
||||
<active>yes</active> |
||||
<version>1.0</version> |
||||
<env-version>10.0</env-version> |
||||
<jartime>2020-07-31</jartime> |
||||
<vendor>author</vendor> |
||||
<description><![CDATA[政务钉钉单点]]></description> |
||||
<change-notes><![CDATA[ |
||||
]]></change-notes> |
||||
<lifecycle-monitor class="com.fr.plugin.ZWLifeCycleMonitor"/> |
||||
<extra-decision> |
||||
<!-- 长连接 --> |
||||
<HttpHandlerProvider class="com.fr.plugin.DDHandlerProvider"/> |
||||
<!-- 短连接 --> |
||||
<URLAliasProvider class="com.fr.plugin.DDURLAliasBridge"/> |
||||
</extra-decision> |
||||
<function-recorder class="com.fr.plugin.ZWLifeCycleMonitor"/> |
||||
</plugin> |
@ -0,0 +1,21 @@
|
||||
package com.fr.plugin; |
||||
|
||||
import com.fr.decision.fun.HttpHandler; |
||||
import com.fr.decision.fun.impl.AbstractHttpHandlerProvider; |
||||
import com.fr.plugin.transform.ExecuteFunctionRecord; |
||||
import com.fr.plugin.transform.FunctionRecorder; |
||||
|
||||
@FunctionRecorder |
||||
/** |
||||
* url处理器需要在这里注册 |
||||
*/ |
||||
public class DDHandlerProvider extends AbstractHttpHandlerProvider { |
||||
@Override |
||||
@ExecuteFunctionRecord |
||||
public HttpHandler[] registerHandlers() { |
||||
return new HttpHandler[]{ |
||||
new LoginApi() |
||||
}; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,22 @@
|
||||
package com.fr.plugin; |
||||
|
||||
import com.fr.decision.fun.impl.AbstractURLAliasProvider; |
||||
import com.fr.decision.webservice.url.alias.URLAlias; |
||||
import com.fr.decision.webservice.url.alias.URLAliasFactory; |
||||
|
||||
/** |
||||
* 将长连接转换为短连接 |
||||
* 参考文档: |
||||
* https://wiki.fanruan.com/display/PD/com.fr.decision.fun.URLAliasProvider
|
||||
*/ |
||||
public class DDURLAliasBridge extends AbstractURLAliasProvider |
||||
{ |
||||
|
||||
@Override |
||||
public URLAlias[] registerAlias() { |
||||
//像这样配置之后再访问/api就可以通过http(s)://ip:port/webroot/decision/url/api。 进行访问
|
||||
return new URLAlias[]{ |
||||
URLAliasFactory.createPluginAlias("/ddxlogin", "/ddxlogin", true), |
||||
}; |
||||
} |
||||
} |
@ -0,0 +1,241 @@
|
||||
package com.fr.plugin; |
||||
|
||||
import com.fr.json.JSONObject; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.third.fasterxml.jackson.core.JsonGenerationException; |
||||
import com.fr.third.fasterxml.jackson.databind.JsonMappingException; |
||||
import com.fr.third.fasterxml.jackson.databind.ObjectMapper; |
||||
|
||||
import javax.net.ssl.*; |
||||
import java.io.*; |
||||
import java.net.HttpURLConnection; |
||||
import java.net.URL; |
||||
import java.net.URLConnection; |
||||
import java.security.cert.X509Certificate; |
||||
import java.util.Base64; |
||||
|
||||
public class HttpApi { |
||||
public HttpApi() { |
||||
} |
||||
|
||||
private static ObjectMapper objectMapper = new ObjectMapper(); |
||||
|
||||
public static String serialize(Object object) { |
||||
Writer write = new StringWriter(); |
||||
try { |
||||
objectMapper.writeValue(write, object); |
||||
} catch (JsonGenerationException e) { |
||||
} catch (JsonMappingException e) { |
||||
} catch (IOException e) { |
||||
} |
||||
return write.toString(); |
||||
} |
||||
|
||||
private final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() { |
||||
public boolean verify(String hostname, SSLSession session) { |
||||
return true; |
||||
} |
||||
}; |
||||
|
||||
private static void trustAllHosts() { |
||||
// Create a trust manager that does not validate certificate chains
|
||||
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { |
||||
public X509Certificate[] getAcceptedIssuers() { |
||||
return new X509Certificate[] {}; |
||||
} |
||||
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType) { |
||||
} |
||||
|
||||
public void checkServerTrusted(X509Certificate[] chain, String authType) { |
||||
} |
||||
} }; |
||||
// Install the all-trusting trust manager
|
||||
try { |
||||
SSLContext sc = SSLContext.getInstance("TLS"); |
||||
sc.init(null, trustAllCerts, new java.security.SecureRandom()); |
||||
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
|
||||
public static String sendPostByForm(String url, String params) { |
||||
PrintWriter out = null; |
||||
BufferedReader in = null; |
||||
String result = ""; |
||||
try { |
||||
trustAllHosts(); |
||||
URL realUrl = new URL(url); |
||||
URLConnection conn = realUrl.openConnection(); |
||||
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); |
||||
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 (realUrl.getProtocol().equalsIgnoreCase("https")) { |
||||
HttpsURLConnection https = (HttpsURLConnection) realUrl.openConnection(); |
||||
https.setHostnameVerifier(DO_NOT_VERIFY); |
||||
conn = https; |
||||
} else { |
||||
conn = realUrl.openConnection(); |
||||
} |
||||
conn.setDoOutput(true); |
||||
conn.setDoInput(true); |
||||
|
||||
out = new PrintWriter(conn.getOutputStream()); |
||||
|
||||
out.print(params); |
||||
|
||||
out.flush(); |
||||
|
||||
in = new BufferedReader(new InputStreamReader(conn.getInputStream())); |
||||
String line; |
||||
while ((line = in.readLine()) != null) { |
||||
result = result + line; |
||||
} |
||||
return result; |
||||
} catch (Exception e) { |
||||
printexception2Fr(e); |
||||
} finally { |
||||
try { |
||||
if (out != null) { |
||||
out.close(); |
||||
} |
||||
if (in != null) { |
||||
in.close(); |
||||
} |
||||
} catch (IOException ex) { |
||||
printexception2Fr(ex); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public static void printexception2Fr (Exception e) { |
||||
StringWriter writer = new StringWriter(); |
||||
e.printStackTrace(new PrintWriter(writer)); |
||||
String s = writer.toString(); |
||||
FineLoggerFactory.getLogger().error("错误:{}", s); |
||||
} |
||||
|
||||
|
||||
public static String sendJsonPost(String var0, JSONObject var1, String var2) { |
||||
PrintWriter var3 = null; |
||||
BufferedReader var4 = null; |
||||
HttpURLConnection var5 = null; |
||||
String var6 = ""; |
||||
|
||||
try { |
||||
URL var7 = new URL(var0); |
||||
var5 = (HttpURLConnection) var7.openConnection(); |
||||
var5.setRequestProperty("Content-Type", "application/json;charset=utf8"); |
||||
// var5.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=utf8");
|
||||
var5.setRequestProperty("accept", "*/*"); |
||||
var5.setRequestProperty("connection", "Keep-Alive"); |
||||
var5.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); |
||||
var5.setRequestProperty("Accept-Charset", var2); |
||||
var5.setRequestMethod("POST"); |
||||
var5.setDoOutput(true); |
||||
var5.setDoInput(true); |
||||
var3 = new PrintWriter(var5.getOutputStream()); |
||||
var3.print(var1.toString()); |
||||
var3.flush(); |
||||
|
||||
String var8; |
||||
for (var4 = new BufferedReader(new InputStreamReader(var5.getInputStream(), var2)); (var8 = var4.readLine()) != null; var6 = var6 + var8) { |
||||
; |
||||
} |
||||
} catch (Exception var17) { |
||||
var17.printStackTrace(); |
||||
} finally { |
||||
try { |
||||
if (var3 != null) { |
||||
var3.close(); |
||||
} |
||||
|
||||
if (var4 != null) { |
||||
var4.close(); |
||||
} |
||||
} catch (Exception var16) { |
||||
; |
||||
} |
||||
|
||||
var5.disconnect(); |
||||
} |
||||
|
||||
System.out.println(var6); |
||||
return var6; |
||||
} |
||||
/** |
||||
* 发送传统的表单提交 |
||||
* |
||||
* @param url |
||||
* @return |
||||
*/ |
||||
public static String sendGet(String url) { |
||||
StringBuilder sb = new StringBuilder(); |
||||
PrintWriter out = null; |
||||
BufferedReader in = null; |
||||
HttpURLConnection conn = null; |
||||
try { |
||||
URL realUrl = new URL(url); |
||||
// 打开和URL之间的连接
|
||||
conn = (HttpURLConnection) realUrl.openConnection(); |
||||
// 设置通用的请求属性
|
||||
conn.setRequestProperty("accept", "*/*"); |
||||
conn.setRequestMethod("GET"); |
||||
conn.setRequestProperty("connection", "Keep-Alive"); |
||||
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); |
||||
conn.setConnectTimeout(100); |
||||
conn.setReadTimeout(200); |
||||
// 发送POST请求必须设置如下两行
|
||||
conn.setDoOutput(true); |
||||
conn.setDoInput(true); |
||||
// 获取URLConnection对象对应的输出流
|
||||
out = new PrintWriter(conn.getOutputStream()); |
||||
|
||||
// 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); |
||||
} |
||||
} catch (Exception e) { |
||||
if (conn != null) { |
||||
InputStream errorStream = ( conn).getErrorStream(); |
||||
if (errorStream != null) { |
||||
in = new BufferedReader(new InputStreamReader(errorStream)); |
||||
String line; |
||||
sb = new StringBuilder(); |
||||
try { |
||||
while ((line = in.readLine()) != null) { |
||||
sb.append(line); |
||||
} |
||||
} catch (Exception ee) { |
||||
FineLoggerFactory.getLogger().error("", ee); |
||||
} |
||||
FineLoggerFactory.getLogger().error("错误响应:=======》" + sb); |
||||
} |
||||
} |
||||
FineLoggerFactory.getLogger().error("发送 GET 请求出现异常!", e); |
||||
} |
||||
// 使用finally块来关闭输出流、输入流
|
||||
finally { |
||||
try { |
||||
if (out != null) { |
||||
out.close(); |
||||
} |
||||
if (in != null) { |
||||
in.close(); |
||||
} |
||||
} catch (IOException ex) { |
||||
FineLoggerFactory.getLogger().error("", ex); |
||||
} |
||||
} |
||||
return sb.toString(); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,142 @@
|
||||
package com.fr.plugin; |
||||
|
||||
import com.alibaba.xxpt.gateway.shared.client.http.ExecutableClient; |
||||
import com.alibaba.xxpt.gateway.shared.client.http.GetClient; |
||||
import com.alibaba.xxpt.gateway.shared.client.http.PostClient; |
||||
import com.fr.decision.authority.data.User; |
||||
import com.fr.decision.fun.impl.BaseHttpHandler; |
||||
import com.fr.decision.webservice.v10.login.LoginService; |
||||
import com.fr.decision.webservice.v10.user.UserService; |
||||
import com.fr.json.JSONObject; |
||||
import com.fr.log.FineLoggerFactory; |
||||
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.PrintWriter; |
||||
import java.io.StringWriter; |
||||
import java.util.HashMap; |
||||
|
||||
public class LoginApi extends BaseHttpHandler { |
||||
@Override |
||||
public RequestMethod getMethod() { |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
public String getPath() { |
||||
return "/ddxlogin"; |
||||
} |
||||
|
||||
@Override |
||||
public boolean isPublic() { |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { |
||||
String code = WebUtils.getHTTPRequestParameter(httpServletRequest, "code"); |
||||
boolean isPc=false; |
||||
if (StringUtils.isBlank(code) ||"undefined".equals(code)) { |
||||
isPc=true; |
||||
code = WebUtils.getHTTPRequestParameter(httpServletRequest, "pcCode"); |
||||
} |
||||
if (StringUtils.isNotBlank(code)) { |
||||
//登录
|
||||
String userName = getUserName(code); |
||||
User user = UserService.getInstance().getUserByUserName(userName); |
||||
if (user != null) { |
||||
login(httpServletRequest, httpServletResponse, userName); |
||||
if(isPc){ |
||||
sendRedirect(httpServletResponse, "/webroot/decision"); |
||||
}else{ |
||||
sendRedirect(httpServletResponse, "/webroot/decision/url/mobile"); |
||||
} |
||||
return; |
||||
} |
||||
WebUtils.printAsString(httpServletResponse, "无法完成登录,获取的code:" + code); |
||||
} else { |
||||
WebUtils.writeOutTemplate("com/fr/plugin/ddlogin.html", httpServletResponse, new HashMap()); |
||||
} |
||||
} |
||||
|
||||
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 String getUserName(String code) { |
||||
try { |
||||
|
||||
|
||||
//第一步获取accessToken
|
||||
// String appkey = "j4GSz7YGcyU9N0ICg9I71juAzuu";
|
||||
// String appsecret = "ZaNfIVdC2ceURjpS0zDO286X0pxupsJV96N8erVD";
|
||||
ZWDDConfig instance = ZWDDConfig.getInstance(); |
||||
String appkey = instance.getAppKey(); |
||||
String appsecret = instance.getAppsecret(); |
||||
//第一步获取accessToken
|
||||
ExecutableClient executableClient = ExecutableClient.getInstance(); |
||||
executableClient.setAccessKey(appkey); |
||||
executableClient.setSecretKey(appsecret); |
||||
executableClient.setDomainName(instance.getDomainName()); |
||||
executableClient.setProtocal("https"); |
||||
executableClient.init(); |
||||
//executableClient要单例,并且使用前要初始化,只需要初始化一次
|
||||
|
||||
String api = "/gettoken.json"; |
||||
GetClient getClient = executableClient.newGetClient(api); |
||||
//设置参数
|
||||
getClient.addParameter("appkey", appkey); |
||||
getClient.addParameter("appsecret", appsecret); |
||||
//调用API
|
||||
String sendGet = getClient.get(); |
||||
// String accessUrl = "https://openplatform-pro.ding.zj.gov.cn/gettoken.json?appkey=" + appkey + "&appsecret=" + appsecret;
|
||||
// String sendGet = HttpApi.sendGet(accessUrl);
|
||||
FineLoggerFactory.getLogger().info("登录获取的accessToken:{} ", sendGet); |
||||
JSONObject entries = new JSONObject(sendGet); |
||||
boolean success = entries.getBoolean("success"); |
||||
if (success) { |
||||
String accessToken = entries.getJSONObject("content").getJSONObject("data").getString("accessToken"); |
||||
api = "/rpc/oauth2/dingtalk_app_user.json"; |
||||
PostClient postClient = executableClient.newPostClient(api); |
||||
//设置参数
|
||||
postClient.addParameter("access_token", accessToken); |
||||
postClient.addParameter("auth_code", code); |
||||
String body = postClient.post(); |
||||
FineLoggerFactory.getLogger().info("获取用户信息请求响应 {} ", body); |
||||
JSONObject jsonObject = new JSONObject(body); |
||||
if (jsonObject.getBoolean("success")) { |
||||
return jsonObject.getJSONObject("content").getJSONObject("data").getString("account"); |
||||
} |
||||
FineLoggerFactory.getLogger().info("登录获取用户信息失败"); |
||||
} else { |
||||
FineLoggerFactory.getLogger().info("登录获取的accessToken 失败 "); |
||||
} |
||||
} catch (Exception e) { |
||||
printException2FrLog(e); |
||||
} |
||||
return ""; |
||||
} |
||||
|
||||
public static void printException2FrLog(Throwable e) { |
||||
StringWriter writer = new StringWriter(); |
||||
e.printStackTrace(new PrintWriter(writer)); |
||||
String s = writer.toString(); |
||||
FineLoggerFactory.getLogger().error("错误:{}", s); |
||||
} |
||||
} |
@ -0,0 +1,57 @@
|
||||
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 ZWDDConfig extends DefaultConfiguration { |
||||
|
||||
private static volatile ZWDDConfig config = null; |
||||
|
||||
public static ZWDDConfig getInstance() { |
||||
if (config == null) { |
||||
config = ConfigContext.getConfigInstance(ZWDDConfig.class); |
||||
} |
||||
return config; |
||||
} |
||||
@Identifier(value = "appKey", name = "钉钉appkey", description = "",status = Status.SHOW) |
||||
private Conf<String> appKey = Holders.simple(""); |
||||
@Identifier(value = "secret", name = "钉钉appsecret", description = "",status = Status.SHOW) |
||||
private Conf<String> appsecret = Holders.simple(""); |
||||
@Identifier(value = "domainName", name = "钉钉域名", description = "",status = Status.SHOW) |
||||
private Conf<String> domainName = Holders.simple("openplatform.dg-work.cn"); |
||||
|
||||
public String getAppKey() { |
||||
return appKey.get(); |
||||
} |
||||
|
||||
public void setAppKey(String appKey) { |
||||
this.appKey .set(appKey); |
||||
} |
||||
|
||||
public String getAppsecret() { |
||||
return appsecret.get(); |
||||
} |
||||
|
||||
public void setAppsecret(String appsecret) { |
||||
this.appsecret .set(appsecret); |
||||
} |
||||
|
||||
public String getDomainName() { |
||||
return domainName.get(); |
||||
} |
||||
|
||||
public void setDomainName(String domainName) { |
||||
this.domainName .set(domainName); |
||||
} |
||||
|
||||
@Override |
||||
public Object clone() throws CloneNotSupportedException { |
||||
ZWDDConfig clone = (ZWDDConfig) super.clone(); |
||||
clone.appKey = (Conf<String>) this.appKey.clone(); |
||||
clone.appsecret = (Conf<String>) this.appKey.clone(); |
||||
clone.domainName = (Conf<String>) this.appKey.clone(); |
||||
return clone; |
||||
} |
||||
} |
@ -0,0 +1,20 @@
|
||||
package com.fr.plugin; |
||||
|
||||
import com.fr.plugin.context.PluginContext; |
||||
import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor; |
||||
import com.fr.plugin.transform.ExecuteFunctionRecord; |
||||
import com.fr.plugin.transform.FunctionRecorder; |
||||
|
||||
@FunctionRecorder |
||||
public class ZWLifeCycleMonitor extends AbstractPluginLifecycleMonitor { |
||||
|
||||
@Override |
||||
@ExecuteFunctionRecord |
||||
public void afterRun(PluginContext pluginContext) { |
||||
ZWDDConfig.getInstance(); |
||||
} |
||||
|
||||
@Override |
||||
public void beforeStop(PluginContext pluginContext) { |
||||
} |
||||
} |
@ -0,0 +1,37 @@
|
||||
<!doctype html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8"> |
||||
<meta name="viewport" |
||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> |
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge"> |
||||
<title>login</title> |
||||
<script src="https://g.alicdn.com/gdt/jsapi/1.9.6/index.js"></script> |
||||
</head> |
||||
<body> |
||||
<h1 id="errorinfo"></h1> |
||||
<h3 id="authinfo">请稍等正在获取钉钉授权3</h3> |
||||
<p>如果超过1分钟未能自动跳转请刷新该页面。</p> |
||||
<script> |
||||
try { |
||||
dd.ready(()=>{ |
||||
dd.getAuthCode({}).then((result) =>{ |
||||
if (result) { |
||||
document.getElementById("authinfo").innerHTML="授权码:"+JSON.stringify(result, null, null) |
||||
setTimeout(function (){ |
||||
document.getElementById("authinfo").innerHTML="调整去"+window.location.href+"?code="+result.code+"&pcCode="+result.auth_code |
||||
window.location.href=window.location.href+"?code="+result.code+"&pcCode="+result.auth_code; |
||||
},500) |
||||
// code: 'hYLK98jkf0m' //string authCode |
||||
} |
||||
}).catch((err)=>{ |
||||
document.getElementById("errorinfo").innerHTML="获取钉钉授权失败,请刷新页面"+err |
||||
}) |
||||
}); |
||||
}catch (e){ |
||||
document.getElementById("errorinfo").innerHTML="获取钉钉授权失败,请刷新页面" |
||||
} |
||||
|
||||
</script> |
||||
</body> |
||||
</html> |
Loading…
Reference in new issue