From 419ca3797cda80d28e59f10b07dbb75dc2d76936 Mon Sep 17 00:00:00 2001 From: click33 <2393584716@qq.com> Date: Fri, 23 Aug 2024 16:18:24 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=86=E8=8A=82=E4=BC=98=E5=8C=96=E3=80=81?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/dev33/satoken/stp/StpLogic.java | 5 +- .../com/pj/SaOAuth2ServerApplication.java | 2 +- .../com/pj/oauth2/SaOAuth2DataLoaderImpl.java | 2 +- .../pj/oauth2/SaOAuth2ServerController.java | 15 ++-- .../custom/PhoneCodeGrantTypeHandler.java | 3 +- .../src/main/resources/application.yml | 8 +- sa-token-doc/_sidebar.md | 2 +- sa-token-doc/oauth2/oauth2-check-domain.md | 18 +++-- sa-token-doc/oauth2/oauth2-custom-api.md | 6 +- .../oauth2/oauth2-custom-grant_type.md | 5 +- sa-token-doc/oauth2/oauth2-custom-login.md | 8 +- ...cope-handler.md => oauth2-custom-scope.md} | 0 sa-token-doc/oauth2/oauth2-interworking.md | 39 +++++---- sa-token-doc/oauth2/oauth2-server.md | 67 +++++++++------ sa-token-doc/up/integ-redis.md | 2 +- sa-token-doc/use/config.md | 81 +++++++++---------- .../dev33/satoken/oauth2/SaOAuth2Manager.java | 10 +-- ...2Config.java => SaOAuth2ServerConfig.java} | 58 ++++++------- .../SaOAuth2DataConverterDefaultImpl.java | 6 +- .../data/model/loader/SaClientModel.java | 36 ++++----- .../AuthorizationCodeGrantTypeHandler.java | 2 +- .../handler/PasswordGrantTypeHandler.java | 2 +- .../handler/RefreshTokenGrantTypeHandler.java | 2 +- .../SaOAuth2GrantTypeHandlerInterface.java | 2 +- .../processor/SaOAuth2ServerProcessor.java | 14 ++-- .../oauth2/strategy/SaOAuth2Strategy.java | 8 +- .../oauth2/template/SaOAuth2Template.java | 4 +- .../solon/oauth2/SaOAuth2AutoConfigure.java | 6 +- .../spring/oauth2/SaOAuth2BeanInject.java | 4 +- .../spring/oauth2/SaOAuth2BeanRegister.java | 8 +- 30 files changed, 226 insertions(+), 199 deletions(-) rename sa-token-doc/oauth2/{oauth2-custom-scope-handler.md => oauth2-custom-scope.md} (100%) rename sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/config/{SaOAuth2Config.java => SaOAuth2ServerConfig.java} (79%) diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java b/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java index 1c071119..0e5050b5 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java @@ -36,6 +36,7 @@ import cn.dev33.satoken.util.SaFoxUtil; import cn.dev33.satoken.util.SaTokenConsts; import cn.dev33.satoken.util.SaValue2Box; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; @@ -2114,7 +2115,7 @@ public class StpLogic { // 如果该账号的 Account-Session 为 null,说明此账号尚没有客户端在登录,此时返回空集合 SaSession session = getSessionByLoginId(loginId, false); if(session == null) { - return Collections.emptyList(); + return new ArrayList<>(); } // 按照设备类型进行筛选 @@ -2132,7 +2133,7 @@ public class StpLogic { // 如果该账号的 Account-Session 为 null,说明此账号尚没有客户端在登录,此时返回空集合 SaSession session = getSessionByLoginId(loginId, false); if(session == null) { - return Collections.emptyList(); + return new ArrayList<>(); } // 按照设备类型进行筛选 diff --git a/sa-token-demo/sa-token-demo-oauth2/sa-token-demo-oauth2-server/src/main/java/com/pj/SaOAuth2ServerApplication.java b/sa-token-demo/sa-token-demo-oauth2/sa-token-demo-oauth2-server/src/main/java/com/pj/SaOAuth2ServerApplication.java index 4cf9200b..8666f2c3 100644 --- a/sa-token-demo/sa-token-demo-oauth2/sa-token-demo-oauth2-server/src/main/java/com/pj/SaOAuth2ServerApplication.java +++ b/sa-token-demo/sa-token-demo-oauth2/sa-token-demo-oauth2-server/src/main/java/com/pj/SaOAuth2ServerApplication.java @@ -13,7 +13,7 @@ public class SaOAuth2ServerApplication { public static void main(String[] args) { SpringApplication.run(SaOAuth2ServerApplication.class, args); - System.out.println("\nSa-Token-OAuth Server端启动成功,配置如下:"); + System.out.println("\nSa-Token-OAuth2 Server端启动成功,配置如下:"); System.out.println(SaOAuth2Manager.getConfig()); } diff --git a/sa-token-demo/sa-token-demo-oauth2/sa-token-demo-oauth2-server/src/main/java/com/pj/oauth2/SaOAuth2DataLoaderImpl.java b/sa-token-demo/sa-token-demo-oauth2/sa-token-demo-oauth2-server/src/main/java/com/pj/oauth2/SaOAuth2DataLoaderImpl.java index fbcc2863..fd8216fc 100644 --- a/sa-token-demo/sa-token-demo-oauth2/sa-token-demo-oauth2-server/src/main/java/com/pj/oauth2/SaOAuth2DataLoaderImpl.java +++ b/sa-token-demo/sa-token-demo-oauth2/sa-token-demo-oauth2-server/src/main/java/com/pj/oauth2/SaOAuth2DataLoaderImpl.java @@ -21,7 +21,7 @@ public class SaOAuth2DataLoaderImpl implements SaOAuth2DataLoader { return new SaClientModel() .setClientId("1001") // client id .setClientSecret("aaaa-bbbb-cccc-dddd-eeee") // client 秘钥 - .addAllowUrls("*") // 所有允许授权的 url + .addAllowRedirectUris("*") // 所有允许授权的 url .addContractScopes("openid", "userid", "userinfo") // 所有签约的权限 .addAllowGrantTypes( // 所有允许的授权模式 GrantType.authorization_code, // 授权码式 diff --git a/sa-token-demo/sa-token-demo-oauth2/sa-token-demo-oauth2-server/src/main/java/com/pj/oauth2/SaOAuth2ServerController.java b/sa-token-demo/sa-token-demo-oauth2/sa-token-demo-oauth2-server/src/main/java/com/pj/oauth2/SaOAuth2ServerController.java index 37261fd0..bc473a8a 100644 --- a/sa-token-demo/sa-token-demo-oauth2/sa-token-demo-oauth2-server/src/main/java/com/pj/oauth2/SaOAuth2ServerController.java +++ b/sa-token-demo/sa-token-demo-oauth2/sa-token-demo-oauth2-server/src/main/java/com/pj/oauth2/SaOAuth2ServerController.java @@ -1,7 +1,7 @@ package com.pj.oauth2; import cn.dev33.satoken.context.SaHolder; -import cn.dev33.satoken.oauth2.config.SaOAuth2Config; +import cn.dev33.satoken.oauth2.config.SaOAuth2ServerConfig; import cn.dev33.satoken.oauth2.processor.SaOAuth2ServerProcessor; import cn.dev33.satoken.oauth2.template.SaOAuth2Util; import cn.dev33.satoken.stp.StpUtil; @@ -24,23 +24,23 @@ import java.util.Map; @RestController public class SaOAuth2ServerController { - // OAuth2-Server 端:处理所有OAuth相关请求 + // OAuth2-Server 端:处理所有 OAuth2 相关请求 @RequestMapping("/oauth2/*") public Object request() { System.out.println("------- 进入请求: " + SaHolder.getRequest().getUrl()); return SaOAuth2ServerProcessor.instance.dister(); } - // Sa-OAuth2 定制化配置 + // Sa-Token OAuth2 定制化配置 @Autowired - public void configOAuth2Server(SaOAuth2Config cfg) { + public void configOAuth2Server(SaOAuth2ServerConfig oauth2Server) { // 未登录的视图 - cfg.notLoginView = ()->{ + oauth2Server.notLoginView = ()->{ return new ModelAndView("login.html"); }; // 登录处理函数 - cfg.doLoginHandle = (name, pwd) -> { + oauth2Server.doLoginHandle = (name, pwd) -> { if("sa".equals(name) && "123456".equals(pwd)) { StpUtil.login(10001); return SaResult.ok(); @@ -49,12 +49,13 @@ public class SaOAuth2ServerController { }; // 授权确认视图 - cfg.confirmView = (clientId, scopes)->{ + oauth2Server.confirmView = (clientId, scopes)->{ Map map = new HashMap<>(); map.put("clientId", clientId); map.put("scope", scopes); return new ModelAndView("confirm.html", map); }; + } diff --git a/sa-token-demo/sa-token-demo-oauth2/sa-token-demo-oauth2-server/src/main/java/com/pj/oauth2/custom/PhoneCodeGrantTypeHandler.java b/sa-token-demo/sa-token-demo-oauth2/sa-token-demo-oauth2-server/src/main/java/com/pj/oauth2/custom/PhoneCodeGrantTypeHandler.java index 9bad7d29..6afb64a7 100644 --- a/sa-token-demo/sa-token-demo-oauth2/sa-token-demo-oauth2-server/src/main/java/com/pj/oauth2/custom/PhoneCodeGrantTypeHandler.java +++ b/sa-token-demo/sa-token-demo-oauth2/sa-token-demo-oauth2-server/src/main/java/com/pj/oauth2/custom/PhoneCodeGrantTypeHandler.java @@ -26,8 +26,9 @@ public class PhoneCodeGrantTypeHandler implements SaOAuth2GrantTypeHandlerInterf } @Override - public AccessTokenModel getAccessTokenModel(SaRequest req, String clientId, List scopes) { + public AccessTokenModel getAccessToken(SaRequest req, String clientId, List scopes) { + // 获取前端提交的参数 String phone = req.getParamNotNull("phone"); String code = req.getParamNotNull("code"); String realCode = SaManager.getSaTokenDao().get("phone_code:" + phone); diff --git a/sa-token-demo/sa-token-demo-oauth2/sa-token-demo-oauth2-server/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-oauth2/sa-token-demo-oauth2-server/src/main/resources/application.yml index 0cd51d5c..eada44d9 100644 --- a/sa-token-demo/sa-token-demo-oauth2/sa-token-demo-oauth2-server/src/main/resources/application.yml +++ b/sa-token-demo/sa-token-demo-oauth2/sa-token-demo-oauth2-server/src/main/resources/application.yml @@ -4,19 +4,19 @@ server: # sa-token配置 sa-token: # token名称 (同时也是 Cookie 名称) - token-name: satoken-oauth2-server + token-name: sa-token-oauth2-server # 是否打印操作日志 is-log: true # OAuth2.0 配置 - oauth2: + oauth2-server: # 是否全局开启授权码模式 - enable-code: true + enable-authorization-code: true # 是否全局开启 Implicit 模式 enable-implicit: true # 是否全局开启密码模式 enable-password: true # 是否全局开启客户端模式 - enable-client: true + enable-client-credentials: true # 定义哪些 scope 是高级权限,多个用逗号隔开 # higher-scope: openid,userid # 定义哪些 scope 是低级权限,多个用逗号隔开 diff --git a/sa-token-doc/_sidebar.md b/sa-token-doc/_sidebar.md index f87b8192..3a7c4b0f 100644 --- a/sa-token-doc/_sidebar.md +++ b/sa-token-doc/_sidebar.md @@ -58,7 +58,7 @@ - [配置 client 域名校验 ](/oauth2/oauth2-check-domain) - [定制化登录页面与授权页面](/oauth2/oauth2-custom-login) - [自定义 API 路由 ](/oauth2/oauth2-custom-api) - - [自定义 Scope 权限以处理器](/oauth2/oauth2-custom-scope-handler) + - [自定义 Scope 权限以处理器](/oauth2/oauth2-custom-scope) - [为 Scope 划分等级](/oauth2/oauth2-scope-level) - [自定义 grant_type](/oauth2/oauth2-custom-grant_type) - [OAuth2-与登录会话实现数据互通](/oauth2/oauth2-interworking) diff --git a/sa-token-doc/oauth2/oauth2-check-domain.md b/sa-token-doc/oauth2/oauth2-check-domain.md index f1cca9e3..a6e8faf6 100644 --- a/sa-token-doc/oauth2/oauth2-check-domain.md +++ b/sa-token-doc/oauth2/oauth2-check-domain.md @@ -14,7 +14,7 @@ public class SaOAuth2DataLoaderImpl implements SaOAuth2DataLoader { if("1001".equals(clientId)) { return new SaClientModel() // ... - .addAllowUrls("*") // 所有允许授权的 url + .addAllowRedirectUris("*") // 所有允许授权的 url // ... } return null; @@ -23,7 +23,7 @@ public class SaOAuth2DataLoaderImpl implements SaOAuth2DataLoader { } ``` -配置项 `AllowUrls` 意为配置此 `Client` 端所有允许的授权地址,不在此配置项中的 URL 将无法下发 `code` 授权码。 +配置项 `AllowRedirectUris` 意为配置此 `Client` 端所有允许的授权地址,不在此配置项中的 URL 将无法下发 `code` 授权码。 为了方便测试,上述代码将其配置为`*`,但是,在生产环境中,此配置项绝对不能配置为 * ,否则会有被 `code` 劫持的风险。 @@ -40,7 +40,7 @@ public class SaOAuth2DataLoaderImpl implements SaOAuth2DataLoader { ### 2、防范方法 -造成此漏洞的直接原因就是我们对此 client 配置了过于宽泛的 `AllowUrls` 允许授权地址,防范的方法也很简单,就是缩小 `AllowUrls` 授权范围。 +造成此漏洞的直接原因就是我们对此 client 配置了过于宽泛的 `AllowRedirectUris` 允许授权地址,防范的方法也很简单,就是缩小 `AllowRedirectUris` 授权范围。 我们将其配置为一个具体的URL: @@ -53,7 +53,7 @@ public class SaOAuth2DataLoaderImpl implements SaOAuth2DataLoader { if("1001".equals(clientId)) { return new SaClientModel() // ... - .addAllowUrls("http://sa-oauth-client.com:8002/") // 所有允许授权的 url + .addAllowRedirectUris("http://sa-oauth-client.com:8002/") // 所有允许授权的 url // ... } return null; @@ -66,7 +66,7 @@ public class SaOAuth2DataLoaderImpl implements SaOAuth2DataLoader { ![oauth2-feifa-rf](https://oss.dev33.cn/sa-token/doc/oauth2-new/oauth2-feifa-rf.png 's-w-sh') -域名没有通过校验,拒绝授权! +URL 没有通过校验,拒绝授权! ### 3、配置安全性参考表 @@ -81,10 +81,18 @@ public class SaOAuth2DataLoaderImpl implements SaOAuth2DataLoader { ### 4、其它规则 1、AllowUrls 配置的地址不允许出现 `@` 字符。 + +- 反例:`http://user@sa-token.cc` +- 反例:`http://sa-oauth-client.com@sa-token.cc` + *详见源码:[SaOAuth2Template.java](https://gitee.com/dromara/sa-token/blob/master/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/template/SaOAuth2Template.java) `checkRightUrl` 方法。* 2、AllowUrls 配置的地址 `*` 通配符只允许出现在字符串末尾,不允许出现在字符串中间位置。 + +- 反例:`http*://sa-oauth-client.com/` +- 反例:`http://*.sa-oauth-client.com/` + *详见源码: [SaOAuth2Template.java](https://gitee.com/dromara/sa-token/blob/master/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/template/SaOAuth2Template.java) `checkAllowUrlListStaticMethod` 方法。* diff --git a/sa-token-doc/oauth2/oauth2-custom-api.md b/sa-token-doc/oauth2/oauth2-custom-api.md index a398c37d..1802a4f1 100644 --- a/sa-token-doc/oauth2/oauth2-custom-api.md +++ b/sa-token-doc/oauth2/oauth2-custom-api.md @@ -12,7 +12,7 @@ @RestController public class SaOAuth2ServerController { - // OAuth2-Server 端:处理所有 OAuth 相关请求 + // OAuth2-Server 端:处理所有 OAuth2 相关请求 @RequestMapping("/oauth2/*") public Object request() { return SaOAuth2ServerProcessor.instance.dister(); @@ -33,7 +33,7 @@ public class SaOAuth2ServerController { ``` java // 配置 OAuth2 相关参数 @Autowired -private void configOAuth2Server(SaOAuth2Config cfg) { +private void configOAuth2Server(SaOAuth2ServerConfig oauth2Server) { // 自定义API地址 SaOAuth2Consts.Api.authorize = "/oauth2/authorize2"; // ... @@ -76,7 +76,7 @@ public class SaOAuth2ServerController { // Code 换 Access-Token || 模式三:密码式 @RequestMapping("/oauth2/token") public Object token() { - return SaOAuth2ServerProcessor.instance.tokenOrPassword(); + return SaOAuth2ServerProcessor.instance.token(); } // Refresh-Token 刷新 Access-Token diff --git a/sa-token-doc/oauth2/oauth2-custom-grant_type.md b/sa-token-doc/oauth2/oauth2-custom-grant_type.md index 071fab88..4714b329 100644 --- a/sa-token-doc/oauth2/oauth2-custom-grant_type.md +++ b/sa-token-doc/oauth2/oauth2-custom-grant_type.md @@ -58,8 +58,9 @@ public class PhoneCodeGrantTypeHandler implements SaOAuth2GrantTypeHandlerInterf } @Override - public AccessTokenModel getAccessTokenModel(SaRequest req, String clientId, List scopes) { + public AccessTokenModel getAccessToken(SaRequest req, String clientId, List scopes) { + // 获取前端提交的参数 String phone = req.getParamNotNull("phone"); String code = req.getParamNotNull("code"); String realCode = SaManager.getSaTokenDao().get("phone_code:" + phone); @@ -102,7 +103,7 @@ public class SaOAuth2DataLoaderImpl implements SaOAuth2DataLoader { return new SaClientModel() .setClientId("1001") .setClientSecret("aaaa-bbbb-cccc-dddd-eeee") - .addAllowUrls("*") + .addAllowRedirectUris("*") // 所有允许授权的 url .addContractScopes("openid", "userid", "userinfo") .addAllowGrantTypes( GrantType.authorization_code, diff --git a/sa-token-doc/oauth2/oauth2-custom-login.md b/sa-token-doc/oauth2/oauth2-custom-login.md index 25cb0bb1..2a23e7a6 100644 --- a/sa-token-doc/oauth2/oauth2-custom-login.md +++ b/sa-token-doc/oauth2/oauth2-custom-login.md @@ -10,9 +10,9 @@ ``` java @Autowired -public void configOAuth2Server(SaOAuth2Config cfg) { +public void configOAuth2Server(SaOAuth2ServerConfig oauth2Server) { // 配置:未登录时返回的View - cfg.notLoginView = ()->{ + oauth2Server.notLoginView = ()->{ return new ModelAndView("xxx.html"); }; } @@ -64,9 +64,9 @@ public SaResult ss(String name, String pwd) { ``` java @Autowired -public void configOAuth2Server(SaOAuth2Config cfg) { +public void configOAuth2Server(SaOAuth2ServerConfig oauth2Server) { // 配置:授权确认视图 - cfg.confirmView = (clientId, scopes)->{ + oauth2Server.confirmView = (clientId, scopes)->{ Map map = new HashMap<>(); map.put("clientId", clientId); map.put("scope", scopes); diff --git a/sa-token-doc/oauth2/oauth2-custom-scope-handler.md b/sa-token-doc/oauth2/oauth2-custom-scope.md similarity index 100% rename from sa-token-doc/oauth2/oauth2-custom-scope-handler.md rename to sa-token-doc/oauth2/oauth2-custom-scope.md diff --git a/sa-token-doc/oauth2/oauth2-interworking.md b/sa-token-doc/oauth2/oauth2-interworking.md index 002ec431..77c0b33c 100644 --- a/sa-token-doc/oauth2/oauth2-interworking.md +++ b/sa-token-doc/oauth2/oauth2-interworking.md @@ -1,4 +1,4 @@ -# Sa-Token-OAuth2 与登录会话实现数据互通 +# OAuth2 与登录会话实现数据互通 --- @@ -16,29 +16,35 @@ ### OAuth2-Server 端数据互通 -很简单,你只需要在 `SaOAuth2TemplateImpl` 实现类中继续重写 Access-Token 的生成策略: +很简单,你只需要在 `configOAuth2Server` 中重写 Access-Token 的生成策略: ``` java -@Component -public class SaOAuth2TemplateImpl extends SaOAuth2Template { +// Sa-Token OAuth2 定制化配置 +@Autowired +public void configOAuth2Server(SaOAuth2ServerConfig oauth2Server) { + // 其它配置 ... - // ... 其它代码 + // 重写 AccessToken 创建策略,返回会话令牌 + SaOAuth2Strategy.instance.createAccessToken = (clientId, loginId, scopes) -> { + System.out.println("----返回会话令牌"); + return StpUtil.createLoginSession(loginId); + }; - // 重写 Access-Token 生成策略:复用登录会话的Token - @Override - public String randomAccessToken(String clientId, Object loginId, String scope) { - String tokenValue = StpUtil.createLoginSession(loginId); - return tokenValue; - } - } ``` 重启项目,然后在 OAuth2 模块授权登录,现在生成的 `access_token` ,可以用来访问 `satoken` 的会话接口了。 +> [!WARNING| label:注意点] +> 数据互通,让前端与后端的交互更加方便,一个 token 即可访问所有接口,但也一定程度上失去了OAuth2的 “不同 Client 不同权限” 的设计意义, +> 同时也默认每个 Client 都拥有了账号的会话权限(access_token 与 satoken 为同一个)。 +> +> 应该根据自己的架构合理分析是否应该整合数据互通。 + + ### OAuth2-Client 数据互通 -除了Server端,Client端也可以打通 `access_token` 与 `satoken` 会话。做法是在 Client 端拿到 `access_token` 后进行登录时,使用 SaLoginModel 预定登录生成的 Token 值 +除了Server端,Client端也可以打通 `access_token` 与 `satoken` 会话。做法是在 Client 端拿到 `access_token` 后进行登录时,使用 `SaLoginModel` 预定登录生成的 Token 值 ``` java // 1. 获取到access_token @@ -51,13 +57,6 @@ StpUtil.login(uid, SaLoginConfig.setToken(access_token)); ``` -> [!WARNING| label:注意点] -> 数据互通,让前端与后端的交互更加方便,一个 token 即可访问所有接口,但也一定程度上失去了OAuth2的 “不同 Client 不同权限” 的设计意义, -> 同时也默认每个 Client 都拥有了账号的会话权限(access_token 与 satoken 为同一个)。 -> -> 应该根据自己的架构合理分析是否应该整合数据互通。 - - diff --git a/sa-token-doc/oauth2/oauth2-server.md b/sa-token-doc/oauth2/oauth2-server.md index de684040..ab385de2 100644 --- a/sa-token-doc/oauth2/oauth2-server.md +++ b/sa-token-doc/oauth2/oauth2-server.md @@ -23,23 +23,39 @@ ${sa.top.version} - + cn.dev33 sa-token-oauth2 ${sa.top.version} + + + + cn.dev33 + sa-token-redis-jackson + ${sa-token.version} + + + org.apache.commons + commons-pool2 + ``` ``` gradle // Sa-Token 权限认证,在线文档:https://sa-token.cc implementation 'cn.dev33:sa-token-spring-boot-starter:${sa.top.version}' -// Sa-Token-OAuth2.0 模块 +// Sa-Token OAuth2.0 模块 implementation 'cn.dev33:sa-token-oauth2:${sa.top.version}' + +// Sa-Token 整合 Redis (可选) +implementation 'cn.dev33:sa-token-redis-jackson:${sa.top.version}' +implementation 'org.apache.commons:commons-pool2' ``` +注:Redis 相关依赖是非必须的,如果集成了 redis,可以让你更细致的观察到 sa-token-oauth2 的底层数据格式。 ### 3、开放服务 @@ -60,9 +76,16 @@ public class SaOAuth2DataLoaderImpl implements SaOAuth2DataLoader { return new SaClientModel() .setClientId("1001") // client id .setClientSecret("aaaa-bbbb-cccc-dddd-eeee") // client 秘钥 - .addAllowUrls("*") // 所有允许授权的 url + .addAllowRedirectUris("*") // 所有允许授权的 url .addContractScopes("openid", "userid", "userinfo") // 所有签约的权限 - .setIsAutoMode(true); // 是否自动判断开放的授权模式 + .addAllowGrantTypes( // 所有允许的授权模式 + GrantType.authorization_code, // 授权码式 + GrantType.implicit, // 隐式式 + GrantType.refresh_token, // 刷新令牌 + GrantType.password, // 密码式 + GrantType.client_credentials // 客户端模式 + ) + ; } return null; } @@ -83,24 +106,24 @@ public class SaOAuth2DataLoaderImpl implements SaOAuth2DataLoader { 2、新建`SaOAuth2ServerController` ``` java /** - * Sa-OAuth2 Server端 控制器 + * Sa-Token OAuth2 Server端 控制器 */ @RestController public class SaOAuth2ServerController { - // 处理所有OAuth相关请求 + // OAuth2-Server 端:处理所有 OAuth2 相关请求 @RequestMapping("/oauth2/*") public Object request() { System.out.println("------- 进入请求: " + SaHolder.getRequest().getUrl()); - return SaOAuth2Handle.serverRequest(); + return SaOAuth2ServerProcessor.instance.dister(); } - - // Sa-OAuth2 定制化配置 + + // Sa-Token OAuth2 定制化配置 @Autowired - public void setSaOAuth2Config(SaOAuth2Config cfg) { + public void setSaOAuth2Config(SaOAuth2Config oauth2Server) { // 配置:未登录时返回的View - cfg.notLoginView = () -> { + oauth2Server.notLoginView = () -> { String msg = "当前会话在OAuth-Server端尚未登录,请先访问" + " doLogin登录 " + "进行登录之后,刷新页面开始授权"; @@ -108,7 +131,7 @@ public class SaOAuth2ServerController { }; // 配置:登录处理函数 - cfg.doLoginHandle = (name, pwd) -> { + oauth2Server.doLoginHandle = (name, pwd) -> { if("sa".equals(name) && "123456".equals(pwd)) { StpUtil.login(10001); return SaResult.ok(); @@ -117,7 +140,7 @@ public class SaOAuth2ServerController { }; // 配置:确认授权时返回的 view - cfg.confirmView = (clientId, scopes) -> { + oauth2Server.confirmView = (clientId, scopes) -> { String scopeStr = SaFoxUtil.convertListToString(scopes); String yesCode = "fetch('/oauth2/doConfirm?client_id=" + clientId + "&scope=" + scopeStr + "', {method: 'POST'})" + @@ -132,16 +155,9 @@ public class SaOAuth2ServerController { }; } - // 全局异常拦截 - @ExceptionHandler - public SaResult handlerException(Exception e) { - e.printStackTrace(); - return SaResult.error(e.getMessage()); - } - } ``` -注意:在`setDoLoginHandle`函数里如果要获取name, pwd以外的参数,可通过`SaHolder.getRequest().getParam("xxx")`来获取 +注意:在 `doLoginHandle` 函数里如果要获取 name, pwd 以外的参数,可通过 `SaHolder.getRequest().getParam("xxx")` 来获取。 3、全局异常处理 ``` java @@ -164,7 +180,8 @@ public class GlobalExceptionHandler { public class SaOAuth2ServerApplication { public static void main(String[] args) { SpringApplication.run(SaOAuth2ServerApplication.class, args); - System.out.println("\nSa-Token-OAuth Server 端启动成功"); + System.out.println("\nSa-Token-OAuth2 Server 端启动成功"); + System.out.println(SaOAuth2Manager.getConfig()); } } ``` @@ -173,7 +190,7 @@ public class SaOAuth2ServerApplication { ### 4、访问测试 -1、由于暂未搭建Client端,我们可以使用Sa-Token官网作为重定向URL进行测试: +1、由于暂未搭建Client端,我们可以使用 Sa-Token 官网作为重定向URL进行测试: ``` url http://sa-oauth-server.com:8000/oauth2/authorize?response_type=code&client_id=1001&redirect_uri=https://sa-token.cc&scope=openid ``` @@ -185,7 +202,7 @@ http://sa-oauth-server.com:8000/oauth2/authorize?response_type=code&client_id=10 3、点击doLogin进行登录之后刷新页面,会提示我们确认授权 ![sa-oauth2-server-scope](https://oss.dev33.cn/sa-token/doc/oauth2-new/sa-oauth2-server-scope.png 's-w-sh') -4、点击确认授权之后刷新页面,我们会被重定向至 redirect_uri 页面,并携带了code参数 +4、点击同意授权之后,我们会被重定向至 redirect_uri 页面,并携带了code参数 ![sa-oauth2-server-code](https://oss.dev33.cn/sa-token/doc/oauth2-new/sa-oauth2-server-code.png 's-w-sh') @@ -194,7 +211,7 @@ http://sa-oauth-server.com:8000/oauth2/authorize?response_type=code&client_id=10 http://sa-oauth-server.com:8000/oauth2/token?grant_type=authorization_code&client_id=1001&client_secret=aaaa-bbbb-cccc-dddd-eeee&code={code} ``` -将得到 `Access-Token`、`Refresh-Token`、`openid`等授权信息 +将得到 `Access-Token`、`Refresh-Token`、`openid`等授权信息: ``` js { diff --git a/sa-token-doc/up/integ-redis.md b/sa-token-doc/up/integ-redis.md index b01ec4de..e0c18701 100644 --- a/sa-token-doc/up/integ-redis.md +++ b/sa-token-doc/up/integ-redis.md @@ -73,7 +73,7 @@ implementation 'cn.dev33:sa-token-redis-jackson:${sa.top.version}' ``` ``` gradle -// Sa-Token 整合 Redis (使用 jackson 序列化方式) +// 提供Redis连接池 implementation 'org.apache.commons:commons-pool2' ``` diff --git a/sa-token-doc/use/config.md b/sa-token-doc/use/config.md index 89a97a97..bc314b06 100644 --- a/sa-token-doc/use/config.md +++ b/sa-token-doc/use/config.md @@ -294,18 +294,21 @@ sa-token.sso-client.is-slo=true ### 4、OAuth2.0相关配置 -| 参数名称 | 类型 | 默认值 | 说明 | -| :-------- | :-------- | :-------- | :-------- | -| isCode | Boolean | true | 是否打开模式:授权码(`Authorization Code`) | -| isImplicit | Boolean | true | 是否打开模式:隐藏式(`Implicit`) | -| isPassword | Boolean | true | 是否打开模式:密码式(`Password`) | -| isClient | Boolean | true | 是否打开模式:凭证式(`Client Credentials`) | -| isNewRefresh | Boolean | false | 是否在每次 `Refresh-Token` 刷新 `Access-Token` 时,产生一个新的 Refresh-Token | -| codeTimeout | long | 300 | Code授权码 保存的时间(单位:秒) 默认五分钟 | -| accessTokenTimeout | long | 7200 | `Access-Token` 保存的时间(单位:秒)默认两个小时 | -| refreshTokenTimeout | long | 2592000 | `Refresh-Token` 保存的时间(单位:秒) 默认30 天 | -| clientTokenTimeout | long | 7200 | `Client-Token` 保存的时间(单位:秒) 默认两个小时 | -| pastClientTokenTimeout | long | 7200 | `Past-Client-Token` 保存的时间(单位:秒) ,默认为-1,代表延续 `Client-Token` 的有效时间 | +| 参数名称 | 类型 | 默认值 | 说明 | +| :-------- | :-------- | :-------- | :-------- | +| enableAuthorizationCode | Boolean | true | 是否打开模式:授权码(`Authorization Code`) | +| enableImplicit | Boolean | true | 是否打开模式:隐藏式(`Implicit`) | +| enablePassword | Boolean | true | 是否打开模式:密码式(`Password`) | +| enableClientCredentials | Boolean | true | 是否打开模式:凭证式(`Client Credentials`) | +| isNewRefresh | Boolean | false | 是否在每次 `Refresh-Token` 刷新 `Access-Token` 时,产生一个新的 `Refresh-Token` | +| codeTimeout | long | 300 | Code授权码 保存的时间(单位:秒) 默认五分钟 | +| accessTokenTimeout | long | 7200 | `Access-Token` 保存的时间(单位:秒)默认两个小时 | +| refreshTokenTimeout | long | 2592000 | `Refresh-Token` 保存的时间(单位:秒) 默认30 天 | +| clientTokenTimeout | long | 7200 | `Client-Token` 保存的时间(单位:秒) 默认两个小时 | +| pastClientTokenTimeout | long | 7200 | `Past-Client-Token` 保存的时间(单位:秒) ,默认为-1,代表延续 `Client-Token` 的有效时间 | +| openidDigestPrefix | String | openid_default_digest_prefix | 默认 openid 生成算法中使用的摘要前缀 | +| higherScope | String | | 指定高级权限,多个用逗号隔开 | +| lowerScope | String | | 指定低级权限,多个用逗号隔开 | 配置示例: @@ -313,44 +316,40 @@ sa-token.sso-client.is-slo=true ``` yaml # Sa-Token 配置 sa-token: - token-name: satoken-server + token-name: sa-token-oauth2-server # OAuth2.0 配置 - oauth2: - is-code: true - is-implicit: true - is-password: true - is-client: true + oauth2-server: + enable-authorization-code: true + enable-implicit: true + enable-password: true + enable-client-credentials: true ``` ``` properties # Sa-Token 配置 -sa-token.token-name=satoken-server +sa-token.token-name=sa-token-oauth2-server # OAuth2.0 配置 -sa-token.oauth2.is-code=true -sa-token.oauth2.is-implicit=true -sa-token.oauth2.is-password=true -sa-token.oauth2.is-client=true +sa-token.oauth2-server.enable-authorization-code=true +sa-token.oauth2-server.enable-implicit=true +sa-token.oauth2-server.enable-password=true +sa-token.oauth2-server.enable-client-credentials=true ``` ##### SaClientModel属性定义 -| 参数名称 | 类型 | 默认值 | 说明 | -| :-------- | :-------- | :-------- | :-------- | -| clientId | String | null | 应用id,应该全局唯一 | -| clientSecret | String | null | 应用秘钥 | -| contractScope | String | null | 应用签约的所有权限, 多个用逗号隔开 | -| allowUrl | String | null | 应用允许授权的所有URL, 多个用逗号隔开 (可以使用 `*` 号通配符) | -| isCode | Boolean | false | 单独配置此 Client 是否打开模式:授权码(`Authorization Code`) | -| isImplicit | Boolean | false | 单独配置此 Client 是否打开模式:隐藏式(`Implicit`) | -| isPassword | Boolean | false | 单独配置此 Client 是否打开模式:密码式(`Password`) | -| isClient | Boolean | false | 单独配置此 Client 是否打开模式:凭证式(`Client Credentials`) | -| isAutoMode | Boolean | true | 是否自动判断此 Client 开放的授权模式。 参考:[详解](/use/config?id=配置项详解:isAutoMode) | -| isNewRefresh | Boolean | 取全局配置 | 单独配置此Client:是否在每次 `Refresh-Token` 刷新 `Access-Token` 时,产生一个新的 Refresh-Token [ 默认取全局配置 ] | -| accessTokenTimeout | long | 取全局配置 | 单独配置此Client:`Access-Token` 保存的时间(单位:秒) [默认取全局配置] | -| refreshTokenTimeout | long | 取全局配置 | 单独配置此Client:`Refresh-Token` 保存的时间(单位:秒) [默认取全局配置] | -| clientTokenTimeout | long | 取全局配置 | 单独配置此Client:`Client-Token` 保存的时间(单位:秒) [默认取全局配置] | -| pastClientTokenTimeout | long | 取全局配置 | 单独配置此Client:`Past-Client-Token` 保存的时间(单位:秒) [默认取全局配置] | +| 参数名称 | 类型 | 默认值 | 说明 | +| :-------- | :-------- | :-------- | :-------- | +| clientId | String | null | 应用id,应该全局唯一 | +| clientSecret | String | null | 应用秘钥 | +| contractScopes | List | null | 应用签约的所有权限 | +| allowUrls | List | null | 应用允许授权的所有URL(可以使用 `*` 号通配符) | +| allowGrantTypes | List | new ArrayList<>() | 应用允许的所有 `grant_type` | +| isNewRefresh | Boolean | 取全局配置 | 单独配置此Client:是否在每次 `Refresh-Token` 刷新 `Access-Token` 时,产生一个新的 Refresh-Token [ 默认取全局配置 ] | +| accessTokenTimeout | long | 取全局配置 | 单独配置此Client:`Access-Token` 保存的时间(单位:秒) [默认取全局配置] | +| refreshTokenTimeout | long | 取全局配置 | 单独配置此Client:`Refresh-Token` 保存的时间(单位:秒) [默认取全局配置] | +| clientTokenTimeout | long | 取全局配置 | 单独配置此Client:`Client-Token` 保存的时间(单位:秒) [默认取全局配置] | +| pastClientTokenTimeout | long | 取全局配置 | 单独配置此Client:`Past-Client-Token` 保存的时间(单位:秒) [默认取全局配置] | @@ -392,14 +391,14 @@ sa-token.oauth2.is-client=true 但是 —— 有的场景下我们又确实需要在登录之前就使用 Token-Session 对象,这时候就把配置项 `tokenSessionCheckLogin` 值改为 `false` 即可。 - + #### 配置项详解:isHttp diff --git a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/SaOAuth2Manager.java b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/SaOAuth2Manager.java index 8521d353..8ba535b8 100644 --- a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/SaOAuth2Manager.java +++ b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/SaOAuth2Manager.java @@ -15,7 +15,7 @@ */ package cn.dev33.satoken.oauth2; -import cn.dev33.satoken.oauth2.config.SaOAuth2Config; +import cn.dev33.satoken.oauth2.config.SaOAuth2ServerConfig; import cn.dev33.satoken.oauth2.dao.SaOAuth2Dao; import cn.dev33.satoken.oauth2.dao.SaOAuth2DaoDefaultImpl; import cn.dev33.satoken.oauth2.data.convert.SaOAuth2DataConverter; @@ -41,19 +41,19 @@ public class SaOAuth2Manager { /** * OAuth2 配置 Bean */ - private static volatile SaOAuth2Config config; - public static SaOAuth2Config getConfig() { + private static volatile SaOAuth2ServerConfig config; + public static SaOAuth2ServerConfig getConfig() { if (config == null) { // 初始化默认值 synchronized (SaOAuth2Manager.class) { if (config == null) { - setConfig(new SaOAuth2Config()); + setConfig(new SaOAuth2ServerConfig()); } } } return config; } - public static void setConfig(SaOAuth2Config config) { + public static void setConfig(SaOAuth2ServerConfig config) { SaOAuth2Manager.config = config; } diff --git a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/config/SaOAuth2Config.java b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/config/SaOAuth2ServerConfig.java similarity index 79% rename from sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/config/SaOAuth2Config.java rename to sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/config/SaOAuth2ServerConfig.java index 0bb39073..1ae2e05f 100644 --- a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/config/SaOAuth2Config.java +++ b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/config/SaOAuth2ServerConfig.java @@ -24,17 +24,17 @@ import cn.dev33.satoken.util.SaResult; import java.io.Serializable; /** - * Sa-Token-OAuth2 配置类 Model + * Sa-Token OAuth2 Server 端 配置类 Model * * @author click33 * @since 1.19.0 */ -public class SaOAuth2Config implements Serializable { +public class SaOAuth2ServerConfig implements Serializable { private static final long serialVersionUID = -6541180061782004705L; /** 是否打开模式:授权码(Authorization Code) */ - public Boolean enableCode = true; + public Boolean enableAuthorizationCode = true; /** 是否打开模式:隐藏式(Implicit) */ public Boolean enableImplicit = true; @@ -43,7 +43,7 @@ public class SaOAuth2Config implements Serializable { public Boolean enablePassword = true; /** 是否打开模式:凭证式(Client Credentials) */ - public Boolean enableClient = true; + public Boolean enableClientCredentials = true; /** 是否在每次 Refresh-Token 刷新 Access-Token 时,产生一个新的 Refresh-Token */ public Boolean isNewRefresh = false; @@ -75,16 +75,16 @@ public class SaOAuth2Config implements Serializable { /** * @return enableCode */ - public Boolean getEnableCode() { - return enableCode; + public Boolean getEnableAuthorizationCode() { + return enableAuthorizationCode; } /** - * @param enableCode 要设置的 enableCode + * @param enableAuthorizationCode 要设置的 enableAuthorizationCode * @return / */ - public SaOAuth2Config setEnableCode(Boolean enableCode) { - this.enableCode = enableCode; + public SaOAuth2ServerConfig setEnableAuthorizationCode(Boolean enableAuthorizationCode) { + this.enableAuthorizationCode = enableAuthorizationCode; return this; } @@ -99,7 +99,7 @@ public class SaOAuth2Config implements Serializable { * @param enableImplicit 要设置的 enableImplicit * @return / */ - public SaOAuth2Config setEnableImplicit(Boolean enableImplicit) { + public SaOAuth2ServerConfig setEnableImplicit(Boolean enableImplicit) { this.enableImplicit = enableImplicit; return this; } @@ -114,24 +114,24 @@ public class SaOAuth2Config implements Serializable { /** * @param enablePassword 要设置的 enablePassword */ - public SaOAuth2Config setEnablePassword(Boolean enablePassword) { + public SaOAuth2ServerConfig setEnablePassword(Boolean enablePassword) { this.enablePassword = enablePassword; return this; } /** - * @return enableClient + * @return enableClientCredentials */ - public Boolean getEnableClient() { - return enableClient; + public Boolean getEnableClientCredentials() { + return enableClientCredentials; } /** - * @param enableClient 要设置的 enableClient + * @param enableClientCredentials 要设置的 enableClientCredentials * @return / */ - public SaOAuth2Config setEnableClient(Boolean enableClient) { - this.enableClient = enableClient; + public SaOAuth2ServerConfig setEnableClientCredentials(Boolean enableClientCredentials) { + this.enableClientCredentials = enableClientCredentials; return this; } @@ -146,7 +146,7 @@ public class SaOAuth2Config implements Serializable { * @param isNewRefresh 要设置的 isNewRefresh * @return / */ - public SaOAuth2Config setIsNewRefresh(Boolean isNewRefresh) { + public SaOAuth2ServerConfig setIsNewRefresh(Boolean isNewRefresh) { this.isNewRefresh = isNewRefresh; return this; } @@ -162,7 +162,7 @@ public class SaOAuth2Config implements Serializable { * @param codeTimeout 要设置的 codeTimeout * @return 对象自身 */ - public SaOAuth2Config setCodeTimeout(long codeTimeout) { + public SaOAuth2ServerConfig setCodeTimeout(long codeTimeout) { this.codeTimeout = codeTimeout; return this; } @@ -178,7 +178,7 @@ public class SaOAuth2Config implements Serializable { * @param accessTokenTimeout 要设置的 accessTokenTimeout * @return 对象自身 */ - public SaOAuth2Config setAccessTokenTimeout(long accessTokenTimeout) { + public SaOAuth2ServerConfig setAccessTokenTimeout(long accessTokenTimeout) { this.accessTokenTimeout = accessTokenTimeout; return this; } @@ -194,7 +194,7 @@ public class SaOAuth2Config implements Serializable { * @param refreshTokenTimeout 要设置的 refreshTokenTimeout * @return 对象自身 */ - public SaOAuth2Config setRefreshTokenTimeout(long refreshTokenTimeout) { + public SaOAuth2ServerConfig setRefreshTokenTimeout(long refreshTokenTimeout) { this.refreshTokenTimeout = refreshTokenTimeout; return this; } @@ -210,7 +210,7 @@ public class SaOAuth2Config implements Serializable { * @param clientTokenTimeout 要设置的 clientTokenTimeout * @return 对象自身 */ - public SaOAuth2Config setClientTokenTimeout(long clientTokenTimeout) { + public SaOAuth2ServerConfig setClientTokenTimeout(long clientTokenTimeout) { this.clientTokenTimeout = clientTokenTimeout; return this; } @@ -226,7 +226,7 @@ public class SaOAuth2Config implements Serializable { * @param pastClientTokenTimeout 要设置的 pastClientTokenTimeout * @return 对象自身 */ - public SaOAuth2Config setPastClientTokenTimeout(long pastClientTokenTimeout) { + public SaOAuth2ServerConfig setPastClientTokenTimeout(long pastClientTokenTimeout) { this.pastClientTokenTimeout = pastClientTokenTimeout; return this; } @@ -242,7 +242,7 @@ public class SaOAuth2Config implements Serializable { * @param openidDigestPrefix 要设置的 openidDigestPrefix * @return 对象自身 */ - public SaOAuth2Config setOpenidDigestPrefix(String openidDigestPrefix) { + public SaOAuth2ServerConfig setOpenidDigestPrefix(String openidDigestPrefix) { this.openidDigestPrefix = openidDigestPrefix; return this; } @@ -262,7 +262,7 @@ public class SaOAuth2Config implements Serializable { * @param higherScope 指定高级权限,多个用逗号隔开 * @return / */ - public SaOAuth2Config setHigherScope(String higherScope) { + public SaOAuth2ServerConfig setHigherScope(String higherScope) { this.higherScope = higherScope; return this; } @@ -282,7 +282,7 @@ public class SaOAuth2Config implements Serializable { * @param lowerScope 指定低级权限,多个用逗号隔开 * @return / */ - public SaOAuth2Config setLowerScope(String lowerScope) { + public SaOAuth2ServerConfig setLowerScope(String lowerScope) { this.lowerScope = lowerScope; return this; } @@ -307,11 +307,11 @@ public class SaOAuth2Config implements Serializable { @Override public String toString() { - return "SaOAuth2Config{" + - "enableCode=" + enableCode + + return "SaOAuth2ServerConfig{" + + "enableAuthorizationCode=" + enableAuthorizationCode + ", enableImplicit=" + enableImplicit + ", enablePassword=" + enablePassword + - ", enableClient=" + enableClient + + ", enableClientCredentials=" + enableClientCredentials + ", isNewRefresh=" + isNewRefresh + ", codeTimeout=" + codeTimeout + ", accessTokenTimeout=" + accessTokenTimeout + diff --git a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/convert/SaOAuth2DataConverterDefaultImpl.java b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/convert/SaOAuth2DataConverterDefaultImpl.java index 5212fc43..1c8865f5 100644 --- a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/convert/SaOAuth2DataConverterDefaultImpl.java +++ b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/convert/SaOAuth2DataConverterDefaultImpl.java @@ -23,7 +23,7 @@ import cn.dev33.satoken.oauth2.data.model.loader.SaClientModel; import cn.dev33.satoken.oauth2.strategy.SaOAuth2Strategy; import cn.dev33.satoken.util.SaFoxUtil; -import java.util.Collections; +import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; @@ -41,7 +41,7 @@ public class SaOAuth2DataConverterDefaultImpl implements SaOAuth2DataConverter { @Override public List convertScopeStringToList(String scopeString) { if(SaFoxUtil.isEmpty(scopeString)) { - return Collections.emptyList(); + return new ArrayList<>(); } // 兼容以下三种分隔符:空格、逗号、%20 scopeString = scopeString.replaceAll(" ", ","); @@ -63,7 +63,7 @@ public class SaOAuth2DataConverterDefaultImpl implements SaOAuth2DataConverter { @Override public List convertAllowUrlStringToList(String allowUrl) { if(SaFoxUtil.isEmpty(allowUrl)) { - return Collections.emptyList(); + return new ArrayList<>(); } return SaFoxUtil.convertStringToList(allowUrl); } diff --git a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/model/loader/SaClientModel.java b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/model/loader/SaClientModel.java index f84ce3d2..e6ae542d 100644 --- a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/model/loader/SaClientModel.java +++ b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/model/loader/SaClientModel.java @@ -16,7 +16,7 @@ package cn.dev33.satoken.oauth2.data.model.loader; import cn.dev33.satoken.oauth2.SaOAuth2Manager; -import cn.dev33.satoken.oauth2.config.SaOAuth2Config; +import cn.dev33.satoken.oauth2.config.SaOAuth2ServerConfig; import java.io.Serializable; import java.util.ArrayList; @@ -49,9 +49,9 @@ public class SaClientModel implements Serializable { public List contractScopes; /** - * 应用允许授权的所有URL + * 应用允许授权的所有 redirect_uri */ - public List allowUrls; + public List allowRedirectUris; /** * 应用允许的所有 grant_type @@ -75,19 +75,19 @@ public class SaClientModel implements Serializable { public SaClientModel() { - SaOAuth2Config config = SaOAuth2Manager.getConfig(); + SaOAuth2ServerConfig config = SaOAuth2Manager.getConfig(); this.isNewRefresh = config.getIsNewRefresh(); this.accessTokenTimeout = config.getAccessTokenTimeout(); this.refreshTokenTimeout = config.getRefreshTokenTimeout(); this.clientTokenTimeout = config.getClientTokenTimeout(); this.pastClientTokenTimeout = config.getPastClientTokenTimeout(); } - public SaClientModel(String clientId, String clientSecret, List contractScopes, List allowUrls) { + public SaClientModel(String clientId, String clientSecret, List contractScopes, List allowRedirectUris) { super(); this.clientId = clientId; this.clientSecret = clientSecret; this.contractScopes = contractScopes; - this.allowUrls = allowUrls; + this.allowRedirectUris = allowRedirectUris; } /** @@ -139,18 +139,18 @@ public class SaClientModel implements Serializable { } /** - * @return 应用允许授权的所有URL + * @return 应用允许授权的所有 redirect_uri */ - public List getAllowUrls() { - return allowUrls; + public List getAllowRedirectUris() { + return allowRedirectUris; } /** - * @param allowUrls 应用允许授权的所有URL + * @param allowRedirectUris 应用允许授权的所有 redirect_uri * @return 对象自身 */ - public SaClientModel setAllowUrls(List allowUrls) { - this.allowUrls = allowUrls; + public SaClientModel setAllowRedirectUris(List allowRedirectUris) { + this.allowRedirectUris = allowRedirectUris; return this; } @@ -259,7 +259,7 @@ public class SaClientModel implements Serializable { "clientId='" + clientId + '\'' + ", clientSecret='" + clientSecret + '\'' + ", contractScopes=" + contractScopes + - ", allowUrls=" + allowUrls + + ", allowRedirectUris=" + allowRedirectUris + ", allowGrantTypes=" + allowGrantTypes + ", isNewRefresh=" + isNewRefresh + ", accessTokenTimeout=" + accessTokenTimeout + @@ -285,14 +285,14 @@ public class SaClientModel implements Serializable { } /** - * @param urls 添加应用允许授权的所有URL + * @param redirectUris 添加应用允许授权的所有 redirect_uri * @return 对象自身 */ - public SaClientModel addAllowUrls(String... urls) { - if(this.allowUrls == null) { - this.allowUrls = new ArrayList<>(); + public SaClientModel addAllowRedirectUris(String... redirectUris) { + if(this.allowRedirectUris == null) { + this.allowRedirectUris = new ArrayList<>(); } - this.allowUrls.addAll(Arrays.asList(urls)); + this.allowRedirectUris.addAll(Arrays.asList(redirectUris)); return this; } diff --git a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/granttype/handler/AuthorizationCodeGrantTypeHandler.java b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/granttype/handler/AuthorizationCodeGrantTypeHandler.java index 1f80841b..00de1e0c 100644 --- a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/granttype/handler/AuthorizationCodeGrantTypeHandler.java +++ b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/granttype/handler/AuthorizationCodeGrantTypeHandler.java @@ -38,7 +38,7 @@ public class AuthorizationCodeGrantTypeHandler implements SaOAuth2GrantTypeHandl } @Override - public AccessTokenModel getAccessTokenModel(SaRequest req, String clientId, List scopes) { + public AccessTokenModel getAccessToken(SaRequest req, String clientId, List scopes) { // 获取参数 ClientIdAndSecretModel clientIdAndSecret = SaOAuth2Manager.getDataResolver().readClientIdAndSecret(req); // String clientId = clientIdAndSecret.clientId; diff --git a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/granttype/handler/PasswordGrantTypeHandler.java b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/granttype/handler/PasswordGrantTypeHandler.java index 89a89df2..1609e355 100644 --- a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/granttype/handler/PasswordGrantTypeHandler.java +++ b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/granttype/handler/PasswordGrantTypeHandler.java @@ -40,7 +40,7 @@ public class PasswordGrantTypeHandler implements SaOAuth2GrantTypeHandlerInterfa } @Override - public AccessTokenModel getAccessTokenModel(SaRequest req, String clientId, List scopes) { + public AccessTokenModel getAccessToken(SaRequest req, String clientId, List scopes) { // 1、获取请求参数 String username = req.getParamNotNull(SaOAuth2Consts.Param.username); diff --git a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/granttype/handler/RefreshTokenGrantTypeHandler.java b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/granttype/handler/RefreshTokenGrantTypeHandler.java index b526f7bf..238e35c1 100644 --- a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/granttype/handler/RefreshTokenGrantTypeHandler.java +++ b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/granttype/handler/RefreshTokenGrantTypeHandler.java @@ -40,7 +40,7 @@ public class RefreshTokenGrantTypeHandler implements SaOAuth2GrantTypeHandlerInt } @Override - public AccessTokenModel getAccessTokenModel(SaRequest req, String clientId, List scopes) { + public AccessTokenModel getAccessToken(SaRequest req, String clientId, List scopes) { // 获取参数 String refreshToken = req.getParamNotNull(SaOAuth2Consts.Param.refresh_token); diff --git a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/granttype/handler/SaOAuth2GrantTypeHandlerInterface.java b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/granttype/handler/SaOAuth2GrantTypeHandlerInterface.java index c07868e1..48d47a19 100644 --- a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/granttype/handler/SaOAuth2GrantTypeHandlerInterface.java +++ b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/granttype/handler/SaOAuth2GrantTypeHandlerInterface.java @@ -41,6 +41,6 @@ public interface SaOAuth2GrantTypeHandlerInterface { * @param req / * @return / */ - AccessTokenModel getAccessTokenModel(SaRequest req, String clientId, List scopes); + AccessTokenModel getAccessToken(SaRequest req, String clientId, List scopes); } \ No newline at end of file diff --git a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/processor/SaOAuth2ServerProcessor.java b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/processor/SaOAuth2ServerProcessor.java index feaa02de..ed8cc38b 100644 --- a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/processor/SaOAuth2ServerProcessor.java +++ b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/processor/SaOAuth2ServerProcessor.java @@ -19,7 +19,7 @@ import cn.dev33.satoken.context.SaHolder; import cn.dev33.satoken.context.model.SaRequest; import cn.dev33.satoken.context.model.SaResponse; import cn.dev33.satoken.oauth2.SaOAuth2Manager; -import cn.dev33.satoken.oauth2.config.SaOAuth2Config; +import cn.dev33.satoken.oauth2.config.SaOAuth2ServerConfig; import cn.dev33.satoken.oauth2.consts.GrantType; import cn.dev33.satoken.oauth2.consts.SaOAuth2Consts; import cn.dev33.satoken.oauth2.consts.SaOAuth2Consts.Api; @@ -113,7 +113,7 @@ public class SaOAuth2ServerProcessor { // 获取变量 SaRequest req = SaHolder.getRequest(); SaResponse res = SaHolder.getResponse(); - SaOAuth2Config cfg = SaOAuth2Manager.getConfig(); + SaOAuth2ServerConfig cfg = SaOAuth2Manager.getConfig(); SaOAuth2DataGenerate dataGenerate = SaOAuth2Manager.getDataGenerate(); SaOAuth2Template oauth2Template = SaOAuth2Manager.getTemplate(); String responseType = req.getParamNotNull(Param.response_type); @@ -218,7 +218,7 @@ public class SaOAuth2ServerProcessor { public Object doLogin() { // 获取变量 SaRequest req = SaHolder.getRequest(); - SaOAuth2Config cfg = SaOAuth2Manager.getConfig(); + SaOAuth2ServerConfig cfg = SaOAuth2Manager.getConfig(); return cfg.doLoginHandle.apply(req.getParam(Param.name), req.getParam(Param.pwd)); } @@ -285,14 +285,14 @@ public class SaOAuth2ServerProcessor { public Object clientToken() { // 获取变量 SaRequest req = SaHolder.getRequest(); - SaOAuth2Config cfg = SaOAuth2Manager.getConfig(); + SaOAuth2ServerConfig cfg = SaOAuth2Manager.getConfig(); SaOAuth2Template oauth2Template = SaOAuth2Manager.getTemplate(); String grantType = req.getParamNotNull(Param.grant_type); if(!grantType.equals(GrantType.client_credentials)) { throw new SaOAuth2Exception("无效 grant_type:" + grantType).setCode(SaOAuth2ErrorCode.CODE_30126); } - if(!cfg.enableClient) { + if(!cfg.enableClientCredentials) { throwErrorSystemNotEnableModel(); } if(!currClientModel().getAllowGrantTypes().contains(GrantType.client_credentials)) { @@ -335,10 +335,10 @@ public class SaOAuth2ServerProcessor { /** * 校验 authorize 路由的 ResponseType 参数 */ - public void checkAuthorizeResponseType(String responseType, SaRequest req, SaOAuth2Config cfg) { + public void checkAuthorizeResponseType(String responseType, SaRequest req, SaOAuth2ServerConfig cfg) { // 模式一:Code授权码 if(responseType.equals(ResponseType.code)) { - if(!cfg.enableCode) { + if(!cfg.enableAuthorizationCode) { throwErrorSystemNotEnableModel(); } if(!currClientModel().getAllowGrantTypes().contains(GrantType.authorization_code)) { diff --git a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/strategy/SaOAuth2Strategy.java b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/strategy/SaOAuth2Strategy.java index 70affdc3..dbfda655 100644 --- a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/strategy/SaOAuth2Strategy.java +++ b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/strategy/SaOAuth2Strategy.java @@ -17,7 +17,7 @@ package cn.dev33.satoken.oauth2.strategy; import cn.dev33.satoken.SaManager; import cn.dev33.satoken.oauth2.SaOAuth2Manager; -import cn.dev33.satoken.oauth2.config.SaOAuth2Config; +import cn.dev33.satoken.oauth2.config.SaOAuth2ServerConfig; import cn.dev33.satoken.oauth2.consts.GrantType; import cn.dev33.satoken.oauth2.consts.SaOAuth2Consts; import cn.dev33.satoken.oauth2.data.model.loader.SaClientModel; @@ -170,8 +170,8 @@ public final class SaOAuth2Strategy { } // 看看全局是否开启了此 grantType - SaOAuth2Config config = SaOAuth2Manager.getConfig(); - if(grantType.equals(GrantType.authorization_code) && !config.getEnableCode() ) { + SaOAuth2ServerConfig config = SaOAuth2Manager.getConfig(); + if(grantType.equals(GrantType.authorization_code) && !config.getEnableAuthorizationCode() ) { throw new SaOAuth2Exception("系统未开放的 grant_type: " + grantType); } if(grantType.equals(GrantType.password) && !config.getEnablePassword() ) { @@ -189,7 +189,7 @@ public final class SaOAuth2Strategy { } // 调用 处理器 - return grantTypeHandler.getAccessTokenModel(req, clientIdAndSecretModel.getClientId(), scopes); + return grantTypeHandler.getAccessToken(req, clientIdAndSecretModel.getClientId(), scopes); }; diff --git a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/template/SaOAuth2Template.java b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/template/SaOAuth2Template.java index 3062f525..cbfeedbb 100644 --- a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/template/SaOAuth2Template.java +++ b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/template/SaOAuth2Template.java @@ -224,8 +224,8 @@ public class SaOAuth2Template { // 4、是否在[允许地址列表]之中 SaClientModel clientModel = checkClientModel(clientId); - checkAllowUrlList(clientModel.allowUrls); - if( ! SaStrategy.instance.hasElement.apply(clientModel.allowUrls, url)) { + checkAllowUrlList(clientModel.allowRedirectUris); + if( ! SaStrategy.instance.hasElement.apply(clientModel.allowRedirectUris, url)) { throw new SaOAuth2Exception("非法 redirect_url: " + url).setCode(SaOAuth2ErrorCode.CODE_30114); } } diff --git a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/oauth2/SaOAuth2AutoConfigure.java b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/oauth2/SaOAuth2AutoConfigure.java index 5c7626c5..dab18067 100644 --- a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/oauth2/SaOAuth2AutoConfigure.java +++ b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/oauth2/SaOAuth2AutoConfigure.java @@ -16,7 +16,7 @@ package cn.dev33.satoken.solon.oauth2; import cn.dev33.satoken.oauth2.SaOAuth2Manager; -import cn.dev33.satoken.oauth2.config.SaOAuth2Config; +import cn.dev33.satoken.oauth2.config.SaOAuth2ServerConfig; import cn.dev33.satoken.oauth2.template.SaOAuth2Template; import cn.dev33.satoken.oauth2.template.SaOAuth2Util; import org.noear.solon.annotation.Bean; @@ -39,7 +39,7 @@ public class SaOAuth2AutoConfigure { SaOAuth2Util.saOAuth2Template = bean; }); - appContext.subBeansOfType(SaOAuth2Config.class, bean -> { + appContext.subBeansOfType(SaOAuth2ServerConfig.class, bean -> { SaOAuth2Manager.setConfig(bean); }); } @@ -48,7 +48,7 @@ public class SaOAuth2AutoConfigure { * 获取 OAuth2配置Bean */ @Bean - public SaOAuth2Config getConfig(@Inject(value = "${sa-token.oauth2}", required = false) SaOAuth2Config oAuth2Config) { + public SaOAuth2ServerConfig getConfig(@Inject(value = "${sa-token.oauth2}", required = false) SaOAuth2ServerConfig oAuth2Config) { return oAuth2Config; } } \ No newline at end of file diff --git a/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/oauth2/SaOAuth2BeanInject.java b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/oauth2/SaOAuth2BeanInject.java index 8511384b..092d7956 100644 --- a/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/oauth2/SaOAuth2BeanInject.java +++ b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/oauth2/SaOAuth2BeanInject.java @@ -16,7 +16,7 @@ package cn.dev33.satoken.spring.oauth2; import cn.dev33.satoken.oauth2.SaOAuth2Manager; -import cn.dev33.satoken.oauth2.config.SaOAuth2Config; +import cn.dev33.satoken.oauth2.config.SaOAuth2ServerConfig; import cn.dev33.satoken.oauth2.dao.SaOAuth2Dao; import cn.dev33.satoken.oauth2.data.convert.SaOAuth2DataConverter; import cn.dev33.satoken.oauth2.data.generate.SaOAuth2DataGenerate; @@ -52,7 +52,7 @@ public class SaOAuth2BeanInject { * @param saOAuth2Config 配置对象 */ @Autowired(required = false) - public void setSaOAuth2Config(SaOAuth2Config saOAuth2Config) { + public void setSaOAuth2Config(SaOAuth2ServerConfig saOAuth2Config) { SaOAuth2Manager.setConfig(saOAuth2Config); } diff --git a/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/oauth2/SaOAuth2BeanRegister.java b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/oauth2/SaOAuth2BeanRegister.java index 2a4a5ed7..788f97af 100644 --- a/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/oauth2/SaOAuth2BeanRegister.java +++ b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/oauth2/SaOAuth2BeanRegister.java @@ -16,7 +16,7 @@ package cn.dev33.satoken.spring.oauth2; import cn.dev33.satoken.oauth2.SaOAuth2Manager; -import cn.dev33.satoken.oauth2.config.SaOAuth2Config; +import cn.dev33.satoken.oauth2.config.SaOAuth2ServerConfig; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; @@ -36,9 +36,9 @@ public class SaOAuth2BeanRegister { * @return 配置对象 */ @Bean - @ConfigurationProperties(prefix = "sa-token.oauth2") - public SaOAuth2Config getSaOAuth2Config() { - return new SaOAuth2Config(); + @ConfigurationProperties(prefix = "sa-token.oauth2-server") + public SaOAuth2ServerConfig getSaOAuth2Config() { + return new SaOAuth2ServerConfig(); } }