提交 f3cfe2dc 编写于 作者: 智布道's avatar 智布道 👁

支持钉钉登录

上级 70d49cd6
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
JustAuth,如你所见,它仅仅是一个**第三方授权登录****工具类库**,它可以让我们脱离繁琐的第三方登录SDK,让登录变得**So easy!** JustAuth,如你所见,它仅仅是一个**第三方授权登录****工具类库**,它可以让我们脱离繁琐的第三方登录SDK,让登录变得**So easy!**
## 快速使用 ## 快速开始
- 引入依赖 - 引入依赖
```xml ```xml
<dependency> <dependency>
...@@ -66,9 +66,9 @@ AuthRequest authRequest = new AuthGiteeRequest(AuthConfig.builder() ...@@ -66,9 +66,9 @@ AuthRequest authRequest = new AuthGiteeRequest(AuthConfig.builder()
.build()); .build());
// 自动跳转到授权页面 // 自动跳转到授权页面
authRequest.authorize(response); authRequest.authorize(response);
// 返回授权页面,可自行调整 // 返回授权页面,可自行跳转
authRequest.authorize(); authRequest.authorize();
// 授权登后会返回一个code,用这个code进行登录 // 授权登后会返回一个code,用这个code进行登录
authRequest.login("code"); authRequest.login("code");
``` ```
...@@ -79,6 +79,6 @@ authRequest.login("code"); ...@@ -79,6 +79,6 @@ authRequest.login("code");
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/github.png" width="20"> | [AuthGithubRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthGiteeRequest.java) | [https://gitee.com/api/v5/oauth_doc#list_1](https://gitee.com/api/v5/oauth_doc#list_1) | | <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/github.png" width="20"> | [AuthGithubRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthGiteeRequest.java) | [https://gitee.com/api/v5/oauth_doc#list_1](https://gitee.com/api/v5/oauth_doc#list_1) |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/weibo.png" width="20"> | [AuthWeiboRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthGiteeRequest.java) | [https://open.weibo.com/apps](https://open.weibo.com/apps) | | <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/weibo.png" width="20"> | [AuthWeiboRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthGiteeRequest.java) | [https://open.weibo.com/apps](https://open.weibo.com/apps) |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/csdn.png" width="20"> | AuthCsdnRequest | [https://connect.qq.com/](https://connect.qq.com/) | | <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/csdn.png" width="20"> | AuthCsdnRequest | [https://connect.qq.com/](https://connect.qq.com/) |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/dingding.png" width="20"> | AuthDingTalkRequest | 待续 | | <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/dingding.png" width="20"> | [AuthDingTalkRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthDingTalkRequest.java) | [https://open-doc.dingtalk.com/microapp/serverapi2/kymkv6](https://open-doc.dingtalk.com/microapp/serverapi2/kymkv6) |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/qq.png" width="20"> | AuthQqRequest | 待续 | | <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/qq.png" width="20"> | AuthQqRequest | 待续 |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechats.png" width="20"> | AuthWechatRequest | 待续 | | <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechats.png" width="20"> | AuthWechatRequest | 待续 |
...@@ -16,7 +16,7 @@ public class AuthConfig { ...@@ -16,7 +16,7 @@ public class AuthConfig {
private String clientId; private String clientId;
private String clientSecret; private String clientSecret;
/** /**
* 登成功后的回调地址 * 登成功后的回调地址
*/ */
private String redirectUri; private String redirectUri;
} }
...@@ -56,4 +56,14 @@ public class ApiUrlConst { ...@@ -56,4 +56,14 @@ public class ApiUrlConst {
*/ */
public static final String GITEE_AUTHORIZE_URL = "https://gitee.com/oauth/authorize"; public static final String GITEE_AUTHORIZE_URL = "https://gitee.com/oauth/authorize";
/**
* 获取钉钉登录二维码的地址
*/
public static final String DING_TALK_QRCONNECT_URL = "https://oapi.dingtalk.com/connect/qrconnect";
/**
* 获取钉钉用户信息的地址
*/
public static final String DING_TALK_USER_INFO_URL = "https://oapi.dingtalk.com/sns/getuserinfo_bycode";
} }
...@@ -11,6 +11,7 @@ public enum AuthSource { ...@@ -11,6 +11,7 @@ public enum AuthSource {
GITHUB, GITHUB,
GITEE, GITEE,
WEIBO, WEIBO,
DINGTALK,
QQ, QQ,
WEIXIN WEIXIN
} }
package me.zhyd.oauth.request;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.model.AuthDIngTalkErrorCode;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthSource;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.DingTalkSignatureUtil;
import me.zhyd.oauth.utils.UrlBuilder;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;
/**
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
* @version 1.0
* @website https://www.zhyd.me
* @date 2019/2/18 18:43
* @since 1.8
*/
public class AuthDingTalkRequest extends BaseAuthRequest {
public AuthDingTalkRequest(AuthConfig config) {
super(config);
}
@Override
public void authorize(HttpServletResponse response) {
String authorizeUrl = UrlBuilder.getDingTalkQrConnectUrl(config.getClientId(), config.getRedirectUri());
try {
response.sendRedirect(authorizeUrl);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public String authorize() {
return UrlBuilder.getDingTalkQrConnectUrl(config.getClientId(), config.getRedirectUri());
}
@Override
public AuthResponse login(String code) {
// 根据timestamp, appSecret计算签名值
String stringToSign = System.currentTimeMillis() + "";
String urlEncodeSignature = DingTalkSignatureUtil.computeSignature(config.getClientSecret(), stringToSign);
HttpResponse response = HttpRequest.post(UrlBuilder.getDingTalkUserInfoUrl(urlEncodeSignature, stringToSign, config.getClientId()))
.body(Objects.requireNonNull(new JSONObject().put("tmp_auth_code", code)))
.execute();
String userInfo = response.body();
JSONObject object = new JSONObject(userInfo);
AuthDIngTalkErrorCode errorCode = AuthDIngTalkErrorCode.getErrorCode(object.getInt("errcode"));
if (!AuthDIngTalkErrorCode.EC0.equals(errorCode)) {
return AuthResponse.builder().code(errorCode.getCode()).msg(errorCode.getDesc()).build();
}
object = object.getJSONObject("user_info");
System.out.println(userInfo);
return AuthResponse.builder()
.data(AuthUser.builder()
.nickname(object.getStr("nick"))
.source(AuthSource.DINGTALK)
.build())
.build();
}
}
...@@ -4,11 +4,9 @@ import cn.hutool.http.HttpRequest; ...@@ -4,11 +4,9 @@ import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse; import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.config.AuthConfig; import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthResponse; import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthSource; import me.zhyd.oauth.model.AuthSource;
import me.zhyd.oauth.model.AuthUser; import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.AuthConfigChecker;
import me.zhyd.oauth.utils.UrlBuilder; import me.zhyd.oauth.utils.UrlBuilder;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
...@@ -21,7 +19,7 @@ import java.io.IOException; ...@@ -21,7 +19,7 @@ import java.io.IOException;
* @date 2019/1/31 16:31 * @date 2019/1/31 16:31
* @since 1.8 * @since 1.8
*/ */
public class AuthGiteeRequest extends BaseAuthRequest implements AuthRequest { public class AuthGiteeRequest extends BaseAuthRequest {
public AuthGiteeRequest(AuthConfig config) { public AuthGiteeRequest(AuthConfig config) {
super(config); super(config);
...@@ -29,9 +27,6 @@ public class AuthGiteeRequest extends BaseAuthRequest implements AuthRequest { ...@@ -29,9 +27,6 @@ public class AuthGiteeRequest extends BaseAuthRequest implements AuthRequest {
@Override @Override
public void authorize(HttpServletResponse response) { public void authorize(HttpServletResponse response) {
if (!AuthConfigChecker.isSupportedGitee()) {
throw new AuthException(ResponseStatus.UNSUPPORTED);
}
String authorizeUrl = UrlBuilder.getGiteeAuthorizeUrl(config.getClientId(), config.getRedirectUri()); String authorizeUrl = UrlBuilder.getGiteeAuthorizeUrl(config.getClientId(), config.getRedirectUri());
try { try {
response.sendRedirect(authorizeUrl); response.sendRedirect(authorizeUrl);
...@@ -42,24 +37,14 @@ public class AuthGiteeRequest extends BaseAuthRequest implements AuthRequest { ...@@ -42,24 +37,14 @@ public class AuthGiteeRequest extends BaseAuthRequest implements AuthRequest {
@Override @Override
public String authorize() { public String authorize() {
if (!AuthConfigChecker.isSupportedGitee()) {
throw new AuthException(ResponseStatus.UNSUPPORTED);
}
return UrlBuilder.getGiteeAuthorizeUrl(config.getClientId(), config.getRedirectUri()); return UrlBuilder.getGiteeAuthorizeUrl(config.getClientId(), config.getRedirectUri());
} }
@Override @Override
public AuthResponse login(String code) { public AuthResponse login(String code) {
if (!AuthConfigChecker.isSupportedGitee()) {
return AuthResponse.builder()
.code(ResponseStatus.UNSUPPORTED.getCode())
.msg(ResponseStatus.UNSUPPORTED.getMsg())
.build();
}
String accessTokenUrl = UrlBuilder.getGiteeAccessTokenUrl(config.getClientId(), config.getClientSecret(), code, config.getRedirectUri()); String accessTokenUrl = UrlBuilder.getGiteeAccessTokenUrl(config.getClientId(), config.getClientSecret(), code, config.getRedirectUri());
HttpResponse response = HttpRequest.post(accessTokenUrl).execute(); HttpResponse response = HttpRequest.post(accessTokenUrl).execute();
String accessTokenStr = response.body(); JSONObject accessTokenObject = JSONObject.parseObject(response.body());
JSONObject accessTokenObject = JSONObject.parseObject(accessTokenStr);
if (accessTokenObject.containsKey("error")) { if (accessTokenObject.containsKey("error")) {
return AuthResponse.builder() return AuthResponse.builder()
.code(500) .code(500)
......
...@@ -21,7 +21,7 @@ import java.io.IOException; ...@@ -21,7 +21,7 @@ import java.io.IOException;
* @date 2019/1/31 16:31 * @date 2019/1/31 16:31
* @since 1.8 * @since 1.8
*/ */
public class AuthGithubRequest extends BaseAuthRequest implements AuthRequest { public class AuthGithubRequest extends BaseAuthRequest {
public AuthGithubRequest(AuthConfig config) { public AuthGithubRequest(AuthConfig config) {
super(config); super(config);
...@@ -29,9 +29,6 @@ public class AuthGithubRequest extends BaseAuthRequest implements AuthRequest { ...@@ -29,9 +29,6 @@ public class AuthGithubRequest extends BaseAuthRequest implements AuthRequest {
@Override @Override
public void authorize(HttpServletResponse response) { public void authorize(HttpServletResponse response) {
if (!AuthConfigChecker.isSupportedGithub()) {
throw new AuthException(ResponseStatus.UNSUPPORTED);
}
String authorizeUrl = UrlBuilder.getGithubAuthorizeUrl(config.getClientId(), config.getRedirectUri()); String authorizeUrl = UrlBuilder.getGithubAuthorizeUrl(config.getClientId(), config.getRedirectUri());
try { try {
response.sendRedirect(authorizeUrl); response.sendRedirect(authorizeUrl);
...@@ -42,20 +39,11 @@ public class AuthGithubRequest extends BaseAuthRequest implements AuthRequest { ...@@ -42,20 +39,11 @@ public class AuthGithubRequest extends BaseAuthRequest implements AuthRequest {
@Override @Override
public String authorize() { public String authorize() {
if (!AuthConfigChecker.isSupportedGithub()) {
throw new AuthException(ResponseStatus.UNSUPPORTED);
}
return UrlBuilder.getGithubAuthorizeUrl(config.getClientId(), config.getRedirectUri()); return UrlBuilder.getGithubAuthorizeUrl(config.getClientId(), config.getRedirectUri());
} }
@Override @Override
public AuthResponse login(String code) { public AuthResponse login(String code) {
if (!AuthConfigChecker.isSupportedGithub()) {
return AuthResponse.builder()
.code(ResponseStatus.UNSUPPORTED.getCode())
.msg(ResponseStatus.UNSUPPORTED.getMsg())
.build();
}
String accessTokenUrl = UrlBuilder.getGithubAccessTokenUrl(config.getClientId(), config.getClientSecret(), code, config.getRedirectUri()); String accessTokenUrl = UrlBuilder.getGithubAccessTokenUrl(config.getClientId(), config.getClientSecret(), code, config.getRedirectUri());
HttpResponse response = HttpRequest.post(accessTokenUrl).execute(); HttpResponse response = HttpRequest.post(accessTokenUrl).execute();
String accessTokenStr = response.body(); String accessTokenStr = response.body();
......
...@@ -34,7 +34,7 @@ public interface AuthRequest { ...@@ -34,7 +34,7 @@ public interface AuthRequest {
* 第三方登录 * 第三方登录
* *
* @param code 通过authorize换回的code * @param code 通过authorize换回的code
* @return 返回登成功后的用户信息 * @return 返回登成功后的用户信息
*/ */
default AuthResponse login(String code) { default AuthResponse login(String code) {
throw new AuthException(ResponseStatus.NOT_IMPLEMENTED); throw new AuthException(ResponseStatus.NOT_IMPLEMENTED);
......
...@@ -4,12 +4,10 @@ import cn.hutool.http.HttpRequest; ...@@ -4,12 +4,10 @@ import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse; import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.config.AuthConfig; import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthResponse; import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthSource; import me.zhyd.oauth.model.AuthSource;
import me.zhyd.oauth.model.AuthUser; import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.model.AuthUserGender; import me.zhyd.oauth.model.AuthUserGender;
import me.zhyd.oauth.utils.AuthConfigChecker;
import me.zhyd.oauth.utils.IpUtils; import me.zhyd.oauth.utils.IpUtils;
import me.zhyd.oauth.utils.StringUtils; import me.zhyd.oauth.utils.StringUtils;
import me.zhyd.oauth.utils.UrlBuilder; import me.zhyd.oauth.utils.UrlBuilder;
...@@ -24,7 +22,7 @@ import java.io.IOException; ...@@ -24,7 +22,7 @@ import java.io.IOException;
* @date 2019/1/31 16:31 * @date 2019/1/31 16:31
* @since 1.8 * @since 1.8
*/ */
public class AuthWeiboRequest extends BaseAuthRequest implements AuthRequest { public class AuthWeiboRequest extends BaseAuthRequest {
public AuthWeiboRequest(AuthConfig config) { public AuthWeiboRequest(AuthConfig config) {
super(config); super(config);
...@@ -32,9 +30,6 @@ public class AuthWeiboRequest extends BaseAuthRequest implements AuthRequest { ...@@ -32,9 +30,6 @@ public class AuthWeiboRequest extends BaseAuthRequest implements AuthRequest {
@Override @Override
public void authorize(HttpServletResponse response) { public void authorize(HttpServletResponse response) {
if (!AuthConfigChecker.isSupportedWeibo()) {
throw new AuthException(ResponseStatus.UNSUPPORTED);
}
String authorizeUrl = UrlBuilder.getWeiboAuthorizeUrl(config.getClientId(), config.getRedirectUri()); String authorizeUrl = UrlBuilder.getWeiboAuthorizeUrl(config.getClientId(), config.getRedirectUri());
try { try {
response.sendRedirect(authorizeUrl); response.sendRedirect(authorizeUrl);
...@@ -45,20 +40,11 @@ public class AuthWeiboRequest extends BaseAuthRequest implements AuthRequest { ...@@ -45,20 +40,11 @@ public class AuthWeiboRequest extends BaseAuthRequest implements AuthRequest {
@Override @Override
public String authorize() { public String authorize() {
if (!AuthConfigChecker.isSupportedWeibo()) {
throw new AuthException(ResponseStatus.UNSUPPORTED);
}
return UrlBuilder.getWeiboAuthorizeUrl(config.getClientId(), config.getRedirectUri()); return UrlBuilder.getWeiboAuthorizeUrl(config.getClientId(), config.getRedirectUri());
} }
@Override @Override
public AuthResponse login(String code) { public AuthResponse login(String code) {
if (!AuthConfigChecker.isSupportedWeibo()) {
return AuthResponse.builder()
.code(ResponseStatus.UNSUPPORTED.getCode())
.msg(ResponseStatus.UNSUPPORTED.getMsg())
.build();
}
String accessTokenUrl = UrlBuilder.getWeiboAccessTokenUrl(config.getClientId(), config.getClientSecret(), code, config.getRedirectUri()); String accessTokenUrl = UrlBuilder.getWeiboAccessTokenUrl(config.getClientId(), config.getClientSecret(), code, config.getRedirectUri());
HttpResponse response = HttpRequest.post(accessTokenUrl).execute(); HttpResponse response = HttpRequest.post(accessTokenUrl).execute();
String accessTokenStr = response.body(); String accessTokenStr = response.body();
......
...@@ -2,6 +2,8 @@ package me.zhyd.oauth.request; ...@@ -2,6 +2,8 @@ package me.zhyd.oauth.request;
import lombok.Data; import lombok.Data;
import me.zhyd.oauth.config.AuthConfig; import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.utils.AuthConfigChecker;
/** /**
* @author yadong.zhang (yadong.zhang0415(a)gmail.com) * @author yadong.zhang (yadong.zhang0415(a)gmail.com)
...@@ -11,10 +13,13 @@ import me.zhyd.oauth.config.AuthConfig; ...@@ -11,10 +13,13 @@ import me.zhyd.oauth.config.AuthConfig;
* @since 1.8 * @since 1.8
*/ */
@Data @Data
public abstract class BaseAuthRequest { public abstract class BaseAuthRequest implements AuthRequest {
protected AuthConfig config; protected AuthConfig config;
public BaseAuthRequest(AuthConfig config) { public BaseAuthRequest(AuthConfig config) {
this.config = config; this.config = config;
if (!AuthConfigChecker.isSupportedAuth(config)) {
throw new AuthException(ResponseStatus.UNSUPPORTED);
}
} }
} }
...@@ -12,49 +12,11 @@ import me.zhyd.oauth.config.AuthConfig; ...@@ -12,49 +12,11 @@ import me.zhyd.oauth.config.AuthConfig;
public class AuthConfigChecker { public class AuthConfigChecker {
/** /**
* 是否支持微博 * 是否支持第三方登录
* *
* @return true or false * @return true or false
*/ */
public static boolean isSupportedWeibo() { public static boolean isSupportedAuth(AuthConfig config) {
return StringUtils.isNotEmpty(AuthConfig.weiboClientId) && StringUtils.isNotEmpty(AuthConfig.weiboClientSecret) && StringUtils.isNotEmpty(AuthConfig.weiboRedirectUri); return StringUtils.isNotEmpty(config.getClientId()) && StringUtils.isNotEmpty(config.getClientSecret()) && StringUtils.isNotEmpty(config.getRedirectUri());
}
/**
* 是否支持Github
*
* @return true or false
*/
public static boolean isSupportedGithub() {
return StringUtils.isNotEmpty(AuthConfig.githubClientId) && StringUtils.isNotEmpty(AuthConfig.githubClientSecret) && StringUtils.isNotEmpty(AuthConfig.githubRedirectUri);
}
/**
* 是否支持Gitee
*
* @return true or false
*/
public static boolean isSupportedGitee() {
return StringUtils.isNotEmpty(AuthConfig.giteeClientId) && StringUtils.isNotEmpty(AuthConfig.giteeClientSecret) && StringUtils.isNotEmpty(AuthConfig.giteeRedirectUri);
}
/**
* 是否支持QQ
*
* @return true or false
*/
@Deprecated
public static boolean isSupportedQq() {
return false;
}
/**
* 是否支持微信
*
* @return true or false
*/
@Deprecated
public static boolean isSupportedWeixin() {
return false;
} }
} }
package me.zhyd.oauth.utils;
import cn.hutool.core.codec.Base64;
import me.zhyd.oauth.exception.AuthException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
public class DingTalkSignatureUtil {
/* The default encoding. */
private static final String DEFAULT_ENCODING = "UTF-8";
/* Signature method. */
private static final String ALGORITHM = "HmacSHA256";
public static String computeSignature(String canonicalString, String secret) {
try {
byte[] signData = sign(canonicalString.getBytes(DEFAULT_ENCODING), secret.getBytes(DEFAULT_ENCODING));
return urlEncode(new String(Base64.encode(signData, false)), DEFAULT_ENCODING);
} catch (UnsupportedEncodingException ex) {
throw new AuthException("Unsupported algorithm: " + DEFAULT_ENCODING, ex);
}
}
private static byte[] sign(byte[] key, byte[] data) {
try {
Mac mac = Mac.getInstance(ALGORITHM);
mac.init(new SecretKeySpec(key, ALGORITHM));
return mac.doFinal(data);
} catch (NoSuchAlgorithmException ex) {
throw new AuthException("Unsupported algorithm: " + ALGORITHM, ex);
} catch (InvalidKeyException ex) {
throw new AuthException("Invalid key: " + Arrays.toString(key), ex);
}
}
/**
* Encode a URL segment with special chars replaced.
*/
private static String urlEncode(String value, String encoding) {
if (value == null) {
return "";
}
try {
String encoded = URLEncoder.encode(value, encoding);
return encoded.replace("+", "%20").replace("*", "%2A")
.replace("~", "%7E").replace("/", "%2F");
} catch (UnsupportedEncodingException e) {
throw new AuthException("FailedToEncodeUri", e);
}
}
}
...@@ -27,6 +27,9 @@ public class UrlBuilder { ...@@ -27,6 +27,9 @@ public class UrlBuilder {
private static final String GITEE_USER_INFO_PATTERN = "{0}?access_token={1}"; private static final String GITEE_USER_INFO_PATTERN = "{0}?access_token={1}";
private static final String GITEE_AUTHORIZE_PATTERN = "{0}?client_id={1}&response_type=code&redirect_uri={2}"; private static final String GITEE_AUTHORIZE_PATTERN = "{0}?client_id={1}&response_type=code&redirect_uri={2}";
private static final String DING_TALK_QRCONNECT_PATTERN = "{0}?appid={1}&response_type=code&scope=snsapi_login&state=STATE&redirect_uri={2}";
private static final String DING_TALK_USER_INFO_PATTERN = "{0}?signature={1}&timestamp={2}&accessKey={3}";
/** /**
* 获取githubtoken的接口地址 * 获取githubtoken的接口地址
* *
...@@ -34,7 +37,7 @@ public class UrlBuilder { ...@@ -34,7 +37,7 @@ public class UrlBuilder {
* @param clientSecret github应用的Client Secret * @param clientSecret github应用的Client Secret
* @param code github授权前的code,用来换token * @param code github授权前的code,用来换token
* @param redirectUri 待跳转的页面 * @param redirectUri 待跳转的页面
* @return 换取github授权token的真实地址 * @return full url
*/ */
public static String getGithubAccessTokenUrl(String clientId, String clientSecret, String code, String redirectUri) { public static String getGithubAccessTokenUrl(String clientId, String clientSecret, String code, String redirectUri) {
return MessageFormat.format(GITHUB_ACCESS_TOKEN_PATTERN, ApiUrlConst.GITHUB_ACCESS_TOKEN_URL, clientId, clientSecret, code, redirectUri); return MessageFormat.format(GITHUB_ACCESS_TOKEN_PATTERN, ApiUrlConst.GITHUB_ACCESS_TOKEN_URL, clientId, clientSecret, code, redirectUri);
...@@ -44,7 +47,7 @@ public class UrlBuilder { ...@@ -44,7 +47,7 @@ public class UrlBuilder {
* 获取github用户详情的接口地址 * 获取github用户详情的接口地址
* *
* @param token github 应用的token * @param token github 应用的token
* @return json * @return full url
*/ */
public static String getGithubUserInfoUrl(String token) { public static String getGithubUserInfoUrl(String token) {
return MessageFormat.format(GITHUB_USER_INFO_PATTERN, ApiUrlConst.GITHUB_USER_INFO_URL, token); return MessageFormat.format(GITHUB_USER_INFO_PATTERN, ApiUrlConst.GITHUB_USER_INFO_URL, token);
...@@ -55,7 +58,7 @@ public class UrlBuilder { ...@@ -55,7 +58,7 @@ public class UrlBuilder {
* *
* @param clientId github 应用的Client ID * @param clientId github 应用的Client ID
* @param redirectUrl github 应用授权成功后的回调地址 * @param redirectUrl github 应用授权成功后的回调地址
* @return json * @return full url
*/ */
public static String getGithubAuthorizeUrl(String clientId, String redirectUrl) { public static String getGithubAuthorizeUrl(String clientId, String redirectUrl) {
return MessageFormat.format(GITHUB_AUTHORIZE_PATTERN, ApiUrlConst.GITHUB_AUTHORIZE_URL, clientId, redirectUrl); return MessageFormat.format(GITHUB_AUTHORIZE_PATTERN, ApiUrlConst.GITHUB_AUTHORIZE_URL, clientId, redirectUrl);
...@@ -68,7 +71,7 @@ public class UrlBuilder { ...@@ -68,7 +71,7 @@ public class UrlBuilder {
* @param clientSecret weibo应用的App Secret * @param clientSecret weibo应用的App Secret
* @param code weibo授权前的code,用来换token * @param code weibo授权前的code,用来换token
* @param redirectUri 待跳转的页面 * @param redirectUri 待跳转的页面
* @return 换取weibo授权token的真实地址 * @return full url
*/ */
public static String getWeiboAccessTokenUrl(String clientId, String clientSecret, String code, String redirectUri) { public static String getWeiboAccessTokenUrl(String clientId, String clientSecret, String code, String redirectUri) {
return MessageFormat.format(WEIBO_ACCESS_TOKEN_PATTERN, ApiUrlConst.WEIBO_ACCESS_TOKEN_URL, clientId, clientSecret, code, redirectUri); return MessageFormat.format(WEIBO_ACCESS_TOKEN_PATTERN, ApiUrlConst.WEIBO_ACCESS_TOKEN_URL, clientId, clientSecret, code, redirectUri);
...@@ -79,7 +82,7 @@ public class UrlBuilder { ...@@ -79,7 +82,7 @@ public class UrlBuilder {
* *
* @param uid 用户id * @param uid 用户id
* @param token weibo 应用的token * @param token weibo 应用的token
* @return json * @return full url
*/ */
public static String getWeiboUserInfoUrl(String uid, String token) { public static String getWeiboUserInfoUrl(String uid, String token) {
return MessageFormat.format(WEIBO_USER_INFO_PATTERN, ApiUrlConst.WEIBO_USER_INFO_URL, uid, token); return MessageFormat.format(WEIBO_USER_INFO_PATTERN, ApiUrlConst.WEIBO_USER_INFO_URL, uid, token);
...@@ -90,7 +93,7 @@ public class UrlBuilder { ...@@ -90,7 +93,7 @@ public class UrlBuilder {
* *
* @param clientId weibo 应用的Client ID * @param clientId weibo 应用的Client ID
* @param redirectUrl weibo 应用授权成功后的回调地址 * @param redirectUrl weibo 应用授权成功后的回调地址
* @return json * @return full url
*/ */
public static String getWeiboAuthorizeUrl(String clientId, String redirectUrl) { public static String getWeiboAuthorizeUrl(String clientId, String redirectUrl) {
return MessageFormat.format(WEIBO_AUTHORIZE_PATTERN, ApiUrlConst.WEIBO_AUTHORIZE_URL, clientId, redirectUrl); return MessageFormat.format(WEIBO_AUTHORIZE_PATTERN, ApiUrlConst.WEIBO_AUTHORIZE_URL, clientId, redirectUrl);
...@@ -103,7 +106,7 @@ public class UrlBuilder { ...@@ -103,7 +106,7 @@ public class UrlBuilder {
* @param clientSecret gitee应用的Client Secret * @param clientSecret gitee应用的Client Secret
* @param code gitee授权前的code,用来换token * @param code gitee授权前的code,用来换token
* @param redirectUri 待跳转的页面 * @param redirectUri 待跳转的页面
* @return 换取gitee授权token的真实地址 * @return full url
*/ */
public static String getGiteeAccessTokenUrl(String clientId, String clientSecret, String code, String redirectUri) { public static String getGiteeAccessTokenUrl(String clientId, String clientSecret, String code, String redirectUri) {
return MessageFormat.format(GITEE_ACCESS_TOKEN_PATTERN, ApiUrlConst.GITEE_ACCESS_TOKEN_URL, clientId, clientSecret, code, redirectUri); return MessageFormat.format(GITEE_ACCESS_TOKEN_PATTERN, ApiUrlConst.GITEE_ACCESS_TOKEN_URL, clientId, clientSecret, code, redirectUri);
...@@ -113,7 +116,7 @@ public class UrlBuilder { ...@@ -113,7 +116,7 @@ public class UrlBuilder {
* 获取gitee用户详情的接口地址 * 获取gitee用户详情的接口地址
* *
* @param token gitee 应用的token * @param token gitee 应用的token
* @return json * @return full url
*/ */
public static String getGiteeUserInfoUrl(String token) { public static String getGiteeUserInfoUrl(String token) {
return MessageFormat.format(GITEE_USER_INFO_PATTERN, ApiUrlConst.GITEE_USER_INFO_URL, token); return MessageFormat.format(GITEE_USER_INFO_PATTERN, ApiUrlConst.GITEE_USER_INFO_URL, token);
...@@ -129,4 +132,27 @@ public class UrlBuilder { ...@@ -129,4 +132,27 @@ public class UrlBuilder {
public static String getGiteeAuthorizeUrl(String clientId, String redirectUrl) { public static String getGiteeAuthorizeUrl(String clientId, String redirectUrl) {
return MessageFormat.format(GITEE_AUTHORIZE_PATTERN, ApiUrlConst.GITEE_AUTHORIZE_URL, clientId, redirectUrl); return MessageFormat.format(GITEE_AUTHORIZE_PATTERN, ApiUrlConst.GITEE_AUTHORIZE_URL, clientId, redirectUrl);
} }
/**
* 获取钉钉登录二维码的地址
*
* @param clientId 钉钉 应用的App Id
* @param redirectUrl 钉钉 应用授权成功后的回调地址
* @return full url
*/
public static String getDingTalkQrConnectUrl(String clientId, String redirectUrl) {
return MessageFormat.format(DING_TALK_QRCONNECT_PATTERN, ApiUrlConst.DING_TALK_QRCONNECT_URL, clientId, redirectUrl);
}
/**
* 获取钉钉用户信息的地址
*
* @param signature 通过appSecret计算出来的签名值,签名计算方法:https://open-doc.dingtalk.com/microapp/faquestions/hxs5v9
* @param timestamp 当前时间戳,单位是毫秒
* @param accessKey 钉钉 应用的App Id
* @return full url
*/
public static String getDingTalkUserInfoUrl(String signature, String timestamp, String accessKey) {
return MessageFormat.format(DING_TALK_USER_INFO_PATTERN, ApiUrlConst.DING_TALK_USER_INFO_URL, signature, timestamp, accessKey);
}
} }
package me.zhyd.oauth; package me.zhyd.oauth;
import me.zhyd.oauth.config.AuthConfig; import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.request.AuthGiteeRequest; import me.zhyd.oauth.request.*;
import me.zhyd.oauth.request.AuthGithubRequest;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.request.AuthWeiboRequest;
import org.junit.Test; import org.junit.Test;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
...@@ -19,7 +16,8 @@ import javax.servlet.http.HttpServletResponse; ...@@ -19,7 +16,8 @@ import javax.servlet.http.HttpServletResponse;
public class AuthRequestTest { public class AuthRequestTest {
@Test @Test
public void giteeTest(HttpServletResponse response) { public void giteeTest() {
HttpServletResponse response = null;
AuthRequest authRequest = new AuthGiteeRequest(AuthConfig.builder() AuthRequest authRequest = new AuthGiteeRequest(AuthConfig.builder()
.clientId("clientId") .clientId("clientId")
.clientSecret("clientSecret") .clientSecret("clientSecret")
...@@ -29,12 +27,13 @@ public class AuthRequestTest { ...@@ -29,12 +27,13 @@ public class AuthRequestTest {
authRequest.authorize(response); authRequest.authorize(response);
// 返回授权页面,可自行调整 // 返回授权页面,可自行调整
authRequest.authorize(); authRequest.authorize();
// 授权登后会返回一个code,用这个code进行登录 // 授权登后会返回一个code,用这个code进行登录
authRequest.login("code"); authRequest.login("code");
} }
@Test @Test
public void githubTest(HttpServletResponse response) { public void githubTest() {
HttpServletResponse response = null;
AuthRequest authRequest = new AuthGithubRequest(AuthConfig.builder() AuthRequest authRequest = new AuthGithubRequest(AuthConfig.builder()
.clientId("clientId") .clientId("clientId")
.clientSecret("clientSecret") .clientSecret("clientSecret")
...@@ -44,12 +43,13 @@ public class AuthRequestTest { ...@@ -44,12 +43,13 @@ public class AuthRequestTest {
authRequest.authorize(response); authRequest.authorize(response);
// 返回授权页面,可自行调整 // 返回授权页面,可自行调整
authRequest.authorize(); authRequest.authorize();
// 授权登后会返回一个code,用这个code进行登录 // 授权登后会返回一个code,用这个code进行登录
authRequest.login("code"); authRequest.login("code");
} }
@Test @Test
public void weiboTest(HttpServletResponse response) { public void weiboTest() {
HttpServletResponse response = null;
AuthRequest authRequest = new AuthWeiboRequest(AuthConfig.builder() AuthRequest authRequest = new AuthWeiboRequest(AuthConfig.builder()
.clientId("clientId") .clientId("clientId")
.clientSecret("clientSecret") .clientSecret("clientSecret")
...@@ -59,7 +59,24 @@ public class AuthRequestTest { ...@@ -59,7 +59,24 @@ public class AuthRequestTest {
authRequest.authorize(response); authRequest.authorize(response);
// 返回授权页面,可自行调整 // 返回授权页面,可自行调整
authRequest.authorize(); authRequest.authorize();
// 授权登后会返回一个code,用这个code进行登录 // 授权登后会返回一个code,用这个code进行登录
authRequest.login("code"); authRequest.login("code");
} }
@Test
public void dingdingTest() {
HttpServletResponse response = null;
AuthRequest authRequest = new AuthDingTalkRequest(AuthConfig.builder()
.clientId("dingoa2q6o3fomfk6vdqzy")
.clientSecret("d5w75-R-yNtQsq_Ya_r50gOsKOy9WlmrlUOJkUJXKvsQp7NDPRHsj0epJriiN3yO")
.redirectUri("http://61.149.7.121:8443/oauth/dingtalk/callback")
.build());
// 自动跳转到授权页面
// authRequest.authorize(response);
// 返回授权页面,可自行调整
String url = authRequest.authorize();
System.out.println(url);
// 授权登录后会返回一个code,用这个code进行登录
// authRequest.login("code");
}
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册