mirror of
https://gitee.com/yadong.zhang/JustAuth.git
synced 2025-12-06 16:58:24 +08:00
Merge branch 'dev'
This commit is contained in:
commit
bbf63c6056
@ -1,11 +1,25 @@
|
|||||||
## 1.16.6
|
## 1.16.7
|
||||||
|
|
||||||
### 2024/08/03
|
### 2024/12/14
|
||||||
|
|
||||||
- 新增
|
- 新增
|
||||||
- 添加 appleid 社交登录能力。 [Github #192](https://github.com/justauth/JustAuth/pull/192)
|
- 添加`微信小程序`登录能力。
|
||||||
- Fixed
|
- 添加`支付宝证书模式`登录能力(原支持的公钥登录模式依然可用)。
|
||||||
|
- 添加`appleid`社交登录能力。 [Github#192](https://github.com/justauth/JustAuth/pull/192)
|
||||||
|
- 添加`QQ小程序`社交登录能力。 [Github#223](https://github.com/justauth/JustAuth/pull/223)
|
||||||
|
- 添加`figma`社交登录能力。 [Gitee#41](https://gitee.com/yadong.zhang/JustAuth/pulls/41)
|
||||||
|
- 添加新版`企业微信扫码`登录能力。 [Github Issue#165](https://github.com/justauth/JustAuth/issues/165)
|
||||||
|
- 添加新版`钉钉扫码`登录能力。 [Gitee Issue#I73FZL](https://gitee.com/yadong.zhang/JustAuth/issues/I73FZL)
|
||||||
|
- 添加新版`华为`登录能力,原`AuthHuaweiRequest`会在后面版本被弃用,如有使用,请切换到`AuthHuaweiV3Request`
|
||||||
- 优化
|
- 优化
|
||||||
|
- 修复文档错误。[Github #222](https://github.com/justauth/JustAuth/pull/222)
|
||||||
|
- 更新 Google 端点地址。[Github #198](https://github.com/justauth/JustAuth/pull/198)
|
||||||
|
- Amazon PKCE 中的 `code_verifier` 基于 `state` 缓存
|
||||||
|
- `AuthRequest`响应时携带泛型,避免二次解析。[Gitee#38](https://gitee.com/yadong.zhang/JustAuth/pulls/38)
|
||||||
|
- 优化业务调用方式:`getAccessToken`和`getUserInfo`两个方法从`AuthDefaultRequest`提升至`AuthRequest`中,部分场景下可以减少一次网络请求。[Github Issue#194](https://github.com/justauth/JustAuth/issues/194)
|
||||||
|
- ***注意:如果有基于 JustAuth 规范自定义实现的三方平台 Request([自定义第三方平台的OAuth](https://justauth.cn/features/customize-the-oauth/)),需要注意`getAccessToken`和`getUserInfo`接口的访问级别是否正确!!!***
|
||||||
|
- 其他
|
||||||
|
- 补充单侧,[Gitee#39](https://gitee.com/yadong.zhang/JustAuth/pulls/39)
|
||||||
|
|
||||||
## 1.16.6
|
## 1.16.6
|
||||||
|
|
||||||
|
|||||||
10
README.md
10
README.md
@ -55,11 +55,11 @@ JustAuth 集成了诸如:Github、Gitee、支付宝、新浪微博、微信、
|
|||||||
|
|
||||||
## 有哪些功能?
|
## 有哪些功能?
|
||||||
|
|
||||||
- 集成国内外数十家第三方平台,实现快速接入。<a href="https://www.justauth.cn/quickstart/how-to-use.html" target="_blank">参考文档</a>
|
- 集成国内外数十家第三方平台,实现快速接入。<a href="https://www.justauth.cn/guide/" target="_blank">参考文档</a>
|
||||||
- 自定义 State 缓存,支持各种分布式缓存组件。<a href="https://www.justauth.cn/features/customize-the-state-cache.html" target="_blank">参考文档</a>
|
- 自定义 State 缓存,支持各种分布式缓存组件。<a href="https://www.justauth.cn/features/using-state/" target="_blank">参考文档</a>
|
||||||
- 自定义 OAuth 平台,更容易适配自有的 OAuth 服务。<a href="https://www.justauth.cn/features/customize-the-oauth.html" target="_blank">参考文档</a>
|
- 自定义 OAuth 平台,更容易适配自有的 OAuth 服务。<a href="https://www.justauth.cn/features/customize-the-oauth/" target="_blank">参考文档</a>
|
||||||
- 自定义 Http 实现,选择权完全交给开发者,不会单独依赖某一具体实现。<a href="https://www.justauth.cn/quickstart/how-to-use.html#%E4%BD%BF%E7%94%A8%E6%96%B9%E5%BC%8F" target="_blank">参考文档</a>
|
- 自定义 Http 实现,选择权完全交给开发者,不会单独依赖某一具体实现。<a href="https://www.justauth.cn/guide/quickstart/how-to-use/#%E4%BD%BF%E7%94%A8%E6%AD%A5%E9%AA%A4" target="_blank">参考文档</a>
|
||||||
- 自定义 Scope,支持更完善的授权体系。<a href="https://www.justauth.cn/features/customize-scopes.html" target="_blank">参考文档</a>
|
- 自定义 Scope,支持更完善的授权体系。<a href="https://www.justauth.cn/features/customize-scopes/#%E5%85%B3%E4%BA%8E-scope" target="_blank">参考文档</a>
|
||||||
- 更多...<a href="https://www.justauth.cn" target="_blank">参考文档</a>
|
- 更多...<a href="https://www.justauth.cn" target="_blank">参考文档</a>
|
||||||
|
|
||||||
## 快速开始
|
## 快速开始
|
||||||
|
|||||||
8
pom.xml
8
pom.xml
@ -58,10 +58,10 @@
|
|||||||
<maven-gpg-version>1.6</maven-gpg-version>
|
<maven-gpg-version>1.6</maven-gpg-version>
|
||||||
<maven.test.skip>false</maven.test.skip>
|
<maven.test.skip>false</maven.test.skip>
|
||||||
<simple-http.version>1.0.5</simple-http.version>
|
<simple-http.version>1.0.5</simple-http.version>
|
||||||
<lombok-version>1.18.20</lombok-version>
|
<lombok-version>1.18.30</lombok-version>
|
||||||
<junit-version>4.13.2</junit-version>
|
<junit-version>4.13.2</junit-version>
|
||||||
<fastjson-version>1.2.83</fastjson-version>
|
<fastjson-version>1.2.83</fastjson-version>
|
||||||
<alipay-sdk-version>4.17.5.ALL</alipay-sdk-version>
|
<alipay-sdk-version>4.39.165.ALL</alipay-sdk-version>
|
||||||
<jacoco-version>0.8.2</jacoco-version>
|
<jacoco-version>0.8.2</jacoco-version>
|
||||||
<jwt.version>0.12.3</jwt.version>
|
<jwt.version>0.12.3</jwt.version>
|
||||||
<bcpkix-jdk18on.version>1.78</bcpkix-jdk18on.version>
|
<bcpkix-jdk18on.version>1.78</bcpkix-jdk18on.version>
|
||||||
@ -106,21 +106,25 @@
|
|||||||
<groupId>io.jsonwebtoken</groupId>
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
<artifactId>jjwt-api</artifactId>
|
<artifactId>jjwt-api</artifactId>
|
||||||
<version>${jwt.version}</version>
|
<version>${jwt.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.jsonwebtoken</groupId>
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
<artifactId>jjwt-impl</artifactId>
|
<artifactId>jjwt-impl</artifactId>
|
||||||
<version>${jwt.version}</version>
|
<version>${jwt.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.jsonwebtoken</groupId>
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
<artifactId>jjwt-jackson</artifactId>
|
<artifactId>jjwt-jackson</artifactId>
|
||||||
<version>${jwt.version}</version>
|
<version>${jwt.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.bouncycastle</groupId>
|
<groupId>org.bouncycastle</groupId>
|
||||||
<artifactId>bcpkix-jdk18on</artifactId>
|
<artifactId>bcpkix-jdk18on</artifactId>
|
||||||
<version>${bcpkix-jdk18on.version}</version>
|
<version>${bcpkix-jdk18on.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|||||||
@ -198,4 +198,58 @@ public class AuthConfig {
|
|||||||
* @see <a href="https://developer.apple.com/help/glossary/team-id/">team id</a>
|
* @see <a href="https://developer.apple.com/help/glossary/team-id/">team id</a>
|
||||||
*/
|
*/
|
||||||
private String teamId;
|
private String teamId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新版企业微信 Web 登录时的参数,
|
||||||
|
*
|
||||||
|
* 登录类型。ServiceApp:服务商登录;CorpApp:企业自建/代开发应用登录。
|
||||||
|
* @see <a href="https://developer.work.weixin.qq.com/document/path/98152">https://developer.work.weixin.qq.com/document/path/98152</a>
|
||||||
|
* @since 1.16.7
|
||||||
|
*/
|
||||||
|
private String loginType = "CorpApp";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 企业微信平台的语言编码
|
||||||
|
*
|
||||||
|
* @since 1.16.7
|
||||||
|
*/
|
||||||
|
private String lang = "zh";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 钉钉平台参数:控制输出特定类型的组织列表,org_type=management 表示只输出有管理权限的组织。
|
||||||
|
*
|
||||||
|
* scope包含corpid时该参数存在意义。
|
||||||
|
*
|
||||||
|
* @see <a href="https://open.dingtalk.com/document/orgapp/obtain-identity-credentials#title-4up-u8w-5ug">https://open.dingtalk.com/document/orgapp/obtain-identity-credentials#title-4up-u8w-5ug</a>
|
||||||
|
* @since 1.16.7
|
||||||
|
*/
|
||||||
|
private String dingTalkOrgType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 钉钉平台参数:用于指定用户需要选择的组织。
|
||||||
|
*
|
||||||
|
* scope包含corpid时该参数存在意义。传入的corpId需要是当前用户所在的组织。
|
||||||
|
*
|
||||||
|
* @see <a href="https://open.dingtalk.com/document/orgapp/obtain-identity-credentials#title-4up-u8w-5ug">https://open.dingtalk.com/document/orgapp/obtain-identity-credentials#title-4up-u8w-5ug</a>
|
||||||
|
* @since 1.16.7
|
||||||
|
*/
|
||||||
|
private String dingTalkCorpId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 钉钉平台参数:true表示专属帐号登录,展示组织代码输入页。
|
||||||
|
*
|
||||||
|
* @see <a href="https://open.dingtalk.com/document/orgapp/obtain-identity-credentials#title-4up-u8w-5ug">https://open.dingtalk.com/document/orgapp/obtain-identity-credentials#title-4up-u8w-5ug</a>
|
||||||
|
* @since 1.16.7
|
||||||
|
*/
|
||||||
|
private boolean dingTalkExclusiveLogin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 钉钉平台参数:开启了专属帐号功能的组织corpId。
|
||||||
|
*
|
||||||
|
* scope包含corpid时该参数存在意义。传入的corpId需要是当前用户所在的组织。
|
||||||
|
*
|
||||||
|
* @see <a href="https://open.dingtalk.com/document/orgapp/obtain-identity-credentials#title-4up-u8w-5ug">https://open.dingtalk.com/document/orgapp/obtain-identity-credentials#title-4up-u8w-5ug</a>
|
||||||
|
* @since 1.16.7
|
||||||
|
*/
|
||||||
|
private String dingTalkExclusiveCorpId;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -112,6 +112,30 @@ public enum AuthDefaultSource implements AuthSource {
|
|||||||
return AuthDingTalkRequest.class;
|
return AuthDingTalkRequest.class;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* 新版钉钉扫码登录
|
||||||
|
*/
|
||||||
|
DINGTALK_V2 {
|
||||||
|
@Override
|
||||||
|
public String authorize() {
|
||||||
|
return "https://login.dingtalk.com/oauth2/challenge.htm";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String accessToken() {
|
||||||
|
return "https://api.dingtalk.com/v1.0/oauth2/userAccessToken";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String userInfo() {
|
||||||
|
return "https://api.dingtalk.com/v1.0/contact/users/me";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends AuthDefaultRequest> getTargetClass() {
|
||||||
|
return AuthDingTalkV2Request.class;
|
||||||
|
}
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* 钉钉账号登录
|
* 钉钉账号登录
|
||||||
*/
|
*/
|
||||||
@ -382,6 +406,7 @@ public enum AuthDefaultSource implements AuthSource {
|
|||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Google
|
* Google
|
||||||
|
* 端点地址:https://accounts.google.com/.well-known/openid-configuration
|
||||||
*/
|
*/
|
||||||
GOOGLE {
|
GOOGLE {
|
||||||
@Override
|
@Override
|
||||||
@ -391,12 +416,12 @@ public enum AuthDefaultSource implements AuthSource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String accessToken() {
|
public String accessToken() {
|
||||||
return "https://www.googleapis.com/oauth2/v4/token";
|
return "https://oauth2.googleapis.com/token";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String userInfo() {
|
public String userInfo() {
|
||||||
return "https://www.googleapis.com/oauth2/v3/userinfo";
|
return "https://openidconnect.googleapis.com/v1/userinfo";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -708,8 +733,11 @@ public enum AuthDefaultSource implements AuthSource {
|
|||||||
/**
|
/**
|
||||||
* 华为
|
* 华为
|
||||||
*
|
*
|
||||||
|
* 当前方式未来可能被废弃,建议使用 {@link this#HUAWEI_V3}
|
||||||
|
*
|
||||||
* @since 1.10.0
|
* @since 1.10.0
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
HUAWEI {
|
HUAWEI {
|
||||||
@Override
|
@Override
|
||||||
public String authorize() {
|
public String authorize() {
|
||||||
@ -737,6 +765,38 @@ public enum AuthDefaultSource implements AuthSource {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 华为最新版本的 API
|
||||||
|
*
|
||||||
|
* @since 1.16.7
|
||||||
|
*/
|
||||||
|
HUAWEI_V3 {
|
||||||
|
@Override
|
||||||
|
public String authorize() {
|
||||||
|
return "https://oauth-login.cloud.huawei.com/oauth2/v3/authorize";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String accessToken() {
|
||||||
|
return "https://oauth-login.cloud.huawei.com/oauth2/v3/token";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String userInfo() {
|
||||||
|
return "https://account.cloud.huawei.com/rest.php";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String refresh() {
|
||||||
|
return "https://oauth-login.cloud.huawei.com/oauth2/v3/token";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends AuthDefaultRequest> getTargetClass() {
|
||||||
|
return AuthHuaweiV3Request.class;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 企业微信二维码登录
|
* 企业微信二维码登录
|
||||||
*
|
*
|
||||||
@ -763,6 +823,32 @@ public enum AuthDefaultSource implements AuthSource {
|
|||||||
return AuthWeChatEnterpriseQrcodeRequest.class;
|
return AuthWeChatEnterpriseQrcodeRequest.class;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* 新版企业微信 Web 登录(扫码),参考 <a href="https://developer.work.weixin.qq.com/document/path/98152">https://developer.work.weixin.qq.com/document/path/98152</a>
|
||||||
|
*
|
||||||
|
* @since 1.16.7
|
||||||
|
*/
|
||||||
|
WECHAT_ENTERPRISE_V2 {
|
||||||
|
@Override
|
||||||
|
public String authorize() {
|
||||||
|
return "https://login.work.weixin.qq.com/wwlogin/sso/login";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String accessToken() {
|
||||||
|
return "https://qyapi.weixin.qq.com/cgi-bin/gettoken";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String userInfo() {
|
||||||
|
return "https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends AuthDefaultRequest> getTargetClass() {
|
||||||
|
return AuthWeChatEnterpriseQrcodeV2Request.class;
|
||||||
|
}
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* 企业微信二维码第三方登录
|
* 企业微信二维码第三方登录
|
||||||
*/
|
*/
|
||||||
@ -1321,6 +1407,92 @@ public enum AuthDefaultSource implements AuthSource {
|
|||||||
public Class<? extends AuthDefaultRequest> getTargetClass() {
|
public Class<? extends AuthDefaultRequest> getTargetClass() {
|
||||||
return AuthAppleRequest.class;
|
return AuthAppleRequest.class;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
FIGMA{
|
||||||
|
@Override
|
||||||
|
public String authorize() {
|
||||||
|
return "https://www.figma.com/oauth";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String accessToken() {
|
||||||
|
return "https://www.figma.com/api/oauth/token";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String userInfo() {
|
||||||
|
return "https://api.figma.com/v1/me";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String refresh() {
|
||||||
|
return "https://www.figma.com/api/oauth/refresh";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends AuthDefaultRequest> getTargetClass() {
|
||||||
|
return AuthFigmaRequest.class;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 微信小程序授权登录
|
||||||
|
* @since yudaocode
|
||||||
|
*/
|
||||||
|
WECHAT_MINI_PROGRAM {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String authorize() {
|
||||||
|
// 参见 https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html 文档
|
||||||
|
throw new UnsupportedOperationException("不支持获取授权 url,请使用小程序内置函数 wx.login() 登录获取 code");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String accessToken() {
|
||||||
|
// 参见 https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html 文档
|
||||||
|
// 获取 openid, unionId , session_key 等字段
|
||||||
|
return "https://api.weixin.qq.com/sns/jscode2session";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String userInfo() {
|
||||||
|
// 参见 https://developers.weixin.qq.com/miniprogram/dev/api/open-api/user-info/wx.getUserProfile.html 文档
|
||||||
|
throw new UnsupportedOperationException("不支持获取用户信息 url,请使用小程序内置函数 wx.getUserProfile() 获取用户信息");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends AuthDefaultRequest> getTargetClass() {
|
||||||
|
return AuthWechatMiniProgramRequest.class;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* QQ小程序授权登录
|
||||||
|
*/
|
||||||
|
QQ_MINI_PROGRAM {
|
||||||
|
@Override
|
||||||
|
public String authorize() {
|
||||||
|
// 参见 https://q.qq.com/wiki/develop/miniprogram/frame/open_ability/open_userinfo.html 文档
|
||||||
|
throw new UnsupportedOperationException("不支持获取授权 url,请使用小程序内置函数 qq.login() 登录获取 code");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String accessToken() {
|
||||||
|
// 参见 https://q.qq.com/wiki/develop/miniprogram/server/open_port/port_login.html 文档
|
||||||
|
// 获取 openid, unionId , session_key 等字段
|
||||||
|
return "https://api.q.qq.com/sns/jscode2session";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String userInfo() {
|
||||||
|
// 参见 https://q.qq.com/wiki/develop/miniprogram/API/open_port/port_userinfo.html 文档
|
||||||
|
throw new UnsupportedOperationException("不支持获取用户信息 url,请使用小程序内置函数 qq.getUserInfo() 获取用户信息");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends AuthDefaultRequest> getTargetClass() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,6 +33,7 @@ public enum AuthResponseStatus {
|
|||||||
ILLEGAL_TEAM_ID(5013, "Invalid team id"),
|
ILLEGAL_TEAM_ID(5013, "Invalid team id"),
|
||||||
ILLEGAL_CLIENT_ID(5014, "Invalid client id"),
|
ILLEGAL_CLIENT_ID(5014, "Invalid client id"),
|
||||||
ILLEGAL_CLIENT_SECRET(5015, "Invalid client secret"),
|
ILLEGAL_CLIENT_SECRET(5015, "Invalid client secret"),
|
||||||
|
ILLEGAL_WECHAT_AGENT_ID(5016, "Illegal wechat agent id"),
|
||||||
;
|
;
|
||||||
|
|
||||||
private final int code;
|
private final int code;
|
||||||
|
|||||||
@ -0,0 +1,33 @@
|
|||||||
|
package me.zhyd.oauth.enums.scope;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 钉钉平台 OAuth 授权范围
|
||||||
|
*
|
||||||
|
* https://open.dingtalk.com/document/orgapp/obtain-identity-credentials#title-4up-u8w-5ug
|
||||||
|
*
|
||||||
|
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 1.16.7
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum AuthDingTalkScope implements AuthScope {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无需申请 默认开启
|
||||||
|
*/
|
||||||
|
openid("openid", "授权后可获得用户userid", true),
|
||||||
|
/**
|
||||||
|
* 无需申请 默认开启
|
||||||
|
*/
|
||||||
|
corpid("corpid", "授权后可获得登录过程中用户选择的组织id", false)
|
||||||
|
;
|
||||||
|
|
||||||
|
private final String scope;
|
||||||
|
private final String description;
|
||||||
|
private final boolean isDefault;
|
||||||
|
|
||||||
|
}
|
||||||
29
src/main/java/me/zhyd/oauth/enums/scope/AuthFigmaScope.java
Normal file
29
src/main/java/me/zhyd/oauth/enums/scope/AuthFigmaScope.java
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package me.zhyd.oauth.enums.scope;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Figma OAuth 授权范围
|
||||||
|
* <a href="https://www.figma.com/developers/api#authentication-scopes">...</a>
|
||||||
|
*
|
||||||
|
* @author xiangqian
|
||||||
|
* @since 1.16.6
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum AuthFigmaScope implements AuthScope {
|
||||||
|
|
||||||
|
FILE_CONTENT("files:read", "Read files, projects, users, versions, comments, components & styles, and webhooks", true),
|
||||||
|
VARIABLES("file_variables:read,file_variables:write", "Read and write to variables in Figma file. Note: this is only available to members in Enterprise organizations", false),
|
||||||
|
COMMENTS("file_comments:write", "Post and delete comments and comment reactions in files", false),
|
||||||
|
DEV_RESOURCES("file_dev_resources:read,file_dev_resources:write", "Read and write to dev resources in files", false),
|
||||||
|
LIBRARY_ANALYTICS("library_analytics:read", "Read your design system analytics", false),
|
||||||
|
WEBHOOKS("webhooks:write", "Create and manage webhooks", false);
|
||||||
|
|
||||||
|
private final String scope;
|
||||||
|
private final String description;
|
||||||
|
private final boolean isDefault;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -6,12 +6,15 @@ import lombok.Getter;
|
|||||||
/**
|
/**
|
||||||
* 华为平台 OAuth 授权范围
|
* 华为平台 OAuth 授权范围
|
||||||
*
|
*
|
||||||
|
* 当前方式未来可能被废弃,建议使用 {@link AuthHuaweiV3Scope}
|
||||||
|
*
|
||||||
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
|
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
|
||||||
* @version 1.0.0
|
* @version 1.0.0
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
@Deprecated
|
||||||
public enum AuthHuaweiScope implements AuthScope {
|
public enum AuthHuaweiScope implements AuthScope {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -0,0 +1,51 @@
|
|||||||
|
package me.zhyd.oauth.enums.scope;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 华为平台 V3 版本 OAuth 授权范围
|
||||||
|
*
|
||||||
|
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 1.16.7
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum AuthHuaweiV3Scope implements AuthScope {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code scope} 含义,以{@code description} 为准
|
||||||
|
*/
|
||||||
|
OPENID("openid", "基础scope,v3必选", true),
|
||||||
|
/**
|
||||||
|
* {@code scope} 含义,以{@code description} 为准
|
||||||
|
*/
|
||||||
|
BASE_PROFILE("https://www.huawei.com/auth/account/base.profile", "获取用户的基本信息", true),
|
||||||
|
MOBILE_NUMBER("https://www.huawei.com/auth/account/mobile.number", "获取用户的手机号", false),
|
||||||
|
ACCOUNTLIST("https://www.huawei.com/auth/account/accountlist", "获取用户的账单列表", false),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 以下两个 scope 不需要经过华为评估和验证
|
||||||
|
*/
|
||||||
|
SCOPE_DRIVE_FILE("https://www.huawei.com/auth/drive.file", "只允许访问由应用程序创建或打开的文件", false),
|
||||||
|
SCOPE_DRIVE_APPDATA("https://www.huawei.com/auth/drive.appdata", "只允许访问由应用程序创建或打开的文件", false),
|
||||||
|
/**
|
||||||
|
* 以下四个 scope 使用前需要向drivekit@huawei.com提交申请
|
||||||
|
* <p>
|
||||||
|
* 参考:https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides-V5/server-dev-0000001050039664-V5#ZH-CN_TOPIC_0000001050039664__section1618418855716
|
||||||
|
*/
|
||||||
|
SCOPE_DRIVE("https://www.huawei.com/auth/drive", "只允许访问由应用程序创建或打开的文件", false),
|
||||||
|
SCOPE_DRIVE_READONLY("https://www.huawei.com/auth/drive.readonly", "只允许访问由应用程序创建或打开的文件", false),
|
||||||
|
SCOPE_DRIVE_METADATA("https://www.huawei.com/auth/drive.metadata", "只允许访问由应用程序创建或打开的文件", false),
|
||||||
|
SCOPE_DRIVE_METADATA_READONLY("https://www.huawei.com/auth/drive.metadata.readonly", "只允许访问由应用程序创建或打开的文件", false),
|
||||||
|
|
||||||
|
|
||||||
|
;
|
||||||
|
;
|
||||||
|
|
||||||
|
private final String scope;
|
||||||
|
private final String description;
|
||||||
|
private final boolean isDefault;
|
||||||
|
|
||||||
|
}
|
||||||
@ -5,6 +5,7 @@ import lombok.Builder;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
import me.zhyd.oauth.utils.StringUtils;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
@ -68,4 +69,8 @@ public class AuthCallback implements Serializable {
|
|||||||
* @see <a href="https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_js/incorporating_sign_in_with_apple_into_other_platforms">error response</a>
|
* @see <a href="https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_js/incorporating_sign_in_with_apple_into_other_platforms">error response</a>
|
||||||
*/
|
*/
|
||||||
private String error;
|
private String error;
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return StringUtils.isEmpty(code) ? auth_code : code;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,4 +66,11 @@ public class AuthToken implements Serializable {
|
|||||||
* Apple附带属性
|
* Apple附带属性
|
||||||
*/
|
*/
|
||||||
private String username;
|
private String username;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新版钉钉附带属性
|
||||||
|
*
|
||||||
|
* @since 1.16.7
|
||||||
|
*/
|
||||||
|
private String corpId;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,12 +34,12 @@ public abstract class AbstractAuthDingtalkRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
return AuthToken.builder().accessCode(authCallback.getCode()).build();
|
return AuthToken.builder().accessCode(authCallback.getCode()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String code = authToken.getAccessCode();
|
String code = authToken.getAccessCode();
|
||||||
JSONObject param = new JSONObject();
|
JSONObject param = new JSONObject();
|
||||||
param.put("tmp_auth_code", code);
|
param.put("tmp_auth_code", code);
|
||||||
|
|||||||
@ -39,7 +39,7 @@ public abstract class AbstractAuthMicrosoftRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
return getToken(accessTokenUrl(authCallback.getCode()));
|
return getToken(accessTokenUrl(authCallback.getCode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ public abstract class AbstractAuthMicrosoftRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String token = authToken.getAccessToken();
|
String token = authToken.getAccessToken();
|
||||||
String tokenType = authToken.getTokenType();
|
String tokenType = authToken.getTokenType();
|
||||||
String jwt = tokenType + " " + token;
|
String jwt = tokenType + " " + token;
|
||||||
@ -111,8 +111,8 @@ public abstract class AbstractAuthMicrosoftRequest extends AuthDefaultRequest {
|
|||||||
* @return AuthResponse
|
* @return AuthResponse
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public AuthResponse refresh(AuthToken authToken) {
|
public AuthResponse<AuthToken> refresh(AuthToken authToken) {
|
||||||
return AuthResponse.builder()
|
return AuthResponse.<AuthToken>builder()
|
||||||
.code(AuthResponseStatus.SUCCESS.getCode())
|
.code(AuthResponseStatus.SUCCESS.getCode())
|
||||||
.data(getToken(refreshTokenUrl(authToken.getRefreshToken())))
|
.data(getToken(refreshTokenUrl(authToken.getRefreshToken())))
|
||||||
.build();
|
.build();
|
||||||
|
|||||||
@ -34,7 +34,7 @@ public abstract class AbstractAuthWeChatEnterpriseRequest extends AuthDefaultReq
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
String response = doGetAuthorizationCode(accessTokenUrl(null));
|
String response = doGetAuthorizationCode(accessTokenUrl(null));
|
||||||
|
|
||||||
JSONObject object = this.checkResponse(response);
|
JSONObject object = this.checkResponse(response);
|
||||||
@ -47,7 +47,7 @@ public abstract class AbstractAuthWeChatEnterpriseRequest extends AuthDefaultReq
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String response = doGetUserInfo(authToken);
|
String response = doGetUserInfo(authToken);
|
||||||
JSONObject object = this.checkResponse(response);
|
JSONObject object = this.checkResponse(response);
|
||||||
|
|
||||||
|
|||||||
@ -30,7 +30,7 @@ public class AuthAfDianRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
Map<String, String> params = new HashMap<>();
|
Map<String, String> params = new HashMap<>();
|
||||||
params.put("grant_type", "authorization_code");
|
params.put("grant_type", "authorization_code");
|
||||||
params.put("client_id", config.getClientId());
|
params.put("client_id", config.getClientId());
|
||||||
@ -44,7 +44,7 @@ public class AuthAfDianRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
return AuthUser.builder()
|
return AuthUser.builder()
|
||||||
.uuid(authToken.getUserId())
|
.uuid(authToken.getUserId())
|
||||||
.gender(AuthUserGender.UNKNOWN)
|
.gender(AuthUserGender.UNKNOWN)
|
||||||
|
|||||||
152
src/main/java/me/zhyd/oauth/request/AuthAlipayCertRequest.java
Normal file
152
src/main/java/me/zhyd/oauth/request/AuthAlipayCertRequest.java
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
package me.zhyd.oauth.request;
|
||||||
|
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.alipay.api.AlipayApiException;
|
||||||
|
import com.alipay.api.AlipayClient;
|
||||||
|
import com.alipay.api.AlipayConfig;
|
||||||
|
import com.alipay.api.DefaultAlipayClient;
|
||||||
|
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
|
||||||
|
import com.alipay.api.request.AlipayUserInfoShareRequest;
|
||||||
|
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
|
||||||
|
import com.alipay.api.response.AlipayUserInfoShareResponse;
|
||||||
|
import me.zhyd.oauth.config.AuthConfig;
|
||||||
|
import me.zhyd.oauth.enums.AuthResponseStatus;
|
||||||
|
import me.zhyd.oauth.enums.AuthUserGender;
|
||||||
|
import me.zhyd.oauth.exception.AuthException;
|
||||||
|
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.StringUtils;
|
||||||
|
import me.zhyd.oauth.utils.UrlBuilder;
|
||||||
|
|
||||||
|
import static me.zhyd.oauth.config.AuthDefaultSource.ALIPAY;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付宝证书模式登录
|
||||||
|
*
|
||||||
|
* @since 1.16.7
|
||||||
|
*/
|
||||||
|
public class AuthAlipayCertRequest extends AuthDefaultRequest {
|
||||||
|
|
||||||
|
private final AlipayClient alipayClient;
|
||||||
|
|
||||||
|
public AuthAlipayCertRequest(AuthConfig config, AlipayConfig alipayConfig) {
|
||||||
|
super(config, ALIPAY);
|
||||||
|
try {
|
||||||
|
this.alipayClient = new DefaultAlipayClient(alipayConfig);
|
||||||
|
} catch (AlipayApiException e) {
|
||||||
|
throw new AuthException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void checkCode(AuthCallback authCallback) {
|
||||||
|
if (StringUtils.isEmpty(authCallback.getAuth_code())) {
|
||||||
|
throw new AuthException(AuthResponseStatus.ILLEGAL_CODE, source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
|
AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
|
||||||
|
request.setGrantType("authorization_code");
|
||||||
|
request.setCode(authCallback.getAuth_code());
|
||||||
|
AlipaySystemOauthTokenResponse response;
|
||||||
|
try {
|
||||||
|
response = this.alipayClient.certificateExecute(request);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new AuthException(e);
|
||||||
|
}
|
||||||
|
if (!response.isSuccess()) {
|
||||||
|
throw new AuthException(response.getSubMsg());
|
||||||
|
}
|
||||||
|
return AuthToken.builder()
|
||||||
|
.accessToken(response.getAccessToken())
|
||||||
|
.uid(response.getUserId())
|
||||||
|
.expireIn(Integer.parseInt(response.getExpiresIn()))
|
||||||
|
.refreshToken(response.getRefreshToken())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新access token (续期)
|
||||||
|
*
|
||||||
|
* @param authToken 登录成功后返回的Token信息
|
||||||
|
* @return AuthResponse
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AuthResponse<AuthToken> refresh(AuthToken authToken) {
|
||||||
|
AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
|
||||||
|
request.setGrantType("refresh_token");
|
||||||
|
request.setRefreshToken(authToken.getRefreshToken());
|
||||||
|
AlipaySystemOauthTokenResponse response = null;
|
||||||
|
try {
|
||||||
|
response = this.alipayClient.certificateExecute(request);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new AuthException(e);
|
||||||
|
}
|
||||||
|
if (!response.isSuccess()) {
|
||||||
|
throw new AuthException(response.getSubMsg());
|
||||||
|
}
|
||||||
|
return AuthResponse.<AuthToken>builder()
|
||||||
|
.code(AuthResponseStatus.SUCCESS.getCode())
|
||||||
|
.data(AuthToken.builder()
|
||||||
|
.accessToken(response.getAccessToken())
|
||||||
|
.uid(response.getUserId())
|
||||||
|
.expireIn(Integer.parseInt(response.getExpiresIn()))
|
||||||
|
.refreshToken(response.getRefreshToken())
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
|
String accessToken = authToken.getAccessToken();
|
||||||
|
AlipayUserInfoShareRequest request = new AlipayUserInfoShareRequest();
|
||||||
|
AlipayUserInfoShareResponse response = null;
|
||||||
|
try {
|
||||||
|
response = this.alipayClient.certificateExecute(request, accessToken);
|
||||||
|
} catch (AlipayApiException e) {
|
||||||
|
throw new AuthException(e.getErrMsg(), e);
|
||||||
|
}
|
||||||
|
if (!response.isSuccess()) {
|
||||||
|
throw new AuthException(response.getSubMsg());
|
||||||
|
}
|
||||||
|
|
||||||
|
String province = response.getProvince(), city = response.getCity();
|
||||||
|
String location = String.format("%s %s", StringUtils.isEmpty(province) ? "" : province, StringUtils.isEmpty(city) ? "" : city);
|
||||||
|
|
||||||
|
return AuthUser.builder()
|
||||||
|
.rawUserInfo(JSONObject.parseObject(JSONObject.toJSONString(response)))
|
||||||
|
.uuid(response.getOpenId())
|
||||||
|
.username(StringUtils.isEmpty(response.getUserName()) ? response.getNickName() : response.getUserName())
|
||||||
|
.nickname(response.getNickName())
|
||||||
|
.avatar(response.getAvatar())
|
||||||
|
.location(location)
|
||||||
|
.gender(AuthUserGender.getRealGender(response.getGender()))
|
||||||
|
.token(authToken)
|
||||||
|
.source(source.toString())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state}
|
||||||
|
*
|
||||||
|
* @param state state 验证授权流程的参数,可以防止csrf
|
||||||
|
* @return 返回授权地址
|
||||||
|
* @since 1.9.3
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String authorize(String state) {
|
||||||
|
return UrlBuilder.fromBaseUrl(source.authorize())
|
||||||
|
.queryParam("app_id", config.getClientId())
|
||||||
|
.queryParam("scope", "auth_user")
|
||||||
|
.queryParam("redirect_uri", config.getRedirectUri())
|
||||||
|
.queryParam("state", getRealState(state))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -26,7 +26,7 @@ import me.zhyd.oauth.utils.UrlBuilder;
|
|||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付宝登录
|
* 支付宝公钥模式登录
|
||||||
*
|
*
|
||||||
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
|
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
|
||||||
* @since 1.0.1
|
* @since 1.0.1
|
||||||
@ -147,7 +147,7 @@ public class AuthAlipayRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
|
AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
|
||||||
request.setGrantType("authorization_code");
|
request.setGrantType("authorization_code");
|
||||||
request.setCode(authCallback.getAuth_code());
|
request.setCode(authCallback.getAuth_code());
|
||||||
@ -175,7 +175,7 @@ public class AuthAlipayRequest extends AuthDefaultRequest {
|
|||||||
* @return AuthResponse
|
* @return AuthResponse
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public AuthResponse refresh(AuthToken authToken) {
|
public AuthResponse<AuthToken> refresh(AuthToken authToken) {
|
||||||
AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
|
AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
|
||||||
request.setGrantType("refresh_token");
|
request.setGrantType("refresh_token");
|
||||||
request.setRefreshToken(authToken.getRefreshToken());
|
request.setRefreshToken(authToken.getRefreshToken());
|
||||||
@ -188,7 +188,7 @@ public class AuthAlipayRequest extends AuthDefaultRequest {
|
|||||||
if (!response.isSuccess()) {
|
if (!response.isSuccess()) {
|
||||||
throw new AuthException(response.getSubMsg());
|
throw new AuthException(response.getSubMsg());
|
||||||
}
|
}
|
||||||
return AuthResponse.builder()
|
return AuthResponse.<AuthToken>builder()
|
||||||
.code(AuthResponseStatus.SUCCESS.getCode())
|
.code(AuthResponseStatus.SUCCESS.getCode())
|
||||||
.data(AuthToken.builder()
|
.data(AuthToken.builder()
|
||||||
.accessToken(response.getAccessToken())
|
.accessToken(response.getAccessToken())
|
||||||
@ -200,7 +200,7 @@ public class AuthAlipayRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String accessToken = authToken.getAccessToken();
|
String accessToken = authToken.getAccessToken();
|
||||||
AlipayUserInfoShareRequest request = new AlipayUserInfoShareRequest();
|
AlipayUserInfoShareRequest request = new AlipayUserInfoShareRequest();
|
||||||
AlipayUserInfoShareResponse response = null;
|
AlipayUserInfoShareResponse response = null;
|
||||||
|
|||||||
@ -26,7 +26,7 @@ public class AuthAliyunRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
String response = doPostAuthorizationCode(authCallback.getCode());
|
String response = doPostAuthorizationCode(authCallback.getCode());
|
||||||
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
||||||
return AuthToken.builder()
|
return AuthToken.builder()
|
||||||
@ -39,7 +39,7 @@ public class AuthAliyunRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String userInfo = doGetUserInfo(authToken);
|
String userInfo = doGetUserInfo(authToken);
|
||||||
JSONObject object = JSONObject.parseObject(userInfo);
|
JSONObject object = JSONObject.parseObject(userInfo);
|
||||||
return AuthUser.builder()
|
return AuthUser.builder()
|
||||||
|
|||||||
@ -50,15 +50,16 @@ public class AuthAmazonRequest extends AuthDefaultRequest {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String authorize(String state) {
|
public String authorize(String state) {
|
||||||
|
String realState = getRealState(state);
|
||||||
UrlBuilder builder = UrlBuilder.fromBaseUrl(source.authorize())
|
UrlBuilder builder = UrlBuilder.fromBaseUrl(source.authorize())
|
||||||
.queryParam("client_id", config.getClientId())
|
.queryParam("client_id", config.getClientId())
|
||||||
.queryParam("scope", this.getScopes(" ", true, AuthScopeUtils.getDefaultScopes(AuthAmazonScope.values())))
|
.queryParam("scope", this.getScopes(" ", true, AuthScopeUtils.getDefaultScopes(AuthAmazonScope.values())))
|
||||||
.queryParam("redirect_uri", config.getRedirectUri())
|
.queryParam("redirect_uri", config.getRedirectUri())
|
||||||
.queryParam("response_type", "code")
|
.queryParam("response_type", "code")
|
||||||
.queryParam("state", getRealState(state));
|
.queryParam("state", realState);
|
||||||
|
|
||||||
if (config.isPkce()) {
|
if (config.isPkce()) {
|
||||||
String cacheKey = this.source.getName().concat(":code_verifier:").concat(config.getClientId());
|
String cacheKey = this.source.getName().concat(":code_verifier:").concat(realState);
|
||||||
String codeVerifier = PkceUtil.generateCodeVerifier();
|
String codeVerifier = PkceUtil.generateCodeVerifier();
|
||||||
String codeChallengeMethod = "S256";
|
String codeChallengeMethod = "S256";
|
||||||
String codeChallenge = PkceUtil.generateCodeChallenge(codeChallengeMethod, codeVerifier);
|
String codeChallenge = PkceUtil.generateCodeChallenge(codeChallengeMethod, codeVerifier);
|
||||||
@ -77,7 +78,7 @@ public class AuthAmazonRequest extends AuthDefaultRequest {
|
|||||||
* @return access token
|
* @return access token
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
Map<String, String> form = new HashMap<>(9);
|
Map<String, String> form = new HashMap<>(9);
|
||||||
form.put("grant_type", "authorization_code");
|
form.put("grant_type", "authorization_code");
|
||||||
form.put("code", authCallback.getCode());
|
form.put("code", authCallback.getCode());
|
||||||
@ -86,7 +87,7 @@ public class AuthAmazonRequest extends AuthDefaultRequest {
|
|||||||
form.put("client_secret", config.getClientSecret());
|
form.put("client_secret", config.getClientSecret());
|
||||||
|
|
||||||
if (config.isPkce()) {
|
if (config.isPkce()) {
|
||||||
String cacheKey = this.source.getName().concat(":code_verifier:").concat(config.getClientId());
|
String cacheKey = this.source.getName().concat(":code_verifier:").concat(authCallback.getState());
|
||||||
String codeVerifier = this.authStateCache.get(cacheKey);
|
String codeVerifier = this.authStateCache.get(cacheKey);
|
||||||
form.put("code_verifier", codeVerifier);
|
form.put("code_verifier", codeVerifier);
|
||||||
}
|
}
|
||||||
@ -94,13 +95,13 @@ public class AuthAmazonRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthResponse refresh(AuthToken authToken) {
|
public AuthResponse<AuthToken> refresh(AuthToken authToken) {
|
||||||
Map<String, String> form = new HashMap<>(7);
|
Map<String, String> form = new HashMap<>(7);
|
||||||
form.put("grant_type", "refresh_token");
|
form.put("grant_type", "refresh_token");
|
||||||
form.put("refresh_token", authToken.getRefreshToken());
|
form.put("refresh_token", authToken.getRefreshToken());
|
||||||
form.put("client_id", config.getClientId());
|
form.put("client_id", config.getClientId());
|
||||||
form.put("client_secret", config.getClientSecret());
|
form.put("client_secret", config.getClientSecret());
|
||||||
return AuthResponse.builder()
|
return AuthResponse.<AuthToken>builder()
|
||||||
.code(AuthResponseStatus.SUCCESS.getCode())
|
.code(AuthResponseStatus.SUCCESS.getCode())
|
||||||
.data(getToken(form, this.source.refresh()))
|
.data(getToken(form, this.source.refresh()))
|
||||||
.build();
|
.build();
|
||||||
@ -140,7 +141,7 @@ public class AuthAmazonRequest extends AuthDefaultRequest {
|
|||||||
* @return AuthUser
|
* @return AuthUser
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String accessToken = authToken.getAccessToken();
|
String accessToken = authToken.getAccessToken();
|
||||||
this.checkToken(accessToken);
|
this.checkToken(accessToken);
|
||||||
|
|
||||||
|
|||||||
@ -50,7 +50,7 @@ public class AuthAppleRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
if (!StringUtils.isEmpty(authCallback.getError())) {
|
if (!StringUtils.isEmpty(authCallback.getError())) {
|
||||||
throw new AuthException(authCallback.getError());
|
throw new AuthException(authCallback.getError());
|
||||||
}
|
}
|
||||||
@ -76,7 +76,7 @@ public class AuthAppleRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
Base64.Decoder urlDecoder = Base64.getUrlDecoder();
|
Base64.Decoder urlDecoder = Base64.getUrlDecoder();
|
||||||
String[] idToken = authToken.getIdToken().split("\\.");
|
String[] idToken = authToken.getIdToken().split("\\.");
|
||||||
String payload = new String(urlDecoder.decode(idToken[1]));
|
String payload = new String(urlDecoder.decode(idToken[1]));
|
||||||
|
|||||||
@ -34,7 +34,7 @@ public class AuthBaiduRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
String response = doPostAuthorizationCode(authCallback.getCode());
|
String response = doPostAuthorizationCode(authCallback.getCode());
|
||||||
return getAuthToken(response);
|
return getAuthToken(response);
|
||||||
}
|
}
|
||||||
@ -48,7 +48,7 @@ public class AuthBaiduRequest extends AuthDefaultRequest {
|
|||||||
* @return AuthUser
|
* @return AuthUser
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String userInfo = doGetUserInfo(authToken);
|
String userInfo = doGetUserInfo(authToken);
|
||||||
JSONObject object = JSONObject.parseObject(userInfo);
|
JSONObject object = JSONObject.parseObject(userInfo);
|
||||||
this.checkResponse(object);
|
this.checkResponse(object);
|
||||||
@ -81,7 +81,7 @@ public class AuthBaiduRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthResponse refresh(AuthToken authToken) {
|
public AuthResponse<AuthToken> refresh(AuthToken authToken) {
|
||||||
String refreshUrl = UrlBuilder.fromBaseUrl(this.source.refresh())
|
String refreshUrl = UrlBuilder.fromBaseUrl(this.source.refresh())
|
||||||
.queryParam("grant_type", "refresh_token")
|
.queryParam("grant_type", "refresh_token")
|
||||||
.queryParam("refresh_token", authToken.getRefreshToken())
|
.queryParam("refresh_token", authToken.getRefreshToken())
|
||||||
@ -89,7 +89,7 @@ public class AuthBaiduRequest extends AuthDefaultRequest {
|
|||||||
.queryParam("client_secret", this.config.getClientSecret())
|
.queryParam("client_secret", this.config.getClientSecret())
|
||||||
.build();
|
.build();
|
||||||
String response = new HttpUtils(config.getHttpConfig()).get(refreshUrl).getBody();
|
String response = new HttpUtils(config.getHttpConfig()).get(refreshUrl).getBody();
|
||||||
return AuthResponse.builder()
|
return AuthResponse.<AuthToken>builder()
|
||||||
.code(AuthResponseStatus.SUCCESS.getCode())
|
.code(AuthResponseStatus.SUCCESS.getCode())
|
||||||
.data(this.getAuthToken(response))
|
.data(this.getAuthToken(response))
|
||||||
.build();
|
.build();
|
||||||
|
|||||||
@ -30,7 +30,7 @@ public class AuthCodingRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
String response = doGetAuthorizationCode(authCallback.getCode());
|
String response = doGetAuthorizationCode(authCallback.getCode());
|
||||||
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
||||||
this.checkResponse(accessTokenObject);
|
this.checkResponse(accessTokenObject);
|
||||||
@ -42,7 +42,7 @@ public class AuthCodingRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String response = doGetUserInfo(authToken);
|
String response = doGetUserInfo(authToken);
|
||||||
JSONObject object = JSONObject.parseObject(response);
|
JSONObject object = JSONObject.parseObject(response);
|
||||||
this.checkResponse(object);
|
this.checkResponse(object);
|
||||||
|
|||||||
@ -28,7 +28,7 @@ public class AuthCsdnRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
String response = doPostAuthorizationCode(authCallback.getCode());
|
String response = doPostAuthorizationCode(authCallback.getCode());
|
||||||
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
||||||
this.checkResponse(accessTokenObject);
|
this.checkResponse(accessTokenObject);
|
||||||
@ -36,7 +36,7 @@ public class AuthCsdnRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String response = doGetUserInfo(authToken);
|
String response = doGetUserInfo(authToken);
|
||||||
JSONObject object = JSONObject.parseObject(response);
|
JSONObject object = JSONObject.parseObject(response);
|
||||||
this.checkResponse(object);
|
this.checkResponse(object);
|
||||||
|
|||||||
@ -43,25 +43,6 @@ public abstract class AuthDefaultRequest implements AuthRequest {
|
|||||||
this.checkConfig(config);
|
this.checkConfig(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取access token
|
|
||||||
*
|
|
||||||
* @param authCallback 授权成功后的回调参数
|
|
||||||
* @return token
|
|
||||||
* @see AuthDefaultRequest#authorize()
|
|
||||||
* @see AuthDefaultRequest#authorize(String)
|
|
||||||
*/
|
|
||||||
protected abstract AuthToken getAccessToken(AuthCallback authCallback);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 使用token换取用户信息
|
|
||||||
*
|
|
||||||
* @param authToken token信息
|
|
||||||
* @return 用户信息
|
|
||||||
* @see AuthDefaultRequest#getAccessToken(AuthCallback)
|
|
||||||
*/
|
|
||||||
protected abstract AuthUser getUserInfo(AuthToken authToken);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 统一的登录入口。当通过{@link AuthDefaultRequest#authorize(String)}授权成功后,会跳转到调用方的相关回调方法中
|
* 统一的登录入口。当通过{@link AuthDefaultRequest#authorize(String)}授权成功后,会跳转到调用方的相关回调方法中
|
||||||
* 方法的入参可以使用{@code AuthCallback},{@code AuthCallback}类中封装好了OAuth2授权回调所需要的参数
|
* 方法的入参可以使用{@code AuthCallback},{@code AuthCallback}类中封装好了OAuth2授权回调所需要的参数
|
||||||
@ -70,7 +51,7 @@ public abstract class AuthDefaultRequest implements AuthRequest {
|
|||||||
* @return AuthResponse
|
* @return AuthResponse
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public AuthResponse login(AuthCallback authCallback) {
|
public AuthResponse<AuthUser> login(AuthCallback authCallback) {
|
||||||
try {
|
try {
|
||||||
checkCode(authCallback);
|
checkCode(authCallback);
|
||||||
if (!config.isIgnoreCheckState()) {
|
if (!config.isIgnoreCheckState()) {
|
||||||
@ -79,7 +60,7 @@ public abstract class AuthDefaultRequest implements AuthRequest {
|
|||||||
|
|
||||||
AuthToken authToken = this.getAccessToken(authCallback);
|
AuthToken authToken = this.getAccessToken(authCallback);
|
||||||
AuthUser user = this.getUserInfo(authToken);
|
AuthUser user = this.getUserInfo(authToken);
|
||||||
return AuthResponse.builder().code(AuthResponseStatus.SUCCESS.getCode()).data(user).build();
|
return AuthResponse.<AuthUser>builder().code(AuthResponseStatus.SUCCESS.getCode()).data(user).build();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.error("Failed to login with oauth authorization.", e);
|
Log.error("Failed to login with oauth authorization.", e);
|
||||||
return this.responseError(e);
|
return this.responseError(e);
|
||||||
@ -96,7 +77,7 @@ public abstract class AuthDefaultRequest implements AuthRequest {
|
|||||||
* @param e 具体的异常
|
* @param e 具体的异常
|
||||||
* @return AuthResponse
|
* @return AuthResponse
|
||||||
*/
|
*/
|
||||||
AuthResponse responseError(Exception e) {
|
AuthResponse<AuthUser> responseError(Exception e) {
|
||||||
int errorCode = AuthResponseStatus.FAILURE.getCode();
|
int errorCode = AuthResponseStatus.FAILURE.getCode();
|
||||||
String errorMsg = e.getMessage();
|
String errorMsg = e.getMessage();
|
||||||
if (e instanceof AuthException) {
|
if (e instanceof AuthException) {
|
||||||
@ -106,7 +87,7 @@ public abstract class AuthDefaultRequest implements AuthRequest {
|
|||||||
errorMsg = authException.getErrorMsg();
|
errorMsg = authException.getErrorMsg();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return AuthResponse.builder().code(errorCode).msg(errorMsg).build();
|
return AuthResponse.<AuthUser>builder().code(errorCode).msg(errorMsg).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
108
src/main/java/me/zhyd/oauth/request/AuthDingTalkV2Request.java
Normal file
108
src/main/java/me/zhyd/oauth/request/AuthDingTalkV2Request.java
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
package me.zhyd.oauth.request;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.xkcoding.http.support.HttpHeader;
|
||||||
|
import me.zhyd.oauth.cache.AuthStateCache;
|
||||||
|
import me.zhyd.oauth.config.AuthConfig;
|
||||||
|
import me.zhyd.oauth.config.AuthDefaultSource;
|
||||||
|
import me.zhyd.oauth.enums.scope.AuthDingTalkScope;
|
||||||
|
import me.zhyd.oauth.exception.AuthException;
|
||||||
|
import me.zhyd.oauth.model.AuthCallback;
|
||||||
|
import me.zhyd.oauth.model.AuthToken;
|
||||||
|
import me.zhyd.oauth.model.AuthUser;
|
||||||
|
import me.zhyd.oauth.utils.AuthScopeUtils;
|
||||||
|
import me.zhyd.oauth.utils.HttpUtils;
|
||||||
|
import me.zhyd.oauth.utils.UrlBuilder;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新版钉钉二维码登录
|
||||||
|
*
|
||||||
|
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
|
||||||
|
* @since 1.16.7
|
||||||
|
*/
|
||||||
|
public class AuthDingTalkV2Request extends AuthDefaultRequest {
|
||||||
|
|
||||||
|
public AuthDingTalkV2Request(AuthConfig config) {
|
||||||
|
super(config, AuthDefaultSource.DINGTALK_V2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthDingTalkV2Request(AuthConfig config, AuthStateCache authStateCache) {
|
||||||
|
super(config, AuthDefaultSource.DINGTALK_V2, authStateCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String authorize(String state) {
|
||||||
|
return UrlBuilder.fromBaseUrl(source.authorize())
|
||||||
|
.queryParam("response_type", "code")
|
||||||
|
.queryParam("client_id", config.getClientId())
|
||||||
|
.queryParam("scope", this.getScopes(",", true, AuthScopeUtils.getDefaultScopes(AuthDingTalkScope.values())))
|
||||||
|
.queryParam("redirect_uri", config.getRedirectUri())
|
||||||
|
.queryParam("prompt", "consent")
|
||||||
|
.queryParam("org_type", config.getDingTalkOrgType())
|
||||||
|
.queryParam("corpId", config.getDingTalkCorpId())
|
||||||
|
.queryParam("exclusiveLogin", config.isDingTalkExclusiveLogin())
|
||||||
|
.queryParam("exclusiveCorpId", config.getDingTalkExclusiveCorpId())
|
||||||
|
.queryParam("state", getRealState(state))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
|
Map<String, String> params = new HashMap<>();
|
||||||
|
params.put("grantType", "authorization_code");
|
||||||
|
params.put("clientId", config.getClientId());
|
||||||
|
params.put("clientSecret", config.getClientSecret());
|
||||||
|
params.put("code", authCallback.getCode());
|
||||||
|
String response = new HttpUtils(config.getHttpConfig()).post(this.source.accessToken(), JSONObject.toJSONString(params)).getBody();
|
||||||
|
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
||||||
|
if (!accessTokenObject.containsKey("accessToken")) {
|
||||||
|
throw new AuthException(JSONObject.toJSONString(response), source);
|
||||||
|
}
|
||||||
|
return AuthToken.builder()
|
||||||
|
.accessToken(accessTokenObject.getString("accessToken"))
|
||||||
|
.refreshToken(accessTokenObject.getString("refreshToken"))
|
||||||
|
.expireIn(accessTokenObject.getIntValue("expireIn"))
|
||||||
|
.corpId(accessTokenObject.getString("corpId"))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
|
HttpHeader header = new HttpHeader();
|
||||||
|
header.add("x-acs-dingtalk-access-token", authToken.getAccessToken());
|
||||||
|
|
||||||
|
String response = new HttpUtils(config.getHttpConfig()).get(this.source.userInfo(), null, header, false).getBody();
|
||||||
|
JSONObject object = JSONObject.parseObject(response);
|
||||||
|
|
||||||
|
authToken.setOpenId(object.getString("openId"));
|
||||||
|
authToken.setUnionId(object.getString("unionId"));
|
||||||
|
return AuthUser.builder()
|
||||||
|
.rawUserInfo(object)
|
||||||
|
.uuid(object.getString("unionId"))
|
||||||
|
.username(object.getString("nick"))
|
||||||
|
.nickname(object.getString("nick"))
|
||||||
|
.avatar(object.getString("avatarUrl"))
|
||||||
|
.snapshotUser(object.getBooleanValue("visitor"))
|
||||||
|
.token(authToken)
|
||||||
|
.source(source.toString())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回获取accessToken的url
|
||||||
|
*
|
||||||
|
* @param code 授权码
|
||||||
|
* @return 返回获取accessToken的url
|
||||||
|
*/
|
||||||
|
protected String accessTokenUrl(String code) {
|
||||||
|
return UrlBuilder.fromBaseUrl(source.accessToken())
|
||||||
|
.queryParam("code", code)
|
||||||
|
.queryParam("clientId", config.getClientId())
|
||||||
|
.queryParam("clientSecret", config.getClientSecret())
|
||||||
|
.queryParam("grantType", "authorization_code")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -34,16 +34,17 @@ public class AuthDouyinRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
return this.getToken(accessTokenUrl(authCallback.getCode()));
|
return this.getToken(accessTokenUrl(authCallback.getCode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String response = doGetUserInfo(authToken);
|
String response = doGetUserInfo(authToken);
|
||||||
JSONObject userInfoObject = JSONObject.parseObject(response);
|
JSONObject userInfoObject = JSONObject.parseObject(response);
|
||||||
this.checkResponse(userInfoObject);
|
this.checkResponse(userInfoObject);
|
||||||
JSONObject object = userInfoObject.getJSONObject("data");
|
JSONObject object = userInfoObject.getJSONObject("data");
|
||||||
|
authToken.setUnionId(object.getString("union_id"));
|
||||||
return AuthUser.builder()
|
return AuthUser.builder()
|
||||||
.rawUserInfo(object)
|
.rawUserInfo(object)
|
||||||
.uuid(object.getString("union_id"))
|
.uuid(object.getString("union_id"))
|
||||||
@ -59,8 +60,8 @@ public class AuthDouyinRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthResponse refresh(AuthToken oldToken) {
|
public AuthResponse<AuthToken> refresh(AuthToken oldToken) {
|
||||||
return AuthResponse.builder()
|
return AuthResponse.<AuthToken>builder()
|
||||||
.code(AuthResponseStatus.SUCCESS.getCode())
|
.code(AuthResponseStatus.SUCCESS.getCode())
|
||||||
.data(getToken(refreshTokenUrl(oldToken.getRefreshToken())))
|
.data(getToken(refreshTokenUrl(oldToken.getRefreshToken())))
|
||||||
.build();
|
.build();
|
||||||
@ -96,6 +97,7 @@ public class AuthDouyinRequest extends AuthDefaultRequest {
|
|||||||
.openId(dataObj.getString("open_id"))
|
.openId(dataObj.getString("open_id"))
|
||||||
.expireIn(dataObj.getIntValue("expires_in"))
|
.expireIn(dataObj.getIntValue("expires_in"))
|
||||||
.refreshToken(dataObj.getString("refresh_token"))
|
.refreshToken(dataObj.getString("refresh_token"))
|
||||||
|
.refreshTokenExpireIn(dataObj.getIntValue("refresh_expires_in"))
|
||||||
.scope(dataObj.getString("scope"))
|
.scope(dataObj.getString("scope"))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,7 +44,7 @@ public class AuthElemeRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
Map<String, String> form = new HashMap<>(7);
|
Map<String, String> form = new HashMap<>(7);
|
||||||
form.put("client_id", config.getClientId());
|
form.put("client_id", config.getClientId());
|
||||||
form.put("redirect_uri", config.getRedirectUri());
|
form.put("redirect_uri", config.getRedirectUri());
|
||||||
@ -66,7 +66,7 @@ public class AuthElemeRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
Map<String, Object> parameters = new HashMap<>(4);
|
Map<String, Object> parameters = new HashMap<>(4);
|
||||||
// 获取商户账号信息的API接口名称
|
// 获取商户账号信息的API接口名称
|
||||||
String action = "eleme.user.getUser";
|
String action = "eleme.user.getUser";
|
||||||
@ -117,7 +117,7 @@ public class AuthElemeRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthResponse refresh(AuthToken oldToken) {
|
public AuthResponse<AuthToken> refresh(AuthToken oldToken) {
|
||||||
Map<String, String> form = new HashMap<>(4);
|
Map<String, String> form = new HashMap<>(4);
|
||||||
form.put("refresh_token", oldToken.getRefreshToken());
|
form.put("refresh_token", oldToken.getRefreshToken());
|
||||||
form.put("grant_type", "refresh_token");
|
form.put("grant_type", "refresh_token");
|
||||||
@ -129,7 +129,7 @@ public class AuthElemeRequest extends AuthDefaultRequest {
|
|||||||
|
|
||||||
this.checkResponse(object);
|
this.checkResponse(object);
|
||||||
|
|
||||||
return AuthResponse.builder()
|
return AuthResponse.<AuthToken>builder()
|
||||||
.code(AuthResponseStatus.SUCCESS.getCode())
|
.code(AuthResponseStatus.SUCCESS.getCode())
|
||||||
.data(AuthToken.builder()
|
.data(AuthToken.builder()
|
||||||
.accessToken(object.getString("access_token"))
|
.accessToken(object.getString("access_token"))
|
||||||
|
|||||||
@ -32,7 +32,7 @@ public class AuthFacebookRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
String response = doPostAuthorizationCode(authCallback.getCode());
|
String response = doPostAuthorizationCode(authCallback.getCode());
|
||||||
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
||||||
this.checkResponse(accessTokenObject);
|
this.checkResponse(accessTokenObject);
|
||||||
@ -44,7 +44,7 @@ public class AuthFacebookRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String userInfo = doGetUserInfo(authToken);
|
String userInfo = doGetUserInfo(authToken);
|
||||||
JSONObject object = JSONObject.parseObject(userInfo);
|
JSONObject object = JSONObject.parseObject(userInfo);
|
||||||
this.checkResponse(object);
|
this.checkResponse(object);
|
||||||
|
|||||||
@ -66,7 +66,7 @@ public class AuthFeishuRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
JSONObject requestObject = new JSONObject();
|
JSONObject requestObject = new JSONObject();
|
||||||
requestObject.put("app_access_token", this.getAppAccessToken());
|
requestObject.put("app_access_token", this.getAppAccessToken());
|
||||||
requestObject.put("grant_type", "authorization_code");
|
requestObject.put("grant_type", "authorization_code");
|
||||||
@ -76,7 +76,7 @@ public class AuthFeishuRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String accessToken = authToken.getAccessToken();
|
String accessToken = authToken.getAccessToken();
|
||||||
String response = new HttpUtils(config.getHttpConfig()).get(source.userInfo(), null, new HttpHeader()
|
String response = new HttpUtils(config.getHttpConfig()).get(source.userInfo(), null, new HttpHeader()
|
||||||
.add("Content-Type", "application/json")
|
.add("Content-Type", "application/json")
|
||||||
@ -98,12 +98,12 @@ public class AuthFeishuRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthResponse refresh(AuthToken authToken) {
|
public AuthResponse<AuthToken> refresh(AuthToken authToken) {
|
||||||
JSONObject requestObject = new JSONObject();
|
JSONObject requestObject = new JSONObject();
|
||||||
requestObject.put("app_access_token", this.getAppAccessToken());
|
requestObject.put("app_access_token", this.getAppAccessToken());
|
||||||
requestObject.put("grant_type", "refresh_token");
|
requestObject.put("grant_type", "refresh_token");
|
||||||
requestObject.put("refresh_token", authToken.getRefreshToken());
|
requestObject.put("refresh_token", authToken.getRefreshToken());
|
||||||
return AuthResponse.builder()
|
return AuthResponse.<AuthToken>builder()
|
||||||
.code(AuthResponseStatus.SUCCESS.getCode())
|
.code(AuthResponseStatus.SUCCESS.getCode())
|
||||||
.data(getToken(requestObject, this.source.refresh()))
|
.data(getToken(requestObject, this.source.refresh()))
|
||||||
.build();
|
.build();
|
||||||
|
|||||||
118
src/main/java/me/zhyd/oauth/request/AuthFigmaRequest.java
Normal file
118
src/main/java/me/zhyd/oauth/request/AuthFigmaRequest.java
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
package me.zhyd.oauth.request;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.xkcoding.http.support.HttpHeader;
|
||||||
|
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.enums.scope.AuthFigmaScope;
|
||||||
|
import me.zhyd.oauth.exception.AuthException;
|
||||||
|
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.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Figma登录
|
||||||
|
* @author xiangqian
|
||||||
|
* @since 1.16.6
|
||||||
|
*/
|
||||||
|
public class AuthFigmaRequest extends AuthDefaultRequest {
|
||||||
|
public AuthFigmaRequest(AuthConfig config) {
|
||||||
|
super(config, AuthDefaultSource.FIGMA);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthFigmaRequest(AuthConfig config, AuthStateCache authStateCache) {
|
||||||
|
super(config, AuthDefaultSource.FIGMA, authStateCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String authorize(String state) {
|
||||||
|
return UrlBuilder.fromBaseUrl(super.authorize(state))
|
||||||
|
.queryParam("scope", this.getScopes(",", true, AuthScopeUtils.getDefaultScopes(AuthFigmaScope.values())))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
|
HttpHeader header = new HttpHeader()
|
||||||
|
.add("content-type", "application/x-www-form-urlencoded")
|
||||||
|
.add("Authorization", "Basic " + Base64Utils.encode(config.getClientId().concat(":").concat(config.getClientSecret())));
|
||||||
|
|
||||||
|
String response = new HttpUtils(config.getHttpConfig()).post(super.accessTokenUrl(authCallback.getCode()), null, header, true).getBody();
|
||||||
|
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
||||||
|
|
||||||
|
this.checkResponse(accessTokenObject);
|
||||||
|
|
||||||
|
return AuthToken.builder()
|
||||||
|
.accessToken(accessTokenObject.getString("access_token"))
|
||||||
|
.refreshToken(accessTokenObject.getString("refresh_token"))
|
||||||
|
.scope(accessTokenObject.getString("scope"))
|
||||||
|
.userId(accessTokenObject.getString("user_id"))
|
||||||
|
.expireIn(accessTokenObject.getIntValue("expires_in"))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AuthResponse<AuthToken> refresh(AuthToken authToken) {
|
||||||
|
HttpHeader header = new HttpHeader().add("content-type", "application/x-www-form-urlencoded");
|
||||||
|
String response = new HttpUtils(config.getHttpConfig()).post(this.refreshTokenUrl(authToken.getRefreshToken()), null, header, false).getBody();
|
||||||
|
JSONObject dataObj = JSONObject.parseObject(response);
|
||||||
|
|
||||||
|
this.checkResponse(dataObj);
|
||||||
|
|
||||||
|
return AuthResponse.<AuthToken>builder()
|
||||||
|
.code(AuthResponseStatus.SUCCESS.getCode())
|
||||||
|
.data(AuthToken.builder()
|
||||||
|
.accessToken(dataObj.getString("access_token"))
|
||||||
|
.openId(dataObj.getString("open_id"))
|
||||||
|
.expireIn(dataObj.getIntValue("expires_in"))
|
||||||
|
.refreshToken(dataObj.getString("refresh_token"))
|
||||||
|
.scope(dataObj.getString("scope"))
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String refreshTokenUrl(String refreshToken) {
|
||||||
|
return UrlBuilder.fromBaseUrl(source.refresh())
|
||||||
|
.queryParam("client_id", config.getClientId())
|
||||||
|
.queryParam("client_secret", config.getClientSecret())
|
||||||
|
.queryParam("refresh_token", refreshToken)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
|
HttpHeader header = new HttpHeader().add("Authorization", "Bearer " + authToken.getAccessToken());
|
||||||
|
String response = new HttpUtils(config.getHttpConfig()).get(super.userInfoUrl(authToken), null, header, false).getBody();
|
||||||
|
JSONObject dataObj = JSONObject.parseObject(response);
|
||||||
|
|
||||||
|
this.checkResponse(dataObj);
|
||||||
|
|
||||||
|
return AuthUser.builder()
|
||||||
|
.rawUserInfo(dataObj)
|
||||||
|
.uuid(dataObj.getString("id"))
|
||||||
|
.username(dataObj.getString("handle"))
|
||||||
|
.avatar(dataObj.getString("img_url"))
|
||||||
|
.email(dataObj.getString("email"))
|
||||||
|
.token(authToken)
|
||||||
|
.source(source.toString())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验响应结果
|
||||||
|
*
|
||||||
|
* @param object 接口返回的结果
|
||||||
|
*/
|
||||||
|
private void checkResponse(JSONObject object) {
|
||||||
|
if (object.containsKey("error")) {
|
||||||
|
throw new AuthException(object.getString("error") + ":" + object.getString("message"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -30,7 +30,7 @@ public class AuthGiteeRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
String response = doPostAuthorizationCode(authCallback.getCode());
|
String response = doPostAuthorizationCode(authCallback.getCode());
|
||||||
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
||||||
this.checkResponse(accessTokenObject);
|
this.checkResponse(accessTokenObject);
|
||||||
@ -44,7 +44,7 @@ public class AuthGiteeRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String userInfo = doGetUserInfo(authToken);
|
String userInfo = doGetUserInfo(authToken);
|
||||||
JSONObject object = JSONObject.parseObject(userInfo);
|
JSONObject object = JSONObject.parseObject(userInfo);
|
||||||
this.checkResponse(object);
|
this.checkResponse(object);
|
||||||
|
|||||||
@ -35,7 +35,7 @@ public class AuthGithubRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
String response = doPostAuthorizationCode(authCallback.getCode());
|
String response = doPostAuthorizationCode(authCallback.getCode());
|
||||||
Map<String, String> res = GlobalAuthUtils.parseStringToMap(response);
|
Map<String, String> res = GlobalAuthUtils.parseStringToMap(response);
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ public class AuthGithubRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
HttpHeader header = new HttpHeader();
|
HttpHeader header = new HttpHeader();
|
||||||
header.add("Authorization", "token " + authToken.getAccessToken());
|
header.add("Authorization", "token " + authToken.getAccessToken());
|
||||||
String response = new HttpUtils(config.getHttpConfig()).get(UrlBuilder.fromBaseUrl(source.userInfo()).build(), null, header, false).getBody();
|
String response = new HttpUtils(config.getHttpConfig()).get(UrlBuilder.fromBaseUrl(source.userInfo()).build(), null, header, false).getBody();
|
||||||
|
|||||||
@ -30,7 +30,7 @@ public class AuthGitlabRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
String response = doPostAuthorizationCode(authCallback.getCode());
|
String response = doPostAuthorizationCode(authCallback.getCode());
|
||||||
JSONObject object = JSONObject.parseObject(response);
|
JSONObject object = JSONObject.parseObject(response);
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ public class AuthGitlabRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String response = doGetUserInfo(authToken);
|
String response = doGetUserInfo(authToken);
|
||||||
JSONObject object = JSONObject.parseObject(response);
|
JSONObject object = JSONObject.parseObject(response);
|
||||||
|
|
||||||
|
|||||||
@ -33,7 +33,7 @@ public class AuthGoogleRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
String response = doPostAuthorizationCode(authCallback.getCode());
|
String response = doPostAuthorizationCode(authCallback.getCode());
|
||||||
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
||||||
this.checkResponse(accessTokenObject);
|
this.checkResponse(accessTokenObject);
|
||||||
@ -47,7 +47,7 @@ public class AuthGoogleRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
HttpHeader httpHeader = new HttpHeader();
|
HttpHeader httpHeader = new HttpHeader();
|
||||||
httpHeader.add("Authorization", "Bearer " + authToken.getAccessToken());
|
httpHeader.add("Authorization", "Bearer " + authToken.getAccessToken());
|
||||||
String userInfo = new HttpUtils(config.getHttpConfig()).post(userInfoUrl(authToken), null, httpHeader).getBody();
|
String userInfo = new HttpUtils(config.getHttpConfig()).post(userInfoUrl(authToken), null, httpHeader).getBody();
|
||||||
|
|||||||
@ -23,10 +23,13 @@ import static me.zhyd.oauth.enums.AuthResponseStatus.SUCCESS;
|
|||||||
/**
|
/**
|
||||||
* 华为授权登录
|
* 华为授权登录
|
||||||
*
|
*
|
||||||
|
* 当前方式未来可能被废弃,建议使用 {@link AuthHuaweiV3Request}
|
||||||
|
*
|
||||||
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
|
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @since 1.10.0
|
* @since 1.10.0
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public class AuthHuaweiRequest extends AuthDefaultRequest {
|
public class AuthHuaweiRequest extends AuthDefaultRequest {
|
||||||
|
|
||||||
public AuthHuaweiRequest(AuthConfig config) {
|
public AuthHuaweiRequest(AuthConfig config) {
|
||||||
@ -46,7 +49,7 @@ public class AuthHuaweiRequest extends AuthDefaultRequest {
|
|||||||
* @see AuthDefaultRequest#authorize(String)
|
* @see AuthDefaultRequest#authorize(String)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
Map<String, String> form = new HashMap<>(8);
|
Map<String, String> form = new HashMap<>(8);
|
||||||
form.put("grant_type", "authorization_code");
|
form.put("grant_type", "authorization_code");
|
||||||
form.put("code", authCallback.getAuthorization_code());
|
form.put("code", authCallback.getAuthorization_code());
|
||||||
@ -66,12 +69,14 @@ public class AuthHuaweiRequest extends AuthDefaultRequest {
|
|||||||
* @see AuthDefaultRequest#getAccessToken(AuthCallback)
|
* @see AuthDefaultRequest#getAccessToken(AuthCallback)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
Map<String, String> form = new HashMap<>(7);
|
Map<String, String> form = new HashMap<>(7);
|
||||||
form.put("nsp_ts", System.currentTimeMillis() + "");
|
form.put("nsp_ts", System.currentTimeMillis() + "");
|
||||||
form.put("access_token", authToken.getAccessToken());
|
form.put("access_token", authToken.getAccessToken());
|
||||||
form.put("nsp_fmt", "JS");
|
form.put("nsp_fmt", "JS");
|
||||||
form.put("nsp_svc", "OpenUP.User.getInfo");
|
form.put("open_id", "OPENID");
|
||||||
|
// form.put("nsp_svc", "OpenUP.User.getInfo");
|
||||||
|
form.put("nsp_svc", "huawei.oauth2.user.getTokenInfo");
|
||||||
|
|
||||||
String response = new HttpUtils(config.getHttpConfig()).post(source.userInfo(), form, false).getBody();
|
String response = new HttpUtils(config.getHttpConfig()).post(source.userInfo(), form, false).getBody();
|
||||||
JSONObject object = JSONObject.parseObject(response);
|
JSONObject object = JSONObject.parseObject(response);
|
||||||
@ -99,7 +104,7 @@ public class AuthHuaweiRequest extends AuthDefaultRequest {
|
|||||||
* @return AuthResponse
|
* @return AuthResponse
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public AuthResponse refresh(AuthToken authToken) {
|
public AuthResponse<AuthToken> refresh(AuthToken authToken) {
|
||||||
Map<String, String> form = new HashMap<>(7);
|
Map<String, String> form = new HashMap<>(7);
|
||||||
form.put("client_id", config.getClientId());
|
form.put("client_id", config.getClientId());
|
||||||
form.put("client_secret", config.getClientSecret());
|
form.put("client_secret", config.getClientSecret());
|
||||||
@ -107,7 +112,7 @@ public class AuthHuaweiRequest extends AuthDefaultRequest {
|
|||||||
form.put("grant_type", "refresh_token");
|
form.put("grant_type", "refresh_token");
|
||||||
|
|
||||||
String response = new HttpUtils(config.getHttpConfig()).post(source.refresh(), form, false).getBody();
|
String response = new HttpUtils(config.getHttpConfig()).post(source.refresh(), form, false).getBody();
|
||||||
return AuthResponse.builder().code(SUCCESS.getCode()).data(getAuthToken(response)).build();
|
return AuthResponse.<AuthToken>builder().code(SUCCESS.getCode()).data(getAuthToken(response)).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private AuthToken getAuthToken(String response) {
|
private AuthToken getAuthToken(String response) {
|
||||||
|
|||||||
196
src/main/java/me/zhyd/oauth/request/AuthHuaweiV3Request.java
Normal file
196
src/main/java/me/zhyd/oauth/request/AuthHuaweiV3Request.java
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
package me.zhyd.oauth.request;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.xkcoding.http.constants.Constants;
|
||||||
|
import com.xkcoding.http.support.HttpHeader;
|
||||||
|
import me.zhyd.oauth.cache.AuthStateCache;
|
||||||
|
import me.zhyd.oauth.config.AuthConfig;
|
||||||
|
import me.zhyd.oauth.config.AuthDefaultSource;
|
||||||
|
import me.zhyd.oauth.enums.AuthUserGender;
|
||||||
|
import me.zhyd.oauth.enums.scope.AuthHuaweiV3Scope;
|
||||||
|
import me.zhyd.oauth.exception.AuthException;
|
||||||
|
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.*;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static me.zhyd.oauth.enums.AuthResponseStatus.SUCCESS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 华为授权登录
|
||||||
|
*
|
||||||
|
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
|
||||||
|
* @version 1.0
|
||||||
|
* @since 1.16.7
|
||||||
|
*/
|
||||||
|
public class AuthHuaweiV3Request extends AuthDefaultRequest {
|
||||||
|
|
||||||
|
public AuthHuaweiV3Request(AuthConfig config) {
|
||||||
|
super(config, AuthDefaultSource.HUAWEI_V3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthHuaweiV3Request(AuthConfig config, AuthStateCache authStateCache) {
|
||||||
|
super(config, AuthDefaultSource.HUAWEI_V3, authStateCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取access token
|
||||||
|
*
|
||||||
|
* @param authCallback 授权成功后的回调参数
|
||||||
|
* @return token
|
||||||
|
* @see AuthDefaultRequest#authorize()
|
||||||
|
* @see AuthDefaultRequest#authorize(String)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
|
Map<String, String> form = new HashMap<>(8);
|
||||||
|
form.put("grant_type", "authorization_code");
|
||||||
|
form.put("code", authCallback.getCode());
|
||||||
|
form.put("client_id", config.getClientId());
|
||||||
|
form.put("client_secret", config.getClientSecret());
|
||||||
|
form.put("redirect_uri", config.getRedirectUri());
|
||||||
|
|
||||||
|
if (config.isPkce()) {
|
||||||
|
String cacheKey = this.source.getName().concat(":code_verifier:").concat(authCallback.getState());
|
||||||
|
String codeVerifier = this.authStateCache.get(cacheKey);
|
||||||
|
form.put("code_verifier", codeVerifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpHeader httpHeader = new HttpHeader();
|
||||||
|
httpHeader.add(Constants.CONTENT_TYPE, "application/x-www-form-urlencoded");
|
||||||
|
String response = new HttpUtils(config.getHttpConfig()).post(source.accessToken(), form, httpHeader, false).getBody();
|
||||||
|
return getAuthToken(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用token换取用户信息
|
||||||
|
*
|
||||||
|
* @param authToken token信息
|
||||||
|
* @return 用户信息
|
||||||
|
* @see AuthDefaultRequest#getAccessToken(AuthCallback)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
|
String idToken = authToken.getIdToken();
|
||||||
|
if (StringUtils.isEmpty(idToken)) {
|
||||||
|
Map<String, String> form = new HashMap<>(7);
|
||||||
|
form.put("access_token", authToken.getAccessToken());
|
||||||
|
form.put("getNickName", "1");
|
||||||
|
form.put("nsp_svc", "GOpen.User.getInfo");
|
||||||
|
|
||||||
|
HttpHeader httpHeader = new HttpHeader();
|
||||||
|
httpHeader.add(Constants.CONTENT_TYPE, "application/x-www-form-urlencoded");
|
||||||
|
String response = new HttpUtils(config.getHttpConfig()).post(source.userInfo(), form, httpHeader, false).getBody();
|
||||||
|
JSONObject object = JSONObject.parseObject(response);
|
||||||
|
|
||||||
|
this.checkResponse(object);
|
||||||
|
|
||||||
|
return AuthUser.builder()
|
||||||
|
.rawUserInfo(object)
|
||||||
|
.uuid(object.getString("unionID"))
|
||||||
|
.username(object.getString("displayName"))
|
||||||
|
.nickname(object.getString("displayName"))
|
||||||
|
.gender(AuthUserGender.UNKNOWN)
|
||||||
|
.avatar(object.getString("headPictureURL"))
|
||||||
|
.token(authToken)
|
||||||
|
.source(source.toString())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
String payload = new String(Base64.getUrlDecoder().decode(idToken.split("\\.")[1]), StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
JSONObject object = JSONObject.parseObject(payload);
|
||||||
|
return AuthUser.builder()
|
||||||
|
.rawUserInfo(object)
|
||||||
|
.uuid(object.getString("sub"))
|
||||||
|
.username(object.getString("name"))
|
||||||
|
.nickname(object.getString("nickname"))
|
||||||
|
.gender(AuthUserGender.UNKNOWN)
|
||||||
|
.avatar(object.getString("picture"))
|
||||||
|
.token(authToken)
|
||||||
|
.source(source.toString())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新access token (续期)
|
||||||
|
*
|
||||||
|
* @param authToken 登录成功后返回的Token信息
|
||||||
|
* @return AuthResponse
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AuthResponse<AuthToken> refresh(AuthToken authToken) {
|
||||||
|
Map<String, String> form = new HashMap<>(7);
|
||||||
|
form.put("client_id", config.getClientId());
|
||||||
|
form.put("client_secret", config.getClientSecret());
|
||||||
|
form.put("refresh_token", authToken.getRefreshToken());
|
||||||
|
form.put("grant_type", "refresh_token");
|
||||||
|
|
||||||
|
HttpHeader httpHeader = new HttpHeader();
|
||||||
|
httpHeader.add(Constants.CONTENT_TYPE, "application/x-www-form-urlencoded");
|
||||||
|
String response = new HttpUtils(config.getHttpConfig()).post(source.refresh(), form, httpHeader, false).getBody();
|
||||||
|
return AuthResponse.<AuthToken>builder().code(SUCCESS.getCode()).data(getAuthToken(response)).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private AuthToken getAuthToken(String response) {
|
||||||
|
JSONObject object = JSONObject.parseObject(response);
|
||||||
|
|
||||||
|
this.checkResponse(object);
|
||||||
|
|
||||||
|
return AuthToken.builder()
|
||||||
|
.accessToken(object.getString("access_token"))
|
||||||
|
.expireIn(object.getIntValue("expires_in"))
|
||||||
|
.refreshToken(object.getString("refresh_token"))
|
||||||
|
.idToken(object.getString("id_token"))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state}
|
||||||
|
*
|
||||||
|
* @param state state 验证授权流程的参数,可以防止csrf
|
||||||
|
* @return 返回授权地址
|
||||||
|
* @since 1.9.3
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String authorize(String state) {
|
||||||
|
String realState = getRealState(state);
|
||||||
|
UrlBuilder builder = UrlBuilder.fromBaseUrl(super.authorize(realState))
|
||||||
|
.queryParam("access_type", "offline")
|
||||||
|
.queryParam("scope", this.getScopes(" ", true, AuthScopeUtils.getDefaultScopes(AuthHuaweiV3Scope.values())));
|
||||||
|
|
||||||
|
if (config.isPkce()) {
|
||||||
|
String cacheKey = this.source.getName().concat(":code_verifier:").concat(realState);
|
||||||
|
String codeVerifier = PkceUtil.generateCodeVerifier();
|
||||||
|
String codeChallengeMethod = "S256";
|
||||||
|
String codeChallenge = PkceUtil.generateCodeChallenge(codeChallengeMethod, codeVerifier);
|
||||||
|
builder.queryParam("code_challenge", codeChallenge)
|
||||||
|
.queryParam("code_challenge_method", codeChallengeMethod);
|
||||||
|
// 缓存 codeVerifier 十分钟
|
||||||
|
this.authStateCache.cache(cacheKey, codeVerifier, TimeUnit.MINUTES.toMillis(10));
|
||||||
|
}
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验响应结果
|
||||||
|
*
|
||||||
|
* @param object 接口返回的结果
|
||||||
|
*/
|
||||||
|
private void checkResponse(JSONObject object) {
|
||||||
|
if (object.containsKey("NSP_STATUS")) {
|
||||||
|
throw new AuthException(object.getString("error"));
|
||||||
|
}
|
||||||
|
if (object.containsKey("error")) {
|
||||||
|
throw new AuthException(object.getString("sub_error") + ":" + object.getString("error_description"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -39,7 +39,7 @@ public class AuthJdRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
|
|
||||||
Map<String, String> params = new HashMap<>(7);
|
Map<String, String> params = new HashMap<>(7);
|
||||||
params.put("app_key", config.getClientId());
|
params.put("app_key", config.getClientId());
|
||||||
@ -61,7 +61,7 @@ public class AuthJdRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
UrlBuilder urlBuilder = UrlBuilder.fromBaseUrl(source.userInfo())
|
UrlBuilder urlBuilder = UrlBuilder.fromBaseUrl(source.userInfo())
|
||||||
.queryParam("access_token", authToken.getAccessToken())
|
.queryParam("access_token", authToken.getAccessToken())
|
||||||
.queryParam("app_key", config.getClientId())
|
.queryParam("app_key", config.getClientId())
|
||||||
@ -103,7 +103,7 @@ public class AuthJdRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthResponse refresh(AuthToken oldToken) {
|
public AuthResponse<AuthToken> refresh(AuthToken oldToken) {
|
||||||
Map<String, String> params = new HashMap<>(7);
|
Map<String, String> params = new HashMap<>(7);
|
||||||
params.put("app_key", config.getClientId());
|
params.put("app_key", config.getClientId());
|
||||||
params.put("app_secret", config.getClientSecret());
|
params.put("app_secret", config.getClientSecret());
|
||||||
@ -114,7 +114,7 @@ public class AuthJdRequest extends AuthDefaultRequest {
|
|||||||
|
|
||||||
this.checkResponse(object);
|
this.checkResponse(object);
|
||||||
|
|
||||||
return AuthResponse.builder()
|
return AuthResponse.<AuthToken>builder()
|
||||||
.code(AuthResponseStatus.SUCCESS.getCode())
|
.code(AuthResponseStatus.SUCCESS.getCode())
|
||||||
.data(AuthToken.builder()
|
.data(AuthToken.builder()
|
||||||
.accessToken(object.getString("access_token"))
|
.accessToken(object.getString("access_token"))
|
||||||
|
|||||||
@ -109,8 +109,8 @@ public class AuthKujialeRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthResponse refresh(AuthToken authToken) {
|
public AuthResponse<AuthToken> refresh(AuthToken authToken) {
|
||||||
String response = new HttpUtils(config.getHttpConfig()).post(refreshTokenUrl(authToken.getRefreshToken())).getBody();
|
String response = new HttpUtils(config.getHttpConfig()).post(refreshTokenUrl(authToken.getRefreshToken())).getBody();
|
||||||
return AuthResponse.builder().code(AuthResponseStatus.SUCCESS.getCode()).data(getAuthToken(response)).build();
|
return AuthResponse.<AuthToken>builder().code(AuthResponseStatus.SUCCESS.getCode()).data(getAuthToken(response)).build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,7 +36,7 @@ public class AuthLineRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
Map<String, String> params = new HashMap<>();
|
Map<String, String> params = new HashMap<>();
|
||||||
params.put("grant_type", "authorization_code");
|
params.put("grant_type", "authorization_code");
|
||||||
params.put("code", authCallback.getCode());
|
params.put("code", authCallback.getCode());
|
||||||
@ -56,7 +56,7 @@ public class AuthLineRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String userInfo = new HttpUtils(config.getHttpConfig()).get(source.userInfo(), null, new HttpHeader()
|
String userInfo = new HttpUtils(config.getHttpConfig()).get(source.userInfo(), null, new HttpHeader()
|
||||||
.add("Content-Type", "application/x-www-form-urlencoded")
|
.add("Content-Type", "application/x-www-form-urlencoded")
|
||||||
.add("Authorization", "Bearer ".concat(authToken.getAccessToken())), false).getBody();
|
.add("Authorization", "Bearer ".concat(authToken.getAccessToken())), false).getBody();
|
||||||
@ -88,7 +88,7 @@ public class AuthLineRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthResponse refresh(AuthToken oldToken) {
|
public AuthResponse<AuthToken> refresh(AuthToken oldToken) {
|
||||||
Map<String, String> params = new HashMap<>();
|
Map<String, String> params = new HashMap<>();
|
||||||
params.put("grant_type", "refresh_token");
|
params.put("grant_type", "refresh_token");
|
||||||
params.put("refresh_token", oldToken.getRefreshToken());
|
params.put("refresh_token", oldToken.getRefreshToken());
|
||||||
@ -96,7 +96,7 @@ public class AuthLineRequest extends AuthDefaultRequest {
|
|||||||
params.put("client_secret", config.getClientSecret());
|
params.put("client_secret", config.getClientSecret());
|
||||||
String response = new HttpUtils(config.getHttpConfig()).post(source.accessToken(), params, false).getBody();
|
String response = new HttpUtils(config.getHttpConfig()).post(source.accessToken(), params, false).getBody();
|
||||||
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
||||||
return AuthResponse.builder()
|
return AuthResponse.<AuthToken>builder()
|
||||||
.code(AuthResponseStatus.SUCCESS.getCode())
|
.code(AuthResponseStatus.SUCCESS.getCode())
|
||||||
.data(AuthToken.builder()
|
.data(AuthToken.builder()
|
||||||
.accessToken(accessTokenObject.getString("access_token"))
|
.accessToken(accessTokenObject.getString("access_token"))
|
||||||
|
|||||||
@ -36,12 +36,12 @@ public class AuthLinkedinRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
return this.getToken(accessTokenUrl(authCallback.getCode()));
|
return this.getToken(accessTokenUrl(authCallback.getCode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String accessToken = authToken.getAccessToken();
|
String accessToken = authToken.getAccessToken();
|
||||||
HttpHeader httpHeader = new HttpHeader();
|
HttpHeader httpHeader = new HttpHeader();
|
||||||
httpHeader.add("Host", "api.linkedin.com");
|
httpHeader.add("Host", "api.linkedin.com");
|
||||||
|
|||||||
@ -34,7 +34,7 @@ public class AuthMeituanRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
Map<String, String> form = new HashMap<>(7);
|
Map<String, String> form = new HashMap<>(7);
|
||||||
form.put("app_id", config.getClientId());
|
form.put("app_id", config.getClientId());
|
||||||
form.put("secret", config.getClientSecret());
|
form.put("secret", config.getClientSecret());
|
||||||
@ -54,7 +54,7 @@ public class AuthMeituanRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
Map<String, String> form = new HashMap<>(5);
|
Map<String, String> form = new HashMap<>(5);
|
||||||
form.put("app_id", config.getClientId());
|
form.put("app_id", config.getClientId());
|
||||||
form.put("secret", config.getClientSecret());
|
form.put("secret", config.getClientSecret());
|
||||||
@ -78,7 +78,7 @@ public class AuthMeituanRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthResponse refresh(AuthToken oldToken) {
|
public AuthResponse<AuthToken> refresh(AuthToken oldToken) {
|
||||||
Map<String, String> form = new HashMap<>(7);
|
Map<String, String> form = new HashMap<>(7);
|
||||||
form.put("app_id", config.getClientId());
|
form.put("app_id", config.getClientId());
|
||||||
form.put("secret", config.getClientSecret());
|
form.put("secret", config.getClientSecret());
|
||||||
@ -90,7 +90,7 @@ public class AuthMeituanRequest extends AuthDefaultRequest {
|
|||||||
|
|
||||||
this.checkResponse(object);
|
this.checkResponse(object);
|
||||||
|
|
||||||
return AuthResponse.builder()
|
return AuthResponse.<AuthToken>builder()
|
||||||
.code(AuthResponseStatus.SUCCESS.getCode())
|
.code(AuthResponseStatus.SUCCESS.getCode())
|
||||||
.data(AuthToken.builder()
|
.data(AuthToken.builder()
|
||||||
.accessToken(object.getString("access_token"))
|
.accessToken(object.getString("access_token"))
|
||||||
|
|||||||
@ -38,7 +38,7 @@ public class AuthMiRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
return getToken(accessTokenUrl(authCallback.getCode()));
|
return getToken(accessTokenUrl(authCallback.getCode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ public class AuthMiRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
// 获取用户信息
|
// 获取用户信息
|
||||||
String userResponse = doGetUserInfo(authToken);
|
String userResponse = doGetUserInfo(authToken);
|
||||||
|
|
||||||
@ -110,8 +110,8 @@ public class AuthMiRequest extends AuthDefaultRequest {
|
|||||||
* @return AuthResponse
|
* @return AuthResponse
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public AuthResponse refresh(AuthToken authToken) {
|
public AuthResponse<AuthToken> refresh(AuthToken authToken) {
|
||||||
return AuthResponse.builder()
|
return AuthResponse.<AuthToken>builder()
|
||||||
.code(AuthResponseStatus.SUCCESS.getCode())
|
.code(AuthResponseStatus.SUCCESS.getCode())
|
||||||
.data(getToken(refreshTokenUrl(authToken.getRefreshToken())))
|
.data(getToken(refreshTokenUrl(authToken.getRefreshToken())))
|
||||||
.build();
|
.build();
|
||||||
|
|||||||
@ -40,7 +40,7 @@ public class AuthOktaRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
String tokenUrl = accessTokenUrl(authCallback.getCode());
|
String tokenUrl = accessTokenUrl(authCallback.getCode());
|
||||||
return getAuthToken(tokenUrl);
|
return getAuthToken(tokenUrl);
|
||||||
}
|
}
|
||||||
@ -64,22 +64,22 @@ public class AuthOktaRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthResponse refresh(AuthToken authToken) {
|
public AuthResponse<AuthToken> refresh(AuthToken authToken) {
|
||||||
if (null == authToken.getRefreshToken()) {
|
if (null == authToken.getRefreshToken()) {
|
||||||
return AuthResponse.builder()
|
return AuthResponse.<AuthToken>builder()
|
||||||
.code(AuthResponseStatus.ILLEGAL_TOKEN.getCode())
|
.code(AuthResponseStatus.ILLEGAL_TOKEN.getCode())
|
||||||
.msg(AuthResponseStatus.ILLEGAL_TOKEN.getMsg())
|
.msg(AuthResponseStatus.ILLEGAL_TOKEN.getMsg())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
String refreshUrl = refreshTokenUrl(authToken.getRefreshToken());
|
String refreshUrl = refreshTokenUrl(authToken.getRefreshToken());
|
||||||
return AuthResponse.builder()
|
return AuthResponse.<AuthToken>builder()
|
||||||
.code(AuthResponseStatus.SUCCESS.getCode())
|
.code(AuthResponseStatus.SUCCESS.getCode())
|
||||||
.data(this.getAuthToken(refreshUrl))
|
.data(this.getAuthToken(refreshUrl))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
HttpHeader header = new HttpHeader()
|
HttpHeader header = new HttpHeader()
|
||||||
.add("Authorization", "Bearer " + authToken.getAccessToken());
|
.add("Authorization", "Bearer " + authToken.getAccessToken());
|
||||||
String response = new HttpUtils(config.getHttpConfig()).post(userInfoUrl(authToken), null, header, false).getBody();
|
String response = new HttpUtils(config.getHttpConfig()).post(userInfoUrl(authToken), null, header, false).getBody();
|
||||||
|
|||||||
@ -28,7 +28,7 @@ public class AuthOschinaRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
String response = doPostAuthorizationCode(authCallback.getCode());
|
String response = doPostAuthorizationCode(authCallback.getCode());
|
||||||
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
||||||
this.checkResponse(accessTokenObject);
|
this.checkResponse(accessTokenObject);
|
||||||
@ -41,7 +41,7 @@ public class AuthOschinaRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String response = doGetUserInfo(authToken);
|
String response = doGetUserInfo(authToken);
|
||||||
JSONObject object = JSONObject.parseObject(response);
|
JSONObject object = JSONObject.parseObject(response);
|
||||||
this.checkResponse(object);
|
this.checkResponse(object);
|
||||||
|
|||||||
@ -36,7 +36,7 @@ public class AuthPinterestRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
String response = doPostAuthorizationCode(authCallback.getCode());
|
String response = doPostAuthorizationCode(authCallback.getCode());
|
||||||
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
||||||
this.checkResponse(accessTokenObject);
|
this.checkResponse(accessTokenObject);
|
||||||
@ -47,7 +47,7 @@ public class AuthPinterestRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String userinfoUrl = userInfoUrl(authToken);
|
String userinfoUrl = userInfoUrl(authToken);
|
||||||
// TODO: 是否需要 .setFollowRedirects(true)
|
// TODO: 是否需要 .setFollowRedirects(true)
|
||||||
String response = new HttpUtils(config.getHttpConfig()).get(userinfoUrl).getBody();
|
String response = new HttpUtils(config.getHttpConfig()).get(userinfoUrl).getBody();
|
||||||
|
|||||||
@ -34,7 +34,7 @@ public class AuthProginnRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
Map<String, String> params = new HashMap<>();
|
Map<String, String> params = new HashMap<>();
|
||||||
params.put("code", authCallback.getCode());
|
params.put("code", authCallback.getCode());
|
||||||
params.put("client_id", config.getClientId());
|
params.put("client_id", config.getClientId());
|
||||||
@ -54,7 +54,7 @@ public class AuthProginnRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String userInfo = doGetUserInfo(authToken);
|
String userInfo = doGetUserInfo(authToken);
|
||||||
JSONObject object = JSONObject.parseObject(userInfo);
|
JSONObject object = JSONObject.parseObject(userInfo);
|
||||||
this.checkResponse(object);
|
this.checkResponse(object);
|
||||||
|
|||||||
@ -0,0 +1,100 @@
|
|||||||
|
package me.zhyd.oauth.request;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.alibaba.fastjson.annotation.JSONField;
|
||||||
|
import lombok.Data;
|
||||||
|
import me.zhyd.oauth.cache.AuthStateCache;
|
||||||
|
import me.zhyd.oauth.config.AuthConfig;
|
||||||
|
import me.zhyd.oauth.config.AuthDefaultSource;
|
||||||
|
import me.zhyd.oauth.exception.AuthException;
|
||||||
|
import me.zhyd.oauth.model.AuthCallback;
|
||||||
|
import me.zhyd.oauth.model.AuthToken;
|
||||||
|
import me.zhyd.oauth.model.AuthUser;
|
||||||
|
import me.zhyd.oauth.utils.HttpUtils;
|
||||||
|
import me.zhyd.oauth.utils.UrlBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* QQ小程序登陆 Request 请求
|
||||||
|
* <p>
|
||||||
|
* 参照微信小程序实现
|
||||||
|
*
|
||||||
|
* @author hurentian
|
||||||
|
* @since 2024-10-08
|
||||||
|
*/
|
||||||
|
public class AuthQQMiniProgramRequest extends AuthDefaultRequest {
|
||||||
|
public AuthQQMiniProgramRequest(AuthConfig config) {
|
||||||
|
super(config, AuthDefaultSource.QQ_MINI_PROGRAM);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthQQMiniProgramRequest(AuthConfig config, AuthStateCache authStateCache) {
|
||||||
|
super(config, AuthDefaultSource.QQ_MINI_PROGRAM, authStateCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
|
// 参见 https://q.qq.com/wiki/develop/miniprogram/server/open_port/port_login.html#code2session 文档
|
||||||
|
// 使用 code 获取对应的 openId、unionId 等字段
|
||||||
|
String response = new HttpUtils(config.getHttpConfig()).get(accessTokenUrl(authCallback.getCode())).getBody();
|
||||||
|
JSCode2SessionResponse accessTokenObject = JSONObject.parseObject(response, JSCode2SessionResponse.class);
|
||||||
|
assert accessTokenObject != null;
|
||||||
|
checkResponse(accessTokenObject);
|
||||||
|
// 拼装结果
|
||||||
|
return AuthToken.builder()
|
||||||
|
.openId(accessTokenObject.getOpenid())
|
||||||
|
.unionId(accessTokenObject.getUnionId())
|
||||||
|
.accessToken(accessTokenObject.getSessionKey())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
|
// 参见 https://q.qq.com/wiki/develop/game/API/open-port/user-info.html#qq-getuserinfo 文档
|
||||||
|
// 如果需要用户信息,需要在小程序调用函数后传给后端
|
||||||
|
return AuthUser.builder()
|
||||||
|
.username("")
|
||||||
|
.nickname("")
|
||||||
|
.avatar("")
|
||||||
|
.uuid(authToken.getOpenId())
|
||||||
|
.token(authToken)
|
||||||
|
.source(source.toString())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查响应内容是否正确
|
||||||
|
*
|
||||||
|
* @param response 请求响应内容
|
||||||
|
*/
|
||||||
|
private void checkResponse(JSCode2SessionResponse response) {
|
||||||
|
if (response.getErrorCode() != 0) {
|
||||||
|
throw new AuthException(response.getErrorCode(), response.getErrorMsg());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String accessTokenUrl(String code) {
|
||||||
|
return UrlBuilder.fromBaseUrl(source.accessToken())
|
||||||
|
.queryParam("appid", config.getClientId())
|
||||||
|
.queryParam("secret", config.getClientSecret())
|
||||||
|
.queryParam("js_code", code)
|
||||||
|
.queryParam("grant_type", "authorization_code")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@SuppressWarnings("SpellCheckingInspection")
|
||||||
|
private static class JSCode2SessionResponse {
|
||||||
|
|
||||||
|
@JSONField(name = "errcode")
|
||||||
|
private int errorCode;
|
||||||
|
@JSONField(name = "errmsg")
|
||||||
|
private String errorMsg;
|
||||||
|
@JSONField(name = "session_key")
|
||||||
|
private String sessionKey;
|
||||||
|
private String openid;
|
||||||
|
@JSONField(name = "unionid")
|
||||||
|
private String unionId;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -33,19 +33,19 @@ public class AuthQqRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
String response = doGetAuthorizationCode(authCallback.getCode());
|
String response = doGetAuthorizationCode(authCallback.getCode());
|
||||||
return getAuthToken(response);
|
return getAuthToken(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthResponse refresh(AuthToken authToken) {
|
public AuthResponse<AuthToken> refresh(AuthToken authToken) {
|
||||||
String response = new HttpUtils(config.getHttpConfig()).get(refreshTokenUrl(authToken.getRefreshToken())).getBody();
|
String response = new HttpUtils(config.getHttpConfig()).get(refreshTokenUrl(authToken.getRefreshToken())).getBody();
|
||||||
return AuthResponse.builder().code(AuthResponseStatus.SUCCESS.getCode()).data(getAuthToken(response)).build();
|
return AuthResponse.<AuthToken>builder().code(AuthResponseStatus.SUCCESS.getCode()).data(getAuthToken(response)).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String openId = this.getOpenId(authToken);
|
String openId = this.getOpenId(authToken);
|
||||||
String response = doGetUserInfo(authToken);
|
String response = doGetUserInfo(authToken);
|
||||||
JSONObject object = JSONObject.parseObject(response);
|
JSONObject object = JSONObject.parseObject(response);
|
||||||
|
|||||||
@ -38,12 +38,12 @@ public class AuthRenrenRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
return this.getToken(accessTokenUrl(authCallback.getCode()));
|
return this.getToken(accessTokenUrl(authCallback.getCode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String response = doGetUserInfo(authToken);
|
String response = doGetUserInfo(authToken);
|
||||||
JSONObject userObj = JSONObject.parseObject(response).getJSONObject("response");
|
JSONObject userObj = JSONObject.parseObject(response).getJSONObject("response");
|
||||||
|
|
||||||
@ -60,8 +60,8 @@ public class AuthRenrenRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthResponse refresh(AuthToken authToken) {
|
public AuthResponse<AuthToken> refresh(AuthToken authToken) {
|
||||||
return AuthResponse.builder()
|
return AuthResponse.<AuthToken>builder()
|
||||||
.code(SUCCESS.getCode())
|
.code(SUCCESS.getCode())
|
||||||
.data(getToken(this.refreshTokenUrl(authToken.getRefreshToken())))
|
.data(getToken(this.refreshTokenUrl(authToken.getRefreshToken())))
|
||||||
.build();
|
.build();
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import me.zhyd.oauth.exception.AuthException;
|
|||||||
import me.zhyd.oauth.model.AuthCallback;
|
import me.zhyd.oauth.model.AuthCallback;
|
||||||
import me.zhyd.oauth.model.AuthResponse;
|
import me.zhyd.oauth.model.AuthResponse;
|
||||||
import me.zhyd.oauth.model.AuthToken;
|
import me.zhyd.oauth.model.AuthToken;
|
||||||
|
import me.zhyd.oauth.model.AuthUser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JustAuth {@code Request}公共接口,所有平台的{@code Request}都需要实现该接口
|
* JustAuth {@code Request}公共接口,所有平台的{@code Request}都需要实现该接口
|
||||||
@ -43,13 +44,32 @@ public interface AuthRequest {
|
|||||||
throw new AuthException(AuthResponseStatus.NOT_IMPLEMENTED);
|
throw new AuthException(AuthResponseStatus.NOT_IMPLEMENTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取access token
|
||||||
|
*
|
||||||
|
* @param authCallback 授权成功后的回调参数
|
||||||
|
* @return token
|
||||||
|
* @see AuthDefaultRequest#authorize()
|
||||||
|
* @see AuthDefaultRequest#authorize(String)
|
||||||
|
*/
|
||||||
|
AuthToken getAccessToken(AuthCallback authCallback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用token换取用户信息
|
||||||
|
*
|
||||||
|
* @param authToken token信息
|
||||||
|
* @return 用户信息
|
||||||
|
* @see AuthDefaultRequest#getAccessToken(AuthCallback)
|
||||||
|
*/
|
||||||
|
AuthUser getUserInfo(AuthToken authToken);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 第三方登录
|
* 第三方登录
|
||||||
*
|
*
|
||||||
* @param authCallback 用于接收回调参数的实体
|
* @param authCallback 用于接收回调参数的实体
|
||||||
* @return 返回登录成功后的用户信息
|
* @return 返回登录成功后的用户信息
|
||||||
*/
|
*/
|
||||||
default AuthResponse login(AuthCallback authCallback) {
|
default AuthResponse<AuthUser> login(AuthCallback authCallback) {
|
||||||
throw new AuthException(AuthResponseStatus.NOT_IMPLEMENTED);
|
throw new AuthException(AuthResponseStatus.NOT_IMPLEMENTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +89,7 @@ public interface AuthRequest {
|
|||||||
* @param authToken 登录成功后返回的Token信息
|
* @param authToken 登录成功后返回的Token信息
|
||||||
* @return AuthResponse
|
* @return AuthResponse
|
||||||
*/
|
*/
|
||||||
default AuthResponse refresh(AuthToken authToken) {
|
default AuthResponse<AuthToken> refresh(AuthToken authToken) {
|
||||||
throw new AuthException(AuthResponseStatus.NOT_IMPLEMENTED);
|
throw new AuthException(AuthResponseStatus.NOT_IMPLEMENTED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,7 +35,7 @@ public class AuthSlackRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
HttpHeader header = new HttpHeader()
|
HttpHeader header = new HttpHeader()
|
||||||
.add("Content-Type", "application/x-www-form-urlencoded");
|
.add("Content-Type", "application/x-www-form-urlencoded");
|
||||||
String response = new HttpUtils(config.getHttpConfig())
|
String response = new HttpUtils(config.getHttpConfig())
|
||||||
@ -51,7 +51,7 @@ public class AuthSlackRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
HttpHeader header = new HttpHeader()
|
HttpHeader header = new HttpHeader()
|
||||||
.add("Content-Type", "application/x-www-form-urlencoded")
|
.add("Content-Type", "application/x-www-form-urlencoded")
|
||||||
.add("Authorization", "Bearer ".concat(authToken.getAccessToken()));
|
.add("Authorization", "Bearer ".concat(authToken.getAccessToken()));
|
||||||
|
|||||||
@ -37,7 +37,7 @@ public class AuthStackOverflowRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
String accessTokenUrl = accessTokenUrl(authCallback.getCode());
|
String accessTokenUrl = accessTokenUrl(authCallback.getCode());
|
||||||
Map<String, String> form = MapUtil.parseStringToMap(accessTokenUrl, false);
|
Map<String, String> form = MapUtil.parseStringToMap(accessTokenUrl, false);
|
||||||
HttpHeader httpHeader = new HttpHeader();
|
HttpHeader httpHeader = new HttpHeader();
|
||||||
@ -54,7 +54,7 @@ public class AuthStackOverflowRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String userInfoUrl = UrlBuilder.fromBaseUrl(this.source.userInfo())
|
String userInfoUrl = UrlBuilder.fromBaseUrl(this.source.userInfo())
|
||||||
.queryParam("access_token", authToken.getAccessToken())
|
.queryParam("access_token", authToken.getAccessToken())
|
||||||
.queryParam("site", "stackoverflow")
|
.queryParam("site", "stackoverflow")
|
||||||
|
|||||||
@ -33,7 +33,7 @@ public class AuthTaobaoRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
return AuthToken.builder().accessCode(authCallback.getCode()).build();
|
return AuthToken.builder().accessCode(authCallback.getCode()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ public class AuthTaobaoRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String response = doPostAuthorizationCode(authToken.getAccessCode());
|
String response = doPostAuthorizationCode(authToken.getAccessCode());
|
||||||
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
||||||
if (accessTokenObject.containsKey("error")) {
|
if (accessTokenObject.containsKey("error")) {
|
||||||
@ -79,11 +79,11 @@ public class AuthTaobaoRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthResponse refresh(AuthToken oldToken) {
|
public AuthResponse<AuthToken> refresh(AuthToken oldToken) {
|
||||||
String tokenUrl = refreshTokenUrl(oldToken.getRefreshToken());
|
String tokenUrl = refreshTokenUrl(oldToken.getRefreshToken());
|
||||||
String response = new HttpUtils(config.getHttpConfig()).post(tokenUrl).getBody();
|
String response = new HttpUtils(config.getHttpConfig()).post(tokenUrl).getBody();
|
||||||
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
||||||
return AuthResponse.builder()
|
return AuthResponse.<AuthToken>builder()
|
||||||
.code(AuthResponseStatus.SUCCESS.getCode())
|
.code(AuthResponseStatus.SUCCESS.getCode())
|
||||||
.data(this.getAuthToken(accessTokenObject))
|
.data(this.getAuthToken(accessTokenObject))
|
||||||
.build();
|
.build();
|
||||||
|
|||||||
@ -38,7 +38,7 @@ public class AuthTeambitionRequest extends AuthDefaultRequest {
|
|||||||
* @return 所有信息
|
* @return 所有信息
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
Map<String, String> form = new HashMap<>(7);
|
Map<String, String> form = new HashMap<>(7);
|
||||||
form.put("client_id", config.getClientId());
|
form.put("client_id", config.getClientId());
|
||||||
form.put("client_secret", config.getClientSecret());
|
form.put("client_secret", config.getClientSecret());
|
||||||
@ -57,7 +57,7 @@ public class AuthTeambitionRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String accessToken = authToken.getAccessToken();
|
String accessToken = authToken.getAccessToken();
|
||||||
|
|
||||||
HttpHeader httpHeader = new HttpHeader();
|
HttpHeader httpHeader = new HttpHeader();
|
||||||
@ -87,7 +87,7 @@ public class AuthTeambitionRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthResponse refresh(AuthToken oldToken) {
|
public AuthResponse<AuthToken> refresh(AuthToken oldToken) {
|
||||||
String uid = oldToken.getUid();
|
String uid = oldToken.getUid();
|
||||||
String refreshToken = oldToken.getRefreshToken();
|
String refreshToken = oldToken.getRefreshToken();
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ public class AuthTeambitionRequest extends AuthDefaultRequest {
|
|||||||
|
|
||||||
this.checkResponse(refreshTokenObject);
|
this.checkResponse(refreshTokenObject);
|
||||||
|
|
||||||
return AuthResponse.builder()
|
return AuthResponse.<AuthToken>builder()
|
||||||
.code(AuthResponseStatus.SUCCESS.getCode())
|
.code(AuthResponseStatus.SUCCESS.getCode())
|
||||||
.data(AuthToken.builder()
|
.data(AuthToken.builder()
|
||||||
.accessToken(refreshTokenObject.getString("access_token"))
|
.accessToken(refreshTokenObject.getString("access_token"))
|
||||||
|
|||||||
@ -29,7 +29,7 @@ public class AuthToutiaoRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
String response = doGetAuthorizationCode(authCallback.getCode());
|
String response = doGetAuthorizationCode(authCallback.getCode());
|
||||||
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ public class AuthToutiaoRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String userResponse = doGetUserInfo(authToken);
|
String userResponse = doGetUserInfo(authToken);
|
||||||
|
|
||||||
JSONObject userProfile = JSONObject.parseObject(userResponse);
|
JSONObject userProfile = JSONObject.parseObject(userResponse);
|
||||||
|
|||||||
@ -88,7 +88,7 @@ public class AuthTwitterRequest extends AuthDefaultRequest {
|
|||||||
* @return access token
|
* @return access token
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
Map<String, String> oauthParams = buildOauthParams();
|
Map<String, String> oauthParams = buildOauthParams();
|
||||||
oauthParams.put("oauth_token", authCallback.getOauth_token());
|
oauthParams.put("oauth_token", authCallback.getOauth_token());
|
||||||
oauthParams.put("oauth_verifier", authCallback.getOauth_verifier());
|
oauthParams.put("oauth_verifier", authCallback.getOauth_verifier());
|
||||||
@ -115,7 +115,7 @@ public class AuthTwitterRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
Map<String, String> queryParams = new HashMap<>(5);
|
Map<String, String> queryParams = new HashMap<>(5);
|
||||||
queryParams.put("include_entities", Boolean.toString(true));
|
queryParams.put("include_entities", Boolean.toString(true));
|
||||||
queryParams.put("include_email", Boolean.toString(true));
|
queryParams.put("include_email", Boolean.toString(true));
|
||||||
|
|||||||
@ -31,6 +31,7 @@ public class AuthWeChatEnterpriseQrcodeRequest extends AbstractAuthWeChatEnterpr
|
|||||||
.queryParam("agentid", config.getAgentId())
|
.queryParam("agentid", config.getAgentId())
|
||||||
.queryParam("redirect_uri", config.getRedirectUri())
|
.queryParam("redirect_uri", config.getRedirectUri())
|
||||||
.queryParam("state", getRealState(state))
|
.queryParam("state", getRealState(state))
|
||||||
|
.queryParam("lang", config.getLang())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,51 @@
|
|||||||
|
package me.zhyd.oauth.request;
|
||||||
|
|
||||||
|
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.utils.GlobalAuthUtils;
|
||||||
|
import me.zhyd.oauth.utils.StringUtils;
|
||||||
|
import me.zhyd.oauth.utils.UrlBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 新版企业微信 Web 登录,参考 <a href="https://developer.work.weixin.qq.com/document/path/98152">https://developer.work.weixin.qq.com/document/path/98152</a>
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
|
||||||
|
* @since 1.16.7
|
||||||
|
*/
|
||||||
|
public class AuthWeChatEnterpriseQrcodeV2Request extends AbstractAuthWeChatEnterpriseRequest {
|
||||||
|
public AuthWeChatEnterpriseQrcodeV2Request(AuthConfig config) {
|
||||||
|
super(config, AuthDefaultSource.WECHAT_ENTERPRISE_V2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthWeChatEnterpriseQrcodeV2Request(AuthConfig config, AuthStateCache authStateCache) {
|
||||||
|
super(config, AuthDefaultSource.WECHAT_ENTERPRISE_V2, authStateCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String authorize(String state) {
|
||||||
|
return UrlBuilder.fromBaseUrl(source.authorize())
|
||||||
|
.queryParam("login_type", config.getLoginType())
|
||||||
|
// 登录类型为企业自建应用/服务商代开发应用时填企业 CorpID,第三方登录时填登录授权 SuiteID
|
||||||
|
.queryParam("appid", config.getClientId())
|
||||||
|
// 企业自建应用/服务商代开发应用 AgentID,当login_type=CorpApp时填写
|
||||||
|
.queryParam("agentid", config.getAgentId())
|
||||||
|
.queryParam("redirect_uri", GlobalAuthUtils.urlEncode(config.getRedirectUri()))
|
||||||
|
.queryParam("state", getRealState(state))
|
||||||
|
.queryParam("lang", config.getLang())
|
||||||
|
.build()
|
||||||
|
.concat("#wechat_redirect");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void checkConfig(AuthConfig config) {
|
||||||
|
super.checkConfig(config);
|
||||||
|
if ("CorpApp".equals(config.getLoginType()) && StringUtils.isEmpty(config.getAgentId())) {
|
||||||
|
throw new AuthException(AuthResponseStatus.ILLEGAL_WECHAT_AGENT_ID, source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -41,14 +41,14 @@ public class AuthWeChatEnterpriseThirdQrcodeRequest extends AbstractAuthWeChatEn
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthResponse login(AuthCallback authCallback) {
|
public AuthResponse<AuthUser> login(AuthCallback authCallback) {
|
||||||
try {
|
try {
|
||||||
if (!config.isIgnoreCheckState()) {
|
if (!config.isIgnoreCheckState()) {
|
||||||
AuthChecker.checkState(authCallback.getState(), source, authStateCache);
|
AuthChecker.checkState(authCallback.getState(), source, authStateCache);
|
||||||
}
|
}
|
||||||
AuthToken authToken = this.getAccessToken(authCallback);
|
AuthToken authToken = this.getAccessToken(authCallback);
|
||||||
AuthUser user = this.getUserInfo(authToken);
|
AuthUser user = this.getUserInfo(authToken);
|
||||||
return AuthResponse.builder().code(AuthResponseStatus.SUCCESS.getCode()).data(user).build();
|
return AuthResponse.<AuthUser>builder().code(AuthResponseStatus.SUCCESS.getCode()).data(user).build();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.error("Failed to login with oauth authorization.", e);
|
Log.error("Failed to login with oauth authorization.", e);
|
||||||
return this.responseError(e);
|
return this.responseError(e);
|
||||||
@ -56,13 +56,14 @@ public class AuthWeChatEnterpriseThirdQrcodeRequest extends AbstractAuthWeChatEn
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
try {
|
try {
|
||||||
String response = doGetAuthorizationCode(accessTokenUrl());
|
String response = doGetAuthorizationCode(accessTokenUrl());
|
||||||
JSONObject object = this.checkResponse(response);
|
JSONObject object = this.checkResponse(response);
|
||||||
AuthToken authToken = AuthToken.builder()
|
AuthToken authToken = AuthToken.builder()
|
||||||
.accessToken(object.getString("provider_access_token"))
|
.accessToken(object.getString("provider_access_token"))
|
||||||
.expireIn(object.getIntValue("expires_in"))
|
.expireIn(object.getIntValue("expires_in"))
|
||||||
|
.code(authCallback.getCode())
|
||||||
.build();
|
.build();
|
||||||
return authToken;
|
return authToken;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -89,7 +90,7 @@ public class AuthWeChatEnterpriseThirdQrcodeRequest extends AbstractAuthWeChatEn
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
JSONObject response = this.checkResponse(doGetUserInfo(authToken));
|
JSONObject response = this.checkResponse(doGetUserInfo(authToken));
|
||||||
return AuthUser.builder()
|
return AuthUser.builder()
|
||||||
.rawUserInfo(response)
|
.rawUserInfo(response)
|
||||||
|
|||||||
@ -36,12 +36,12 @@ public class AuthWeChatMpRequest extends AuthDefaultRequest {
|
|||||||
* @return 所有信息
|
* @return 所有信息
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
return this.getToken(accessTokenUrl(authCallback.getCode()));
|
return this.getToken(accessTokenUrl(authCallback.getCode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String openId = authToken.getOpenId();
|
String openId = authToken.getOpenId();
|
||||||
|
|
||||||
String scope = authToken.getScope();
|
String scope = authToken.getScope();
|
||||||
@ -79,8 +79,8 @@ public class AuthWeChatMpRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthResponse refresh(AuthToken oldToken) {
|
public AuthResponse<AuthToken> refresh(AuthToken oldToken) {
|
||||||
return AuthResponse.builder()
|
return AuthResponse.<AuthToken>builder()
|
||||||
.code(AuthResponseStatus.SUCCESS.getCode())
|
.code(AuthResponseStatus.SUCCESS.getCode())
|
||||||
.data(this.getToken(refreshTokenUrl(oldToken.getRefreshToken())))
|
.data(this.getToken(refreshTokenUrl(oldToken.getRefreshToken())))
|
||||||
.build();
|
.build();
|
||||||
|
|||||||
@ -36,12 +36,12 @@ public class AuthWeChatOpenRequest extends AuthDefaultRequest {
|
|||||||
* @return 所有信息
|
* @return 所有信息
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
return this.getToken(accessTokenUrl(authCallback.getCode()));
|
return this.getToken(accessTokenUrl(authCallback.getCode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String openId = authToken.getOpenId();
|
String openId = authToken.getOpenId();
|
||||||
|
|
||||||
String response = doGetUserInfo(authToken);
|
String response = doGetUserInfo(authToken);
|
||||||
@ -69,8 +69,8 @@ public class AuthWeChatOpenRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthResponse refresh(AuthToken oldToken) {
|
public AuthResponse<AuthToken> refresh(AuthToken oldToken) {
|
||||||
return AuthResponse.builder()
|
return AuthResponse.<AuthToken>builder()
|
||||||
.code(AuthResponseStatus.SUCCESS.getCode())
|
.code(AuthResponseStatus.SUCCESS.getCode())
|
||||||
.data(this.getToken(refreshTokenUrl(oldToken.getRefreshToken())))
|
.data(this.getToken(refreshTokenUrl(oldToken.getRefreshToken())))
|
||||||
.build();
|
.build();
|
||||||
|
|||||||
@ -0,0 +1,100 @@
|
|||||||
|
package me.zhyd.oauth.request;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.alibaba.fastjson.annotation.JSONField;
|
||||||
|
import lombok.Data;
|
||||||
|
import me.zhyd.oauth.cache.AuthStateCache;
|
||||||
|
import me.zhyd.oauth.config.AuthConfig;
|
||||||
|
import me.zhyd.oauth.config.AuthDefaultSource;
|
||||||
|
import me.zhyd.oauth.exception.AuthException;
|
||||||
|
import me.zhyd.oauth.model.AuthCallback;
|
||||||
|
import me.zhyd.oauth.model.AuthToken;
|
||||||
|
import me.zhyd.oauth.model.AuthUser;
|
||||||
|
import me.zhyd.oauth.utils.HttpUtils;
|
||||||
|
import me.zhyd.oauth.utils.UrlBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信小程序授权登录
|
||||||
|
*
|
||||||
|
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
|
||||||
|
* @author yudaocode
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public class AuthWechatMiniProgramRequest extends AuthDefaultRequest {
|
||||||
|
public AuthWechatMiniProgramRequest(AuthConfig config) {
|
||||||
|
super(config, AuthDefaultSource.WECHAT_MINI_PROGRAM);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthWechatMiniProgramRequest(AuthConfig config, AuthStateCache authStateCache) {
|
||||||
|
super(config, AuthDefaultSource.WECHAT_MINI_PROGRAM, authStateCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
|
// 参见 https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html 文档
|
||||||
|
// 使用 code 获取对应的 openId、unionId 等字段
|
||||||
|
String response = new HttpUtils(config.getHttpConfig()).get(accessTokenUrl(authCallback.getCode())).getBody();
|
||||||
|
JSCode2SessionResponse accessTokenObject = JSONObject.parseObject(response, JSCode2SessionResponse.class);
|
||||||
|
assert accessTokenObject != null;
|
||||||
|
checkResponse(accessTokenObject);
|
||||||
|
// 拼装结果
|
||||||
|
return AuthToken.builder()
|
||||||
|
.openId(accessTokenObject.getOpenid())
|
||||||
|
.unionId(accessTokenObject.getUnionId())
|
||||||
|
.accessToken(accessTokenObject.getSessionKey())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
|
// 参见 https://developers.weixin.qq.com/miniprogram/dev/api/open-api/user-info/wx.getUserProfile.html 文档
|
||||||
|
// 如果需要用户信息,需要在小程序调用函数后传给后端
|
||||||
|
return AuthUser.builder()
|
||||||
|
.username("")
|
||||||
|
.nickname("")
|
||||||
|
.avatar("")
|
||||||
|
.uuid(authToken.getOpenId())
|
||||||
|
.token(authToken)
|
||||||
|
.source(source.toString())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查响应内容是否正确
|
||||||
|
*
|
||||||
|
* @param response 请求响应内容
|
||||||
|
*/
|
||||||
|
private void checkResponse(JSCode2SessionResponse response) {
|
||||||
|
if (response.getErrorCode() != 0) {
|
||||||
|
throw new AuthException(response.getErrorCode(), response.getErrorMsg());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String accessTokenUrl(String code) {
|
||||||
|
return UrlBuilder.fromBaseUrl(source.accessToken())
|
||||||
|
.queryParam("appid", config.getClientId())
|
||||||
|
.queryParam("secret", config.getClientSecret())
|
||||||
|
.queryParam("js_code", code)
|
||||||
|
.queryParam("grant_type", "authorization_code")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@SuppressWarnings("SpellCheckingInspection")
|
||||||
|
private static class JSCode2SessionResponse {
|
||||||
|
|
||||||
|
@JSONField(name = "errcode")
|
||||||
|
private int errorCode;
|
||||||
|
@JSONField(name = "errmsg")
|
||||||
|
private String errorMsg;
|
||||||
|
@JSONField(name = "session_key")
|
||||||
|
private String sessionKey;
|
||||||
|
private String openid;
|
||||||
|
@JSONField(name = "unionid")
|
||||||
|
private String unionId;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -33,7 +33,7 @@ public class AuthWeiboRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
String response = doPostAuthorizationCode(authCallback.getCode());
|
String response = doPostAuthorizationCode(authCallback.getCode());
|
||||||
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
JSONObject accessTokenObject = JSONObject.parseObject(response);
|
||||||
if (accessTokenObject.containsKey("error")) {
|
if (accessTokenObject.containsKey("error")) {
|
||||||
@ -48,7 +48,7 @@ public class AuthWeiboRequest extends AuthDefaultRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
String accessToken = authToken.getAccessToken();
|
String accessToken = authToken.getAccessToken();
|
||||||
String uid = authToken.getUid();
|
String uid = authToken.getUid();
|
||||||
String oauthParam = String.format("uid=%s&access_token=%s", uid, accessToken);
|
String oauthParam = String.format("uid=%s&access_token=%s", uid, accessToken);
|
||||||
|
|||||||
@ -42,7 +42,7 @@ public class AuthXmlyRequest extends AuthDefaultRequest {
|
|||||||
* @see AuthDefaultRequest#authorize(String)
|
* @see AuthDefaultRequest#authorize(String)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
Map<String, String> map = new HashMap<>(9);
|
Map<String, String> map = new HashMap<>(9);
|
||||||
map.put("code", authCallback.getCode());
|
map.put("code", authCallback.getCode());
|
||||||
map.put("client_id", config.getClientId());
|
map.put("client_id", config.getClientId());
|
||||||
|
|||||||
@ -80,7 +80,7 @@ public class AuthChecker {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String code = callback.getCode();
|
String code = callback.getCode();
|
||||||
if (source == AuthDefaultSource.HUAWEI) {
|
if (StringUtils.isEmpty(code) && source == AuthDefaultSource.HUAWEI) {
|
||||||
code = callback.getAuthorization_code();
|
code = callback.getAuthorization_code();
|
||||||
}
|
}
|
||||||
if (StringUtils.isEmpty(code)) {
|
if (StringUtils.isEmpty(code)) {
|
||||||
|
|||||||
@ -82,6 +82,10 @@ public class AuthRequestBuilderTest {
|
|||||||
.stackOverflowKey("asd")
|
.stackOverflowKey("asd")
|
||||||
.deviceId("asd")
|
.deviceId("asd")
|
||||||
.clientOsType(3)
|
.clientOsType(3)
|
||||||
|
.kid("kid")
|
||||||
|
.teamId("teamid")
|
||||||
|
.ignoreCheckState(true)
|
||||||
|
.ignoreCheckRedirectUri(true)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
for (AuthDefaultSource value : AuthDefaultSource.values()) {
|
for (AuthDefaultSource value : AuthDefaultSource.values()) {
|
||||||
@ -97,6 +101,18 @@ public class AuthRequestBuilderTest {
|
|||||||
System.out.println(authRequest.authorize(AuthStateUtils.createState()));
|
System.out.println(authRequest.authorize(AuthStateUtils.createState()));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
case WECHAT_MINI_PROGRAM: {
|
||||||
|
// 小程序不支持获取调用 authorize
|
||||||
|
AuthRequest authRequest = new AuthWechatMiniProgramRequest(config);
|
||||||
|
System.out.println(value.getTargetClass());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
case QQ_MINI_PROGRAM: {
|
||||||
|
// 小程序不支持获取调用 authorize
|
||||||
|
AuthRequest authRequest = new AuthQQMiniProgramRequest(config);
|
||||||
|
System.out.println(value.getTargetClass());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
AuthRequest authRequest = AuthRequestBuilder.builder()
|
AuthRequest authRequest = AuthRequestBuilder.builder()
|
||||||
.source(value.getName())
|
.source(value.getName())
|
||||||
|
|||||||
@ -36,7 +36,7 @@ public class AuthExtendRequest extends AuthDefaultRequest {
|
|||||||
* @see AuthDefaultRequest#authorize(String)
|
* @see AuthDefaultRequest#authorize(String)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||||
return AuthToken.builder()
|
return AuthToken.builder()
|
||||||
.openId("openId")
|
.openId("openId")
|
||||||
.expireIn(1000)
|
.expireIn(1000)
|
||||||
@ -56,7 +56,7 @@ public class AuthExtendRequest extends AuthDefaultRequest {
|
|||||||
* @see AuthDefaultRequest#getAccessToken(AuthCallback)
|
* @see AuthDefaultRequest#getAccessToken(AuthCallback)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
public AuthUser getUserInfo(AuthToken authToken) {
|
||||||
return AuthUser.builder()
|
return AuthUser.builder()
|
||||||
.username("test")
|
.username("test")
|
||||||
.nickname("test")
|
.nickname("test")
|
||||||
@ -87,8 +87,8 @@ public class AuthExtendRequest extends AuthDefaultRequest {
|
|||||||
* @return AuthResponse
|
* @return AuthResponse
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public AuthResponse refresh(AuthToken authToken) {
|
public AuthResponse<AuthToken> refresh(AuthToken authToken) {
|
||||||
return AuthResponse.builder()
|
return AuthResponse.<AuthToken>builder()
|
||||||
.code(AuthResponseStatus.SUCCESS.getCode())
|
.code(AuthResponseStatus.SUCCESS.getCode())
|
||||||
.data(AuthToken.builder()
|
.data(AuthToken.builder()
|
||||||
.openId("openId")
|
.openId("openId")
|
||||||
|
|||||||
@ -45,10 +45,10 @@ public class AuthExtendRequestTest {
|
|||||||
.code("code")
|
.code("code")
|
||||||
.state(state)
|
.state(state)
|
||||||
.build();
|
.build();
|
||||||
AuthResponse response = request.login(callback);
|
AuthResponse<AuthUser> response = request.login(callback);
|
||||||
Assert.assertNotNull(response);
|
Assert.assertNotNull(response);
|
||||||
|
|
||||||
AuthUser user = (AuthUser) response.getData();
|
AuthUser user = response.getData();
|
||||||
Assert.assertNotNull(user);
|
Assert.assertNotNull(user);
|
||||||
System.out.println(JSON.toJSONString(user));
|
System.out.println(JSON.toJSONString(user));
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ public class AuthExtendRequestTest {
|
|||||||
.redirectUri("http://redirectUri")
|
.redirectUri("http://redirectUri")
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
AuthResponse response = request.refresh(AuthToken.builder().build());
|
AuthResponse<AuthToken> response = request.refresh(AuthToken.builder().build());
|
||||||
Assert.assertNotNull(response);
|
Assert.assertNotNull(response);
|
||||||
System.out.println(JSON.toJSONString(response.getData()));
|
System.out.println(JSON.toJSONString(response.getData()));
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user