From 7d6049da67e95e4b463c8dccd2d08a7fa1be90f8 Mon Sep 17 00:00:00 2001 From: zheng-jx <18260621320@163.com> Date: Wed, 11 Aug 2021 15:50:39 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=81=E4=B8=9A=E5=BE=AE=E4=BF=A1=E7=AC=AC?= =?UTF-8?q?=E4=B8=89=E6=96=B9=E7=99=BB=E5=BD=95=20=E6=8E=A5=E5=85=A5?= =?UTF-8?q?=E9=93=BE=E6=8E=A5https://open.work.weixin.qq.com/api/doc/90001?= =?UTF-8?q?/90143/91123?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/me/zhyd/oauth/config/AuthConfig.java | 7 ++ .../zhyd/oauth/config/AuthDefaultSource.java | 33 +++++ .../oauth/request/AuthDefaultRequest.java | 2 +- ...uthWeChatEnterpriseThirdQrcodeRequest.java | 119 ++++++++++++++++++ 4 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 src/main/java/me/zhyd/oauth/request/AuthWeChatEnterpriseThirdQrcodeRequest.java diff --git a/src/main/java/me/zhyd/oauth/config/AuthConfig.java b/src/main/java/me/zhyd/oauth/config/AuthConfig.java index 38f4ccc..752464b 100644 --- a/src/main/java/me/zhyd/oauth/config/AuthConfig.java +++ b/src/main/java/me/zhyd/oauth/config/AuthConfig.java @@ -65,6 +65,13 @@ public class AuthConfig { */ private String agentId; + /** + * 企业微信第三方授权用户类型,member|admin + * + * @since 1.10.0 + */ + private String usertype; + /** * 域名前缀。 *

