From 13934b8a365ec20aea712c26c5bb43d7c462babe Mon Sep 17 00:00:00 2001 From: "zhangteng@dtelec.com" <84920599> Date: Mon, 11 Mar 2019 10:09:42 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B4=E5=90=88=E9=92=89=E9=92=89=E7=9A=84?= =?UTF-8?q?=E7=AC=AC=E4=B8=89=E6=96=B9=E7=99=BB=E5=BD=95=EF=BC=8C=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E7=99=BB=E5=BD=95=E7=95=8C=E9=9D=A2=E4=B8=8B=E6=96=B9?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BD=BF=E7=94=A8=E9=92=89=E9=92=89=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E7=9A=84=E5=85=A5=E5=8F=A3=EF=BC=8C=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E9=92=89=E9=92=89=E7=9A=84=E9=89=B4=E6=9D=83=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=EF=BC=8C=E5=90=8E=E5=8F=B0=E9=85=8D=E7=BD=AE=E7=95=8C=E9=9D=A2?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=98=AF=E5=90=A6=E5=90=AF=E7=94=A8=E9=92=89?= =?UTF-8?q?=E9=92=89=E7=9A=84=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jpress/commons/oauth2/OauthConnector.java | 11 +- .../oauth2/connector/DingdingConnector.java | 105 ++++++++++++++++++ .../java/io/jpress/model/base/BaseUser.java | 4 + .../java/io/jpress/service/UserService.java | 2 + .../service/provider/UserServiceProvider.java | 5 + .../io/jpress/web/front/OauthController.java | 21 +++- .../WEB-INF/views/admin/setting/reg.html | 33 ++++++ .../WEB-INF/views/ucenter/user_login.html | 6 +- .../main/resources/static/commons/img/dd.png | Bin 0 -> 1185 bytes 9 files changed, 183 insertions(+), 4 deletions(-) create mode 100644 jpress-commons/src/main/java/io/jpress/commons/oauth2/connector/DingdingConnector.java create mode 100644 jpress-web/src/main/resources/static/commons/img/dd.png diff --git a/jpress-commons/src/main/java/io/jpress/commons/oauth2/OauthConnector.java b/jpress-commons/src/main/java/io/jpress/commons/oauth2/OauthConnector.java index ee3fa3a90..b0b1350be 100644 --- a/jpress-commons/src/main/java/io/jpress/commons/oauth2/OauthConnector.java +++ b/jpress-commons/src/main/java/io/jpress/commons/oauth2/OauthConnector.java @@ -85,7 +85,16 @@ public abstract class OauthConnector { try { return JbootHttpKit.httpPost(url, params); } catch (Exception e) { - LOGGER.error("httpGet error", e); + LOGGER.error("httpPost error", e); + } + return null; + } + + protected String httpPost(String url, Map paras, Map headers, String postData) { + try { + return JbootHttpKit.httpPost(url, paras, headers, postData); + } catch (Exception e) { + LOGGER.error("httpPost error", e); } return null; } diff --git a/jpress-commons/src/main/java/io/jpress/commons/oauth2/connector/DingdingConnector.java b/jpress-commons/src/main/java/io/jpress/commons/oauth2/connector/DingdingConnector.java new file mode 100644 index 000000000..31df57abd --- /dev/null +++ b/jpress-commons/src/main/java/io/jpress/commons/oauth2/connector/DingdingConnector.java @@ -0,0 +1,105 @@ +package io.jpress.commons.oauth2.connector; + +import com.alibaba.fastjson.JSONObject; +import io.jboot.core.http.JbootHttpKit; +import io.jboot.utils.StrUtils; +import io.jpress.commons.oauth2.OauthConnector; +import io.jpress.commons.oauth2.OauthUser; + +import java.util.HashMap; +import java.util.Map; + +public class DingdingConnector extends OauthConnector { + public DingdingConnector(String name, String appkey, String appSecret) { + super(name, appkey, appSecret); + } + + @Override + public String createAuthorizeUrl(String state) { + //https://oapi.dingtalk.com/connect/qrconnect?appid=APPID&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=REDIRECT_URI + StringBuilder sb = new StringBuilder("https://oapi.dingtalk.com/connect/qrconnect?"); + sb.append("appid=" + getClientId()); + sb.append("&response_type=code"); + sb.append("&scope=snsapi_login"); + sb.append("&state=" + state); + sb.append("&redirect_uri=" + getRedirectUri()); //"http://b5ad905b.ngrok.io");http://127.0.0.1:8080/callback + + return sb.toString(); + } + + protected JSONObject getAccessToken() { + + //https://oapi.dingtalk.com/sns/gettoken?appid=APPID&appsecret=APPSECRET + StringBuilder urlBuilder = new StringBuilder("https://oapi.dingtalk.com/sns/gettoken?"); + urlBuilder.append("appid=" + getClientId()); + urlBuilder.append("&appsecret=" + getClientSecret()); + + String url = urlBuilder.toString(); + + String httpString = httpGet(url); + + return JSONObject.parseObject(httpString); + } + + protected JSONObject getPersistentCode(String code,String access_token) { + Map headers = new HashMap<>(); + headers.put("Content-Type","application/json"); + + StringBuilder paramsBuilder = new StringBuilder("{\"tmp_auth_code\":\""+code+"\"}"); + String postData = paramsBuilder.toString(); + //获取用户授权的持久授权码 + String url = "https://oapi.dingtalk.com/sns/get_persistent_code?access_token=" + access_token; + String httpString = httpPost(url, null, headers, postData); + if (StrUtils.isBlank(httpString)) { + return null; + } + return JSONObject.parseObject(httpString); + } + + protected JSONObject getSnsToken(String accessToken,String persistentCode, String openId){ + Map headers = new HashMap<>(); + headers.put("Content-Type","application/json"); + + StringBuilder paramsBuilder = new StringBuilder("{\"persistent_code\":\""+persistentCode+"\",\"openid\":\""+openId+"\"}"); + String postData = paramsBuilder.toString(); + + String url = "https://oapi.dingtalk.com/sns/get_sns_token?access_token=" + accessToken; + String httpString = httpPost(url, null, headers, postData); + if (StrUtils.isBlank(httpString)) { + return null; + } + return JSONObject.parseObject(httpString); + } + @Override + protected OauthUser getOauthUser(String code) { + JSONObject tokenJson = getAccessToken(); + String accessToken = tokenJson.getString("access_token"); + + JSONObject persistentCodes = getPersistentCode(code,accessToken); + String persistentCode = persistentCodes.getString("persistent_code"); + String openId = persistentCodes.getString("openid"); + + JSONObject snsTokens = getSnsToken(accessToken,persistentCode,openId); + String snsToken = snsTokens.getString("sns_token"); + + String url = "https://oapi.dingtalk.com/sns/getuserinfo?sns_token=" + snsToken ; + String httpString = httpGet(url); + + if (StrUtils.isBlank(httpString)) { + return null; + } + + JSONObject json = JSONObject.parseObject(httpString); + JSONObject userInfo = json.getJSONObject("user_info"); + + OauthUser user = new OauthUser(); + //nick、unionid、dingId、openid + user.setAvatar(userInfo.getString("unionid")); + user.setNickname(userInfo.getString("nick")); + user.setOpenId(userInfo.getString( "openid")); + user.setSource(getName()); + + return user; + } +} + diff --git a/jpress-model/src/main/java/io/jpress/model/base/BaseUser.java b/jpress-model/src/main/java/io/jpress/model/base/BaseUser.java index e17affd93..0a1599a10 100644 --- a/jpress-model/src/main/java/io/jpress/model/base/BaseUser.java +++ b/jpress-model/src/main/java/io/jpress/model/base/BaseUser.java @@ -76,6 +76,10 @@ public abstract class BaseUser> extends JbootModel impl public void setWxOpenid(java.lang.String wxOpenid) { set("wx_openid", wxOpenid); } + + public void setDdOpenid(java.lang.String ddOpenid) { + set("dd_openid", ddOpenid); + } public java.lang.String getWxOpenid() { return getStr("wx_openid"); diff --git a/jpress-service-api/src/main/java/io/jpress/service/UserService.java b/jpress-service-api/src/main/java/io/jpress/service/UserService.java index d53a42d86..496e96cc1 100644 --- a/jpress-service-api/src/main/java/io/jpress/service/UserService.java +++ b/jpress-service-api/src/main/java/io/jpress/service/UserService.java @@ -136,6 +136,8 @@ public interface UserService { public User findFistByWxOpenid(String openId); + public User findFistByDdOpenid(String openId); + public User findFistByQQOpenid(String openId); public Long saveAndGetId(User user); diff --git a/jpress-service-provider/src/main/java/io/jpress/service/provider/UserServiceProvider.java b/jpress-service-provider/src/main/java/io/jpress/service/provider/UserServiceProvider.java index 871e518dd..f2b2fc37a 100644 --- a/jpress-service-provider/src/main/java/io/jpress/service/provider/UserServiceProvider.java +++ b/jpress-service-provider/src/main/java/io/jpress/service/provider/UserServiceProvider.java @@ -130,6 +130,11 @@ public class UserServiceProvider extends JbootServiceBase implements UserS return DAO.findFirstByColumn("wx_openid", openId); } + @Override + public User findFistByDdOpenid(String openId) { + return DAO.findFirstByColumn("dd_openid", openId); + } + @Override public User findFistByQQOpenid(String openId) { return DAO.findFirstByColumn("qq_openid", openId); diff --git a/jpress-web/src/main/java/io/jpress/web/front/OauthController.java b/jpress-web/src/main/java/io/jpress/web/front/OauthController.java index 53ccbac5c..2bbaaec09 100644 --- a/jpress-web/src/main/java/io/jpress/web/front/OauthController.java +++ b/jpress-web/src/main/java/io/jpress/web/front/OauthController.java @@ -23,6 +23,7 @@ import io.jpress.JPressOptions; import io.jpress.commons.oauth2.Oauth2Controller; import io.jpress.commons.oauth2.OauthConnector; import io.jpress.commons.oauth2.OauthUser; +import io.jpress.commons.oauth2.connector.DingdingConnector; import io.jpress.commons.oauth2.connector.QQConnector; import io.jpress.commons.oauth2.connector.WechatConnector; import io.jpress.model.User; @@ -36,6 +37,7 @@ import java.util.Date; *

* 当进行qq授权的时候,应该是 /oauth/qq * 当进行微信授权的时候,应该是 /oauth/wechat + * 当进行钉钉授权的时候,应该是 /oauth/dingding *

* 这个行为由:Oauth2Controller 实现 */ @@ -62,6 +64,9 @@ public class OauthController extends Oauth2Controller { case "wechat": dbUser = userService.findFistByWxOpenid(ouser.getOpenId()); break; + case "dingding": + dbUser = userService.findFistByDdOpenid(ouser.getOpenId()); + break; default: redirect("/user/login"); return; @@ -78,7 +83,9 @@ public class OauthController extends Oauth2Controller { if ("qq".equals(ouser.getSource())) { dbUser.setQqOpenid(ouser.getOpenId()); - } else { + } else if("dingding".equals(ouser.getSource())){ + dbUser.setDdOpenid(ouser.getOpenId()); + }else{ dbUser.setWxOpenid(ouser.getOpenId()); } @@ -88,7 +95,7 @@ public class OauthController extends Oauth2Controller { EncryptCookieUtils.put(this, JPressConsts.COOKIE_UID, dbUser.getId()); //跳转到用户中心 - redirect("/user"); + redirect("/ucenter"); } @@ -116,6 +123,8 @@ public class OauthController extends Oauth2Controller { return createQQConnector(); case "wechat": return createWechatConnector(); + case "dingding": + return createDingdingConnector(); } return null; @@ -140,5 +149,13 @@ public class OauthController extends Oauth2Controller { return new WechatConnector("wechat", appkey, appsecret); } + private OauthConnector createDingdingConnector() { + boolean enable = JPressOptions.getAsBool("login_dingding_enable"); + if (enable == false) return null; + + String appkey = JPressOptions.get("login_dingding_appkey"); + String appsecret = JPressOptions.get("login_dingding_appsecret"); + return new DingdingConnector("dingding", appkey, appsecret); + } } diff --git a/jpress-web/src/main/resources/WEB-INF/views/admin/setting/reg.html b/jpress-web/src/main/resources/WEB-INF/views/admin/setting/reg.html index 843f53b74..5c5ff9067 100755 --- a/jpress-web/src/main/resources/WEB-INF/views/admin/setting/reg.html +++ b/jpress-web/src/main/resources/WEB-INF/views/admin/setting/reg.html @@ -90,6 +90,39 @@ +

+ +
+ +
+ + +
+
+ +
+ + +
+ +
+
+
+ + +
+ +

+ 钉钉的 AppKey 和 AppSecret 请去 https://open.dingtalk.com 申请。 +

+
+
+
diff --git a/jpress-web/src/main/resources/WEB-INF/views/ucenter/user_login.html b/jpress-web/src/main/resources/WEB-INF/views/ucenter/user_login.html index d62608b13..2e26aef15 100755 --- a/jpress-web/src/main/resources/WEB-INF/views/ucenter/user_login.html +++ b/jpress-web/src/main/resources/WEB-INF/views/ucenter/user_login.html @@ -52,7 +52,7 @@

- #if(option('login_qq_enable') || option('login_wechat_enable')) + #if(option('login_qq_enable') || option('login_wechat_enable') || option('login_dingding_enable'))
快速登录: @@ -63,6 +63,10 @@ #if(option('login_qq_enable')) #end + + #if(option('login_dingding_enable')) + + #end
#end diff --git a/jpress-web/src/main/resources/static/commons/img/dd.png b/jpress-web/src/main/resources/static/commons/img/dd.png new file mode 100644 index 0000000000000000000000000000000000000000..b99208c48ab33af394961767fca29babcfbb27e8 GIT binary patch literal 1185 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CH!3HFy_x^nYq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~;1FfglShD4M^`1)8S=jZArg4F0$^BXQ!4Z zB&DWj=GiK}-@RW+Av48RDcsc8z_-9TH6zobswg$M$}c3jDm&RSMakYy!KT6rXh3di zNuokUZcbjYRfVk**jy_h8zii+qySb@l5ML5aa4qFfP!;=QL2Keo|$g4p^1@#xuu?= znSrH|iH?GifuXs+fw{h+v95ukm4TU+v84hOC;@FNN=dT{a&d#&1?1T(Wt5Z@Sn2DR zmzV368|&p4rRy77T3YHG80i}s=>k>g7FXt#Bv$C=6)VF`a7isrF3Kz@$;{7F0GXJW zlwVq6s|0i@#0$9vaAWg|p}_sb2KzCH#RacwzM=fbhUIcb#ipI zG_*9buyk@Xa5IDHb;(aI%}vcKf$2>_=rzWv7nB@w3xGDeq!wkCrKY$Q<>xAZy=|3= z+bsq-&4cPq!R;19oO<dK}gn%gs#DphZAP1iKQ}ci+z6hAKs|;Ejc zGWf!@MTayCN6!%5Yqxb?Ys`BfHaSmIRY&oCZrvl< zQwy)x94$-w?DBecPT&5Zq9(tIXW1)`Sn_>rsE+x|QSoq|-2 ArvLx| literal 0 HcmV?d00001 -- Gitee