diff --git a/src/main/java/me/zhyd/oauth/config/AuthConfig.java b/src/main/java/me/zhyd/oauth/config/AuthConfig.java
index 153585eddfbdfe009ed207f4382169ad1c2f798d..c9dffc7258567dd522404b6314a4fd26d2dbcc0b 100644
--- a/src/main/java/me/zhyd/oauth/config/AuthConfig.java
+++ b/src/main/java/me/zhyd/oauth/config/AuthConfig.java
@@ -2,8 +2,11 @@ package me.zhyd.oauth.config;
import com.xkcoding.http.config.HttpConfig;
import lombok.*;
+import me.zhyd.oauth.enums.scope.AuthScope;
import me.zhyd.oauth.model.AuthCallback;
+import java.util.List;
+
/**
* JustAuth配置类
*
@@ -64,7 +67,7 @@ public class AuthConfig {
/**
* 使用 Coding 登录时,需要传该值。
- *
+ *
* 团队域名前缀,比如以“ https://justauth.coding.net/ ”为例,{@code codingGroupName} = justauth
*
* @since 1.15.5
@@ -84,18 +87,27 @@ public class AuthConfig {
/**
* 忽略校验 {@code state} 参数,默认不开启。当 {@code ignoreCheckState} 为 {@code true} 时,
* {@link me.zhyd.oauth.request.AuthDefaultRequest#login(AuthCallback)} 将不会校验 {@code state} 的合法性。
- *
+ *
* 使用场景:当且仅当使用自实现 {@code state} 校验逻辑时开启
- *
+ *
* 以下场景使用方案仅作参考:
* 1. 授权、登录为同端,并且全部使用 JustAuth 实现时,该值建议设为 {@code false};
* 2. 授权和登录为不同端实现时,比如前端页面拼装 {@code authorizeUrl},并且前端自行对{@code state}进行校验,
* 后端只负责使用{@code code}获取用户信息时,该值建议设为 {@code true};
*
* 如非特殊需要,不建议开启这个配置
- *
+ *
* 该方案主要为了解决以下类似场景的问题:
+ *
* @see https://github.com/justauth/JustAuth/issues/83
+ * @since 1.15.6
*/
private boolean ignoreCheckState;
+
+ /**
+ * 支持自定义授权平台的 scope 内容
+ *
+ * @since 1.15.7
+ */
+ private List scopes;
}
diff --git a/src/main/java/me/zhyd/oauth/enums/scope/AuthBaiduScope.java b/src/main/java/me/zhyd/oauth/enums/scope/AuthBaiduScope.java
new file mode 100644
index 0000000000000000000000000000000000000000..aaec676109542d246508ab47e7c41f52608a151f
--- /dev/null
+++ b/src/main/java/me/zhyd/oauth/enums/scope/AuthBaiduScope.java
@@ -0,0 +1,48 @@
+package me.zhyd.oauth.enums.scope;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 边度平台 OAuth 授权范围
+ *
+ * @author yadong.zhang (yadong.zhang0415(a)gmail.com)
+ * @version 1.0.0
+ * @since 1.0.0
+ */
+@Getter
+@AllArgsConstructor
+public enum AuthBaiduScope implements AuthScope {
+
+ /**
+ * {@code scope} 含义,以{@code description} 为准
+ */
+ BASIC("basic", "用户基本权限,可以获取用户的基本信息 。", true),
+ SUPER_MSG("super_msg", "往用户的百度首页上发送消息提醒,相关API任何应用都能使用,但要想将消息提醒在百度首页显示,需要第三方在注册应用时额外填写相关信息。", false),
+ NETDISK("netdisk", "获取用户在个人云存储中存放的数据。", false),
+ PUBLIC("public", "可以访问公共的开放API。", false),
+ HAO123("hao123", "可以访问Hao123 提供的开放API接口。该权限需要申请开通,请将具体的理由和用途发邮件给tuangou@baidu.com。", false);
+
+ private String scope;
+ private String description;
+ private boolean isDefault;
+
+ public static List getDefaultScopes() {
+ AuthBaiduScope[] scopes = AuthBaiduScope.values();
+ List defaultScopes = new ArrayList<>();
+ for (AuthBaiduScope scope : scopes) {
+ if (scope.isDefault()) {
+ defaultScopes.add(scope);
+ }
+ }
+ return defaultScopes;
+ }
+
+ public static List listAll() {
+ return Arrays.asList(AuthBaiduScope.values());
+ }
+}
diff --git a/src/main/java/me/zhyd/oauth/enums/scope/AuthCodingScope.java b/src/main/java/me/zhyd/oauth/enums/scope/AuthCodingScope.java
new file mode 100644
index 0000000000000000000000000000000000000000..cbaa315b6d450d3250477afc95a3cca36a33b545
--- /dev/null
+++ b/src/main/java/me/zhyd/oauth/enums/scope/AuthCodingScope.java
@@ -0,0 +1,49 @@
+package me.zhyd.oauth.enums.scope;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Coding平台 OAuth 授权范围
+ *
+ * @author yadong.zhang (yadong.zhang0415(a)gmail.com)
+ * @version 1.0.0
+ * @since 1.0.0
+ */
+@Getter
+@AllArgsConstructor
+public enum AuthCodingScope implements AuthScope {
+
+ /**
+ * {@code scope} 含义,以{@code description} 为准
+ */
+ USER("user", "读取用户的基本信息", false),
+ USER_EMAIL("user:email", "读取用户的邮件", false),
+ USER_PHONE("user:phone", "读取用户的手机号", false),
+ PROJECT("project", "授权项目信息、项目列表,仓库信息,公钥列表、成员", false),
+ PROJECT_DEPOT("project:depot", "完整的仓库控制权限", false),
+ PROJECT_WIKI("project:wiki", "授权读取与操作 wiki", false),
+ ;
+ private String scope;
+ private String description;
+ private boolean isDefault;
+
+ public static List getDefaultScopes() {
+ AuthCodingScope[] scopes = AuthCodingScope.values();
+ List defaultScopes = new ArrayList<>();
+ for (AuthCodingScope scope : scopes) {
+ if (scope.isDefault()) {
+ defaultScopes.add(scope);
+ }
+ }
+ return defaultScopes;
+ }
+
+ public static List listAll() {
+ return Arrays.asList(AuthCodingScope.values());
+ }
+}
diff --git a/src/main/java/me/zhyd/oauth/request/AuthBaiduRequest.java b/src/main/java/me/zhyd/oauth/request/AuthBaiduRequest.java
index 4e8f5c83dafb1ffefd0870bb54ce43355f30194c..fec4ae8449ce5f6ece9cd8130cb524640b324e0b 100644
--- a/src/main/java/me/zhyd/oauth/request/AuthBaiduRequest.java
+++ b/src/main/java/me/zhyd/oauth/request/AuthBaiduRequest.java
@@ -1,17 +1,18 @@
package me.zhyd.oauth.request;
import com.alibaba.fastjson.JSONObject;
-import me.zhyd.oauth.utils.HttpUtils;
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.AuthUserGender;
+import me.zhyd.oauth.enums.scope.AuthBaiduScope;
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.HttpUtils;
import me.zhyd.oauth.utils.StringUtils;
import me.zhyd.oauth.utils.UrlBuilder;
@@ -41,6 +42,7 @@ public class AuthBaiduRequest extends AuthDefaultRequest {
* https://openapi.baidu.com/rest/2.0/passport/users/getInfo?access_token=121.c86e87cc0828cc1dabb8faee540531d4.YsUIAWvYbgqVni1VhkgKgyLh8nEyELbDOEZs_OA.OgDgmA
* https://openapi.baidu.com/rest/2.0/passport/users/getInfo?access_token=121.2907d9facf9fb97adf7287fa75496eda.Y3NSjR3-3HKt1RgT0HEl7GgxRXT5gOOVdngXezY.OcC_7g
* 新旧应用返回的用户信息不一致
+ *
* @param authToken token信息
* @return AuthUser
*/
@@ -106,6 +108,7 @@ public class AuthBaiduRequest extends AuthDefaultRequest {
.queryParam("client_id", config.getClientId())
.queryParam("redirect_uri", config.getRedirectUri())
.queryParam("display", "popup")
+ .queryParam("scope", this.getScopes(" ", false, AuthBaiduScope.getDefaultScopes()))
.queryParam("state", getRealState(state))
.build();
}
diff --git a/src/main/java/me/zhyd/oauth/request/AuthCodingRequest.java b/src/main/java/me/zhyd/oauth/request/AuthCodingRequest.java
index 8acf798299dcd229a7188b7c743eedbb865441de..65c734bf7e2814aff9df7758b117697842c8e556 100644
--- a/src/main/java/me/zhyd/oauth/request/AuthCodingRequest.java
+++ b/src/main/java/me/zhyd/oauth/request/AuthCodingRequest.java
@@ -5,6 +5,7 @@ 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.AuthCodingScope;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthToken;
@@ -87,10 +88,11 @@ public class AuthCodingRequest extends AuthDefaultRequest {
.queryParam("response_type", "code")
.queryParam("client_id", config.getClientId())
.queryParam("redirect_uri", config.getRedirectUri())
- .queryParam("scope", "user")
+ .queryParam("scope", this.getScopes(" ", true, AuthCodingScope.getDefaultScopes()))
.queryParam("state", getRealState(state))
.build();
}
+
/**
* 返回获取accessToken的url
*
@@ -98,7 +100,7 @@ public class AuthCodingRequest extends AuthDefaultRequest {
* @return 返回获取accessToken的url
*/
@Override
- public String accessTokenUrl(String code) {
+ public String accessTokenUrl(String code) {
return UrlBuilder.fromBaseUrl(String.format(source.accessToken(), config.getCodingGroupName()))
.queryParam("code", code)
.queryParam("client_id", config.getClientId())
@@ -115,7 +117,7 @@ public class AuthCodingRequest extends AuthDefaultRequest {
* @return 返回获取userInfo的url
*/
@Override
- public String userInfoUrl(AuthToken authToken) {
+ public String userInfoUrl(AuthToken authToken) {
return UrlBuilder.fromBaseUrl(String.format(source.userInfo(), config.getCodingGroupName()))
.queryParam("access_token", authToken.getAccessToken())
.build();
diff --git a/src/main/java/me/zhyd/oauth/request/AuthDefaultRequest.java b/src/main/java/me/zhyd/oauth/request/AuthDefaultRequest.java
index 241840008717da963680ebff7f7dd472081abf21..86707fde3720f8c8233b11441e1e99eead9ecfb3 100644
--- a/src/main/java/me/zhyd/oauth/request/AuthDefaultRequest.java
+++ b/src/main/java/me/zhyd/oauth/request/AuthDefaultRequest.java
@@ -1,21 +1,21 @@
package me.zhyd.oauth.request;
-import me.zhyd.oauth.utils.HttpUtils;
+import com.xkcoding.http.util.UrlUtil;
import me.zhyd.oauth.cache.AuthDefaultStateCache;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.enums.AuthResponseStatus;
+import me.zhyd.oauth.enums.scope.AuthScope;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.log.Log;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
-import me.zhyd.oauth.utils.AuthChecker;
-import me.zhyd.oauth.utils.StringUtils;
-import me.zhyd.oauth.utils.UrlBuilder;
-import me.zhyd.oauth.utils.UuidUtils;
+import me.zhyd.oauth.utils.*;
+
+import java.util.List;
/**
* 默认的request处理类
@@ -267,4 +267,33 @@ public abstract class AuthDefaultRequest implements AuthRequest {
return new HttpUtils(config.getHttpConfig()).get(revokeUrl(authToken));
}
+ /**
+ * 获取以 {@code separator}分割过后的 scope 信息
+ *
+ * @param separator 多个 {@code scope} 间的分隔符
+ * @param encode 是否 encode 编码
+ * @param defaultScopes 默认的 scope, 当客户端没有配置 {@code scopes} 时启用
+ * @return String
+ * @since 1.16.7
+ */
+ protected String getScopes(String separator, boolean encode, List defaultScopes) {
+ if (null == separator) {
+ // 默认为空格
+ separator = " ";
+ }
+ List scopes = config.getScopes();
+ if (null == scopes || scopes.isEmpty()) {
+ if (null == defaultScopes || defaultScopes.isEmpty()) {
+ return null;
+ }
+ scopes = defaultScopes;
+ }
+ StringBuilder res = new StringBuilder();
+ for (AuthScope scope : scopes) {
+ res.append(scope.getScope()).append(separator);
+ }
+ String scopeStr = res.deleteCharAt(res.length() - separator.length()).toString();
+ return encode ? UrlUtil.urlEncode(scopeStr) : scopeStr;
+ }
+
}