diff --git a/src/main/java/me/zhyd/oauth/config/AuthDefaultSource.java b/src/main/java/me/zhyd/oauth/config/AuthDefaultSource.java index ea99d3d..1339866 100644 --- a/src/main/java/me/zhyd/oauth/config/AuthDefaultSource.java +++ b/src/main/java/me/zhyd/oauth/config/AuthDefaultSource.java @@ -600,7 +600,40 @@ public enum AuthDefaultSource implements AuthSource { return "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo"; } }, + /** + * 企业微信二维码第三方登录 + */ + WECHAT_ENTERPRISE_QRCODE_THIRD { + /** + * 授权的api + * + * @return url + */ + @Override + public String authorize() { + return "https://open.work.weixin.qq.com/wwopen/sso/3rd_qrConnect"; + } + + /** + * 获取accessToken的api + * + * @return url + */ + @Override + public String accessToken() { + return "https://qyapi.weixin.qq.com/cgi-bin/service/get_provider_token"; + } + /** + * 获取用户信息的api + * + * @return url + */ + @Override + public String userInfo() { + return "https://qyapi.weixin.qq.com/cgi-bin/service/get_login_info"; + } + }, /** * 企业微信网页登录 */ diff --git a/src/main/java/me/zhyd/oauth/request/AuthDefaultRequest.java b/src/main/java/me/zhyd/oauth/request/AuthDefaultRequest.java index b765297..8a949fa 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthDefaultRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthDefaultRequest.java @@ -92,7 +92,7 @@ public abstract class AuthDefaultRequest implements AuthRequest { * @param e 具体的异常 * @return AuthResponse */ - private AuthResponse responseError(Exception e) { + AuthResponse responseError(Exception e) { int errorCode = AuthResponseStatus.FAILURE.getCode(); String errorMsg = e.getMessage(); if (e instanceof AuthException) { diff --git a/src/main/java/me/zhyd/oauth/request/AuthWeChatEnterpriseThirdQrcodeRequest.java b/src/main/java/me/zhyd/oauth/request/AuthWeChatEnterpriseThirdQrcodeRequest.java new file mode 100644 index 0000000..0f85f21 --- /dev/null +++ b/src/main/java/me/zhyd/oauth/request/AuthWeChatEnterpriseThirdQrcodeRequest.java @@ -0,0 +1,119 @@ +package me.zhyd.oauth.request; + +import com.alibaba.fastjson.JSONObject; +import me.zhyd.oauth.cache.AuthStateCache; +import me.zhyd.oauth.config.AuthConfig; +import me.zhyd.oauth.config.AuthDefaultSource; +import me.zhyd.oauth.enums.AuthResponseStatus; +import me.zhyd.oauth.exception.AuthException; +import me.zhyd.oauth.log.Log; +import me.zhyd.oauth.model.AuthCallback; +import me.zhyd.oauth.model.AuthResponse; +import me.zhyd.oauth.model.AuthToken; +import me.zhyd.oauth.model.AuthUser; +import me.zhyd.oauth.utils.*; + +/** + *

+ * 企业微信第三方二维码登录 + *

+ * + * @author zhengjx + * @since 1.10.0 + */ +public class AuthWeChatEnterpriseThirdQrcodeRequest extends AbstractAuthWeChatEnterpriseRequest { + public AuthWeChatEnterpriseThirdQrcodeRequest(AuthConfig config) { + super(config, AuthDefaultSource.WECHAT_ENTERPRISE_QRCODE_THIRD); + } + + public AuthWeChatEnterpriseThirdQrcodeRequest(AuthConfig config, AuthStateCache authStateCache) { + super(config, AuthDefaultSource.WECHAT_ENTERPRISE_QRCODE_THIRD, authStateCache); + } + + @Override + public String authorize(String state) { + return UrlBuilder.fromBaseUrl(source.authorize()) + .queryParam("appid", config.getClientId()) + .queryParam("redirect_uri", config.getRedirectUri()) + .queryParam("state", getRealState(state)) + .queryParam("usertype", config.getUsertype()) + .build(); + } + + @Override + public AuthResponse login(AuthCallback authCallback) { + try { + if (!config.isIgnoreCheckState()) { + AuthChecker.checkState(authCallback.getState(), source, authStateCache); + } + AuthToken authToken = this.getAccessToken(authCallback); + AuthUser user = this.getUserInfo(authToken); + return AuthResponse.builder().code(AuthResponseStatus.SUCCESS.getCode()).data(user).build(); + } catch (Exception e) { + Log.error("Failed to login with oauth authorization.", e); + return this.responseError(e); + } + } + + @Override + protected AuthToken getAccessToken(AuthCallback authCallback) { + try { + String response = doGetAuthorizationCode(accessTokenUrl()); + JSONObject object = this.checkResponse(response); + AuthToken authToken = AuthToken.builder() + .accessToken(object.getString("provider_access_token")) + .expireIn(object.getIntValue("expires_in")) + .build(); + return authToken; + } catch (Exception e) { + throw new AuthException("企业微信获取token失败", e); + } + } + + @Override + protected String doGetAuthorizationCode(String code) { + JSONObject data = new JSONObject(); + data.put("corpid", config.getClientId()); + data.put("provider_secret", config.getClientSecret()); + return new HttpUtils(config.getHttpConfig()).post(accessTokenUrl(code), data.toJSONString()); + } + + /** + * 获取token的URL + * + * @return + */ + protected String accessTokenUrl() { + return UrlBuilder.fromBaseUrl(source.accessToken()) + .build(); + } + + @Override + protected AuthUser getUserInfo(AuthToken authToken) { + JSONObject response = this.checkResponse(doGetUserInfo(authToken)); + return AuthUser.builder() + .rawUserInfo(response) + .build(); + } + + protected String doGetUserInfo(AuthToken authToken) { + JSONObject data = new JSONObject(); + data.put("auth_code", authToken.getCode()); + return new HttpUtils(config.getHttpConfig()) + .post(userInfoUrl(authToken), data.toJSONString()); + } + + protected String userInfoUrl(AuthToken authToken) { + return UrlBuilder.fromBaseUrl(source.userInfo()) + .queryParam("access_token", authToken.getAccessToken()). + build(); + } + + private JSONObject checkResponse(String response) { + JSONObject object = JSONObject.parseObject(response); + if (object.containsKey("errcode") && object.getIntValue("errcode") != 0) { + throw new AuthException(object.getString("errmsg"), source); + } + return object; + } +} -- GitLab