细节优化、文档优化
This commit is contained in:
@@ -36,6 +36,7 @@ import cn.dev33.satoken.util.SaFoxUtil;
|
|||||||
import cn.dev33.satoken.util.SaTokenConsts;
|
import cn.dev33.satoken.util.SaTokenConsts;
|
||||||
import cn.dev33.satoken.util.SaValue2Box;
|
import cn.dev33.satoken.util.SaValue2Box;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -2114,7 +2115,7 @@ public class StpLogic {
|
|||||||
// 如果该账号的 Account-Session 为 null,说明此账号尚没有客户端在登录,此时返回空集合
|
// 如果该账号的 Account-Session 为 null,说明此账号尚没有客户端在登录,此时返回空集合
|
||||||
SaSession session = getSessionByLoginId(loginId, false);
|
SaSession session = getSessionByLoginId(loginId, false);
|
||||||
if(session == null) {
|
if(session == null) {
|
||||||
return Collections.emptyList();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 按照设备类型进行筛选
|
// 按照设备类型进行筛选
|
||||||
@@ -2132,7 +2133,7 @@ public class StpLogic {
|
|||||||
// 如果该账号的 Account-Session 为 null,说明此账号尚没有客户端在登录,此时返回空集合
|
// 如果该账号的 Account-Session 为 null,说明此账号尚没有客户端在登录,此时返回空集合
|
||||||
SaSession session = getSessionByLoginId(loginId, false);
|
SaSession session = getSessionByLoginId(loginId, false);
|
||||||
if(session == null) {
|
if(session == null) {
|
||||||
return Collections.emptyList();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 按照设备类型进行筛选
|
// 按照设备类型进行筛选
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@ public class SaOAuth2ServerApplication {
|
|||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(SaOAuth2ServerApplication.class, 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());
|
System.out.println(SaOAuth2Manager.getConfig());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -21,7 +21,7 @@ public class SaOAuth2DataLoaderImpl implements SaOAuth2DataLoader {
|
|||||||
return new SaClientModel()
|
return new SaClientModel()
|
||||||
.setClientId("1001") // client id
|
.setClientId("1001") // client id
|
||||||
.setClientSecret("aaaa-bbbb-cccc-dddd-eeee") // client 秘钥
|
.setClientSecret("aaaa-bbbb-cccc-dddd-eeee") // client 秘钥
|
||||||
.addAllowUrls("*") // 所有允许授权的 url
|
.addAllowRedirectUris("*") // 所有允许授权的 url
|
||||||
.addContractScopes("openid", "userid", "userinfo") // 所有签约的权限
|
.addContractScopes("openid", "userid", "userinfo") // 所有签约的权限
|
||||||
.addAllowGrantTypes( // 所有允许的授权模式
|
.addAllowGrantTypes( // 所有允许的授权模式
|
||||||
GrantType.authorization_code, // 授权码式
|
GrantType.authorization_code, // 授权码式
|
||||||
|
|||||||
+8
-7
@@ -1,7 +1,7 @@
|
|||||||
package com.pj.oauth2;
|
package com.pj.oauth2;
|
||||||
|
|
||||||
import cn.dev33.satoken.context.SaHolder;
|
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.processor.SaOAuth2ServerProcessor;
|
||||||
import cn.dev33.satoken.oauth2.template.SaOAuth2Util;
|
import cn.dev33.satoken.oauth2.template.SaOAuth2Util;
|
||||||
import cn.dev33.satoken.stp.StpUtil;
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
@@ -24,23 +24,23 @@ import java.util.Map;
|
|||||||
@RestController
|
@RestController
|
||||||
public class SaOAuth2ServerController {
|
public class SaOAuth2ServerController {
|
||||||
|
|
||||||
// OAuth2-Server 端:处理所有OAuth相关请求
|
// OAuth2-Server 端:处理所有 OAuth2 相关请求
|
||||||
@RequestMapping("/oauth2/*")
|
@RequestMapping("/oauth2/*")
|
||||||
public Object request() {
|
public Object request() {
|
||||||
System.out.println("------- 进入请求: " + SaHolder.getRequest().getUrl());
|
System.out.println("------- 进入请求: " + SaHolder.getRequest().getUrl());
|
||||||
return SaOAuth2ServerProcessor.instance.dister();
|
return SaOAuth2ServerProcessor.instance.dister();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sa-OAuth2 定制化配置
|
// Sa-Token OAuth2 定制化配置
|
||||||
@Autowired
|
@Autowired
|
||||||
public void configOAuth2Server(SaOAuth2Config cfg) {
|
public void configOAuth2Server(SaOAuth2ServerConfig oauth2Server) {
|
||||||
// 未登录的视图
|
// 未登录的视图
|
||||||
cfg.notLoginView = ()->{
|
oauth2Server.notLoginView = ()->{
|
||||||
return new ModelAndView("login.html");
|
return new ModelAndView("login.html");
|
||||||
};
|
};
|
||||||
|
|
||||||
// 登录处理函数
|
// 登录处理函数
|
||||||
cfg.doLoginHandle = (name, pwd) -> {
|
oauth2Server.doLoginHandle = (name, pwd) -> {
|
||||||
if("sa".equals(name) && "123456".equals(pwd)) {
|
if("sa".equals(name) && "123456".equals(pwd)) {
|
||||||
StpUtil.login(10001);
|
StpUtil.login(10001);
|
||||||
return SaResult.ok();
|
return SaResult.ok();
|
||||||
@@ -49,12 +49,13 @@ public class SaOAuth2ServerController {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 授权确认视图
|
// 授权确认视图
|
||||||
cfg.confirmView = (clientId, scopes)->{
|
oauth2Server.confirmView = (clientId, scopes)->{
|
||||||
Map<String, Object> map = new HashMap<>();
|
Map<String, Object> map = new HashMap<>();
|
||||||
map.put("clientId", clientId);
|
map.put("clientId", clientId);
|
||||||
map.put("scope", scopes);
|
map.put("scope", scopes);
|
||||||
return new ModelAndView("confirm.html", map);
|
return new ModelAndView("confirm.html", map);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -26,8 +26,9 @@ public class PhoneCodeGrantTypeHandler implements SaOAuth2GrantTypeHandlerInterf
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AccessTokenModel getAccessTokenModel(SaRequest req, String clientId, List<String> scopes) {
|
public AccessTokenModel getAccessToken(SaRequest req, String clientId, List<String> scopes) {
|
||||||
|
|
||||||
|
// 获取前端提交的参数
|
||||||
String phone = req.getParamNotNull("phone");
|
String phone = req.getParamNotNull("phone");
|
||||||
String code = req.getParamNotNull("code");
|
String code = req.getParamNotNull("code");
|
||||||
String realCode = SaManager.getSaTokenDao().get("phone_code:" + phone);
|
String realCode = SaManager.getSaTokenDao().get("phone_code:" + phone);
|
||||||
|
|||||||
+4
-4
@@ -4,19 +4,19 @@ server:
|
|||||||
# sa-token配置
|
# sa-token配置
|
||||||
sa-token:
|
sa-token:
|
||||||
# token名称 (同时也是 Cookie 名称)
|
# token名称 (同时也是 Cookie 名称)
|
||||||
token-name: satoken-oauth2-server
|
token-name: sa-token-oauth2-server
|
||||||
# 是否打印操作日志
|
# 是否打印操作日志
|
||||||
is-log: true
|
is-log: true
|
||||||
# OAuth2.0 配置
|
# OAuth2.0 配置
|
||||||
oauth2:
|
oauth2-server:
|
||||||
# 是否全局开启授权码模式
|
# 是否全局开启授权码模式
|
||||||
enable-code: true
|
enable-authorization-code: true
|
||||||
# 是否全局开启 Implicit 模式
|
# 是否全局开启 Implicit 模式
|
||||||
enable-implicit: true
|
enable-implicit: true
|
||||||
# 是否全局开启密码模式
|
# 是否全局开启密码模式
|
||||||
enable-password: true
|
enable-password: true
|
||||||
# 是否全局开启客户端模式
|
# 是否全局开启客户端模式
|
||||||
enable-client: true
|
enable-client-credentials: true
|
||||||
# 定义哪些 scope 是高级权限,多个用逗号隔开
|
# 定义哪些 scope 是高级权限,多个用逗号隔开
|
||||||
# higher-scope: openid,userid
|
# higher-scope: openid,userid
|
||||||
# 定义哪些 scope 是低级权限,多个用逗号隔开
|
# 定义哪些 scope 是低级权限,多个用逗号隔开
|
||||||
|
|||||||
@@ -58,7 +58,7 @@
|
|||||||
- [配置 client 域名校验 ](/oauth2/oauth2-check-domain)
|
- [配置 client 域名校验 ](/oauth2/oauth2-check-domain)
|
||||||
- [定制化登录页面与授权页面](/oauth2/oauth2-custom-login)
|
- [定制化登录页面与授权页面](/oauth2/oauth2-custom-login)
|
||||||
- [自定义 API 路由 ](/oauth2/oauth2-custom-api)
|
- [自定义 API 路由 ](/oauth2/oauth2-custom-api)
|
||||||
- [自定义 Scope 权限以处理器](/oauth2/oauth2-custom-scope-handler)
|
- [自定义 Scope 权限以处理器](/oauth2/oauth2-custom-scope)
|
||||||
- [为 Scope 划分等级](/oauth2/oauth2-scope-level)
|
- [为 Scope 划分等级](/oauth2/oauth2-scope-level)
|
||||||
- [自定义 grant_type](/oauth2/oauth2-custom-grant_type)
|
- [自定义 grant_type](/oauth2/oauth2-custom-grant_type)
|
||||||
- [OAuth2-与登录会话实现数据互通](/oauth2/oauth2-interworking)
|
- [OAuth2-与登录会话实现数据互通](/oauth2/oauth2-interworking)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public class SaOAuth2DataLoaderImpl implements SaOAuth2DataLoader {
|
|||||||
if("1001".equals(clientId)) {
|
if("1001".equals(clientId)) {
|
||||||
return new SaClientModel()
|
return new SaClientModel()
|
||||||
// ...
|
// ...
|
||||||
.addAllowUrls("*") // 所有允许授权的 url
|
.addAllowRedirectUris("*") // 所有允许授权的 url
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -23,7 +23,7 @@ public class SaOAuth2DataLoaderImpl implements SaOAuth2DataLoader {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
配置项 `AllowUrls` 意为配置此 `Client` 端所有允许的授权地址,不在此配置项中的 URL 将无法下发 `code` 授权码。
|
配置项 `AllowRedirectUris` 意为配置此 `Client` 端所有允许的授权地址,不在此配置项中的 URL 将无法下发 `code` 授权码。
|
||||||
|
|
||||||
为了方便测试,上述代码将其配置为`*`,但是,<font color="#FF0000" >在生产环境中,此配置项绝对不能配置为 * </font>,否则会有被 `code` 劫持的风险。
|
为了方便测试,上述代码将其配置为`*`,但是,<font color="#FF0000" >在生产环境中,此配置项绝对不能配置为 * </font>,否则会有被 `code` 劫持的风险。
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ public class SaOAuth2DataLoaderImpl implements SaOAuth2DataLoader {
|
|||||||
|
|
||||||
### 2、防范方法
|
### 2、防范方法
|
||||||
|
|
||||||
造成此漏洞的直接原因就是我们对此 client 配置了过于宽泛的 `AllowUrls` 允许授权地址,防范的方法也很简单,就是缩小 `AllowUrls` 授权范围。
|
造成此漏洞的直接原因就是我们对此 client 配置了过于宽泛的 `AllowRedirectUris` 允许授权地址,防范的方法也很简单,就是缩小 `AllowRedirectUris` 授权范围。
|
||||||
|
|
||||||
我们将其配置为一个具体的URL:
|
我们将其配置为一个具体的URL:
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ public class SaOAuth2DataLoaderImpl implements SaOAuth2DataLoader {
|
|||||||
if("1001".equals(clientId)) {
|
if("1001".equals(clientId)) {
|
||||||
return new SaClientModel()
|
return new SaClientModel()
|
||||||
// ...
|
// ...
|
||||||
.addAllowUrls("http://sa-oauth-client.com:8002/") // 所有允许授权的 url
|
.addAllowRedirectUris("http://sa-oauth-client.com:8002/") // 所有允许授权的 url
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -66,7 +66,7 @@ public class SaOAuth2DataLoaderImpl implements SaOAuth2DataLoader {
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
域名没有通过校验,拒绝授权!
|
URL 没有通过校验,拒绝授权!
|
||||||
|
|
||||||
|
|
||||||
### 3、配置安全性参考表
|
### 3、配置安全性参考表
|
||||||
@@ -81,10 +81,18 @@ public class SaOAuth2DataLoaderImpl implements SaOAuth2DataLoader {
|
|||||||
### 4、其它规则
|
### 4、其它规则
|
||||||
|
|
||||||
1、AllowUrls 配置的地址不允许出现 `@` 字符。
|
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)
|
*详见源码:[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` 方法。*
|
`checkRightUrl` 方法。*
|
||||||
|
|
||||||
2、AllowUrls 配置的地址 `*` 通配符只允许出现在字符串末尾,不允许出现在字符串中间位置。
|
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)
|
*详见源码: [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` 方法。*
|
`checkAllowUrlListStaticMethod` 方法。*
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
@RestController
|
@RestController
|
||||||
public class SaOAuth2ServerController {
|
public class SaOAuth2ServerController {
|
||||||
|
|
||||||
// OAuth2-Server 端:处理所有 OAuth 相关请求
|
// OAuth2-Server 端:处理所有 OAuth2 相关请求
|
||||||
@RequestMapping("/oauth2/*")
|
@RequestMapping("/oauth2/*")
|
||||||
public Object request() {
|
public Object request() {
|
||||||
return SaOAuth2ServerProcessor.instance.dister();
|
return SaOAuth2ServerProcessor.instance.dister();
|
||||||
@@ -33,7 +33,7 @@ public class SaOAuth2ServerController {
|
|||||||
``` java
|
``` java
|
||||||
// 配置 OAuth2 相关参数
|
// 配置 OAuth2 相关参数
|
||||||
@Autowired
|
@Autowired
|
||||||
private void configOAuth2Server(SaOAuth2Config cfg) {
|
private void configOAuth2Server(SaOAuth2ServerConfig oauth2Server) {
|
||||||
// 自定义API地址
|
// 自定义API地址
|
||||||
SaOAuth2Consts.Api.authorize = "/oauth2/authorize2";
|
SaOAuth2Consts.Api.authorize = "/oauth2/authorize2";
|
||||||
// ...
|
// ...
|
||||||
@@ -76,7 +76,7 @@ public class SaOAuth2ServerController {
|
|||||||
// Code 换 Access-Token || 模式三:密码式
|
// Code 换 Access-Token || 模式三:密码式
|
||||||
@RequestMapping("/oauth2/token")
|
@RequestMapping("/oauth2/token")
|
||||||
public Object token() {
|
public Object token() {
|
||||||
return SaOAuth2ServerProcessor.instance.tokenOrPassword();
|
return SaOAuth2ServerProcessor.instance.token();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh-Token 刷新 Access-Token
|
// Refresh-Token 刷新 Access-Token
|
||||||
|
|||||||
@@ -58,8 +58,9 @@ public class PhoneCodeGrantTypeHandler implements SaOAuth2GrantTypeHandlerInterf
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AccessTokenModel getAccessTokenModel(SaRequest req, String clientId, List<String> scopes) {
|
public AccessTokenModel getAccessToken(SaRequest req, String clientId, List<String> scopes) {
|
||||||
|
|
||||||
|
// 获取前端提交的参数
|
||||||
String phone = req.getParamNotNull("phone");
|
String phone = req.getParamNotNull("phone");
|
||||||
String code = req.getParamNotNull("code");
|
String code = req.getParamNotNull("code");
|
||||||
String realCode = SaManager.getSaTokenDao().get("phone_code:" + phone);
|
String realCode = SaManager.getSaTokenDao().get("phone_code:" + phone);
|
||||||
@@ -102,7 +103,7 @@ public class SaOAuth2DataLoaderImpl implements SaOAuth2DataLoader {
|
|||||||
return new SaClientModel()
|
return new SaClientModel()
|
||||||
.setClientId("1001")
|
.setClientId("1001")
|
||||||
.setClientSecret("aaaa-bbbb-cccc-dddd-eeee")
|
.setClientSecret("aaaa-bbbb-cccc-dddd-eeee")
|
||||||
.addAllowUrls("*")
|
.addAllowRedirectUris("*") // 所有允许授权的 url
|
||||||
.addContractScopes("openid", "userid", "userinfo")
|
.addContractScopes("openid", "userid", "userinfo")
|
||||||
.addAllowGrantTypes(
|
.addAllowGrantTypes(
|
||||||
GrantType.authorization_code,
|
GrantType.authorization_code,
|
||||||
|
|||||||
@@ -10,9 +10,9 @@
|
|||||||
|
|
||||||
``` java
|
``` java
|
||||||
@Autowired
|
@Autowired
|
||||||
public void configOAuth2Server(SaOAuth2Config cfg) {
|
public void configOAuth2Server(SaOAuth2ServerConfig oauth2Server) {
|
||||||
// 配置:未登录时返回的View
|
// 配置:未登录时返回的View
|
||||||
cfg.notLoginView = ()->{
|
oauth2Server.notLoginView = ()->{
|
||||||
return new ModelAndView("xxx.html");
|
return new ModelAndView("xxx.html");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -64,9 +64,9 @@ public SaResult ss(String name, String pwd) {
|
|||||||
|
|
||||||
``` java
|
``` java
|
||||||
@Autowired
|
@Autowired
|
||||||
public void configOAuth2Server(SaOAuth2Config cfg) {
|
public void configOAuth2Server(SaOAuth2ServerConfig oauth2Server) {
|
||||||
// 配置:授权确认视图
|
// 配置:授权确认视图
|
||||||
cfg.confirmView = (clientId, scopes)->{
|
oauth2Server.confirmView = (clientId, scopes)->{
|
||||||
Map<String, Object> map = new HashMap<>();
|
Map<String, Object> map = new HashMap<>();
|
||||||
map.put("clientId", clientId);
|
map.put("clientId", clientId);
|
||||||
map.put("scope", scopes);
|
map.put("scope", scopes);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Sa-Token-OAuth2 与登录会话实现数据互通
|
# OAuth2 与登录会话实现数据互通
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -16,20 +16,19 @@
|
|||||||
|
|
||||||
### OAuth2-Server 端数据互通
|
### OAuth2-Server 端数据互通
|
||||||
|
|
||||||
很简单,你只需要在 `SaOAuth2TemplateImpl` 实现类中继续重写 Access-Token 的生成策略:
|
很简单,你只需要在 `configOAuth2Server` 中重写 Access-Token 的生成策略:
|
||||||
|
|
||||||
``` java
|
``` java
|
||||||
@Component
|
// Sa-Token OAuth2 定制化配置
|
||||||
public class SaOAuth2TemplateImpl extends SaOAuth2Template {
|
@Autowired
|
||||||
|
public void configOAuth2Server(SaOAuth2ServerConfig oauth2Server) {
|
||||||
|
// 其它配置 ...
|
||||||
|
|
||||||
// ... 其它代码
|
// 重写 AccessToken 创建策略,返回会话令牌
|
||||||
|
SaOAuth2Strategy.instance.createAccessToken = (clientId, loginId, scopes) -> {
|
||||||
// 重写 Access-Token 生成策略:复用登录会话的Token
|
System.out.println("----返回会话令牌");
|
||||||
@Override
|
return StpUtil.createLoginSession(loginId);
|
||||||
public String randomAccessToken(String clientId, Object loginId, String scope) {
|
};
|
||||||
String tokenValue = StpUtil.createLoginSession(loginId);
|
|
||||||
return tokenValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -37,8 +36,15 @@ public class SaOAuth2TemplateImpl extends SaOAuth2Template {
|
|||||||
重启项目,然后在 OAuth2 模块授权登录,现在生成的 `access_token` ,可以用来访问 `satoken` 的会话接口了。
|
重启项目,然后在 OAuth2 模块授权登录,现在生成的 `access_token` ,可以用来访问 `satoken` 的会话接口了。
|
||||||
|
|
||||||
|
|
||||||
|
> [!WARNING| label:注意点]
|
||||||
|
> 数据互通,让前端与后端的交互更加方便,一个 token 即可访问所有接口,但也一定程度上失去了OAuth2的 “不同 Client 不同权限” 的设计意义,
|
||||||
|
> 同时也默认每个 Client 都拥有了账号的会话权限(access_token 与 satoken 为同一个)。
|
||||||
|
>
|
||||||
|
> 应该根据自己的架构合理分析是否应该整合数据互通。
|
||||||
|
|
||||||
|
|
||||||
### OAuth2-Client 数据互通
|
### OAuth2-Client 数据互通
|
||||||
除了Server端,Client端也可以打通 `access_token` 与 `satoken` 会话。做法是在 Client 端拿到 `access_token` 后进行登录时,使用 SaLoginModel 预定登录生成的 Token 值
|
除了Server端,Client端也可以打通 `access_token` 与 `satoken` 会话。做法是在 Client 端拿到 `access_token` 后进行登录时,使用 `SaLoginModel` 预定登录生成的 Token 值
|
||||||
|
|
||||||
``` java
|
``` java
|
||||||
// 1. 获取到access_token
|
// 1. 获取到access_token
|
||||||
@@ -51,13 +57,6 @@ StpUtil.login(uid, SaLoginConfig.setToken(access_token));
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
> [!WARNING| label:注意点]
|
|
||||||
> 数据互通,让前端与后端的交互更加方便,一个 token 即可访问所有接口,但也一定程度上失去了OAuth2的 “不同 Client 不同权限” 的设计意义,
|
|
||||||
> 同时也默认每个 Client 都拥有了账号的会话权限(access_token 与 satoken 为同一个)。
|
|
||||||
>
|
|
||||||
> 应该根据自己的架构合理分析是否应该整合数据互通。
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -23,23 +23,39 @@
|
|||||||
<version>${sa.top.version}</version>
|
<version>${sa.top.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Sa-Token-OAuth2.0 模块 -->
|
<!-- Sa-Token OAuth2.0 模块 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.dev33</groupId>
|
<groupId>cn.dev33</groupId>
|
||||||
<artifactId>sa-token-oauth2</artifactId>
|
<artifactId>sa-token-oauth2</artifactId>
|
||||||
<version>${sa.top.version}</version>
|
<version>${sa.top.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Sa-Token 整合 Redis (可选) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-redis-jackson</artifactId>
|
||||||
|
<version>${sa-token.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-pool2</artifactId>
|
||||||
|
</dependency>
|
||||||
```
|
```
|
||||||
<!-------- tab:Gradle 方式 -------->
|
<!-------- tab:Gradle 方式 -------->
|
||||||
``` gradle
|
``` gradle
|
||||||
// Sa-Token 权限认证,在线文档:https://sa-token.cc
|
// Sa-Token 权限认证,在线文档:https://sa-token.cc
|
||||||
implementation 'cn.dev33:sa-token-spring-boot-starter:${sa.top.version}'
|
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}'
|
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'
|
||||||
```
|
```
|
||||||
<!---------------------------- tabs:end ---------------------------->
|
<!---------------------------- tabs:end ---------------------------->
|
||||||
|
|
||||||
|
注:Redis 相关依赖是非必须的,如果集成了 redis,可以让你更细致的观察到 sa-token-oauth2 的底层数据格式。
|
||||||
|
|
||||||
|
|
||||||
### 3、开放服务
|
### 3、开放服务
|
||||||
@@ -60,9 +76,16 @@ public class SaOAuth2DataLoaderImpl implements SaOAuth2DataLoader {
|
|||||||
return new SaClientModel()
|
return new SaClientModel()
|
||||||
.setClientId("1001") // client id
|
.setClientId("1001") // client id
|
||||||
.setClientSecret("aaaa-bbbb-cccc-dddd-eeee") // client 秘钥
|
.setClientSecret("aaaa-bbbb-cccc-dddd-eeee") // client 秘钥
|
||||||
.addAllowUrls("*") // 所有允许授权的 url
|
.addAllowRedirectUris("*") // 所有允许授权的 url
|
||||||
.addContractScopes("openid", "userid", "userinfo") // 所有签约的权限
|
.addContractScopes("openid", "userid", "userinfo") // 所有签约的权限
|
||||||
.setIsAutoMode(true); // 是否自动判断开放的授权模式
|
.addAllowGrantTypes( // 所有允许的授权模式
|
||||||
|
GrantType.authorization_code, // 授权码式
|
||||||
|
GrantType.implicit, // 隐式式
|
||||||
|
GrantType.refresh_token, // 刷新令牌
|
||||||
|
GrantType.password, // 密码式
|
||||||
|
GrantType.client_credentials // 客户端模式
|
||||||
|
)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -83,24 +106,24 @@ public class SaOAuth2DataLoaderImpl implements SaOAuth2DataLoader {
|
|||||||
2、新建`SaOAuth2ServerController`
|
2、新建`SaOAuth2ServerController`
|
||||||
``` java
|
``` java
|
||||||
/**
|
/**
|
||||||
* Sa-OAuth2 Server端 控制器
|
* Sa-Token OAuth2 Server端 控制器
|
||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
public class SaOAuth2ServerController {
|
public class SaOAuth2ServerController {
|
||||||
|
|
||||||
// 处理所有OAuth相关请求
|
// OAuth2-Server 端:处理所有 OAuth2 相关请求
|
||||||
@RequestMapping("/oauth2/*")
|
@RequestMapping("/oauth2/*")
|
||||||
public Object request() {
|
public Object request() {
|
||||||
System.out.println("------- 进入请求: " + SaHolder.getRequest().getUrl());
|
System.out.println("------- 进入请求: " + SaHolder.getRequest().getUrl());
|
||||||
return SaOAuth2Handle.serverRequest();
|
return SaOAuth2ServerProcessor.instance.dister();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sa-OAuth2 定制化配置
|
// Sa-Token OAuth2 定制化配置
|
||||||
@Autowired
|
@Autowired
|
||||||
public void setSaOAuth2Config(SaOAuth2Config cfg) {
|
public void setSaOAuth2Config(SaOAuth2Config oauth2Server) {
|
||||||
|
|
||||||
// 配置:未登录时返回的View
|
// 配置:未登录时返回的View
|
||||||
cfg.notLoginView = () -> {
|
oauth2Server.notLoginView = () -> {
|
||||||
String msg = "当前会话在OAuth-Server端尚未登录,请先访问"
|
String msg = "当前会话在OAuth-Server端尚未登录,请先访问"
|
||||||
+ "<a href='/oauth2/doLogin?name=sa&pwd=123456' target='_blank'> doLogin登录 </a>"
|
+ "<a href='/oauth2/doLogin?name=sa&pwd=123456' target='_blank'> doLogin登录 </a>"
|
||||||
+ "进行登录之后,刷新页面开始授权";
|
+ "进行登录之后,刷新页面开始授权";
|
||||||
@@ -108,7 +131,7 @@ public class SaOAuth2ServerController {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 配置:登录处理函数
|
// 配置:登录处理函数
|
||||||
cfg.doLoginHandle = (name, pwd) -> {
|
oauth2Server.doLoginHandle = (name, pwd) -> {
|
||||||
if("sa".equals(name) && "123456".equals(pwd)) {
|
if("sa".equals(name) && "123456".equals(pwd)) {
|
||||||
StpUtil.login(10001);
|
StpUtil.login(10001);
|
||||||
return SaResult.ok();
|
return SaResult.ok();
|
||||||
@@ -117,7 +140,7 @@ public class SaOAuth2ServerController {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 配置:确认授权时返回的 view
|
// 配置:确认授权时返回的 view
|
||||||
cfg.confirmView = (clientId, scopes) -> {
|
oauth2Server.confirmView = (clientId, scopes) -> {
|
||||||
String scopeStr = SaFoxUtil.convertListToString(scopes);
|
String scopeStr = SaFoxUtil.convertListToString(scopes);
|
||||||
String yesCode =
|
String yesCode =
|
||||||
"fetch('/oauth2/doConfirm?client_id=" + clientId + "&scope=" + scopeStr + "', {method: 'POST'})" +
|
"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、全局异常处理
|
3、全局异常处理
|
||||||
``` java
|
``` java
|
||||||
@@ -164,7 +180,8 @@ public class GlobalExceptionHandler {
|
|||||||
public class SaOAuth2ServerApplication {
|
public class SaOAuth2ServerApplication {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(SaOAuth2ServerApplication.class, 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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -185,7 +202,7 @@ http://sa-oauth-server.com:8000/oauth2/authorize?response_type=code&client_id=10
|
|||||||
3、点击doLogin进行登录之后刷新页面,会提示我们确认授权
|
3、点击doLogin进行登录之后刷新页面,会提示我们确认授权
|
||||||

|

|
||||||
|
|
||||||
4、点击确认授权之后刷新页面,我们会被重定向至 redirect_uri 页面,并携带了code参数
|
4、点击同意授权之后,我们会被重定向至 redirect_uri 页面,并携带了code参数
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -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}
|
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
|
``` js
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ implementation 'cn.dev33:sa-token-redis-jackson:${sa.top.version}'
|
|||||||
```
|
```
|
||||||
<!-------- tab:Gradle 方式 -------->
|
<!-------- tab:Gradle 方式 -------->
|
||||||
``` gradle
|
``` gradle
|
||||||
// Sa-Token 整合 Redis (使用 jackson 序列化方式)
|
// 提供Redis连接池
|
||||||
implementation 'org.apache.commons:commons-pool2'
|
implementation 'org.apache.commons:commons-pool2'
|
||||||
```
|
```
|
||||||
<!---------------------------- tabs:end ------------------------------>
|
<!---------------------------- tabs:end ------------------------------>
|
||||||
|
|||||||
+24
-25
@@ -296,16 +296,19 @@ sa-token.sso-client.is-slo=true
|
|||||||
### 4、OAuth2.0相关配置
|
### 4、OAuth2.0相关配置
|
||||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||||
| :-------- | :-------- | :-------- | :-------- |
|
| :-------- | :-------- | :-------- | :-------- |
|
||||||
| isCode | Boolean | true | 是否打开模式:授权码(`Authorization Code`) |
|
| enableAuthorizationCode | Boolean | true | 是否打开模式:授权码(`Authorization Code`) |
|
||||||
| isImplicit | Boolean | true | 是否打开模式:隐藏式(`Implicit`) |
|
| enableImplicit | Boolean | true | 是否打开模式:隐藏式(`Implicit`) |
|
||||||
| isPassword | Boolean | true | 是否打开模式:密码式(`Password`) |
|
| enablePassword | Boolean | true | 是否打开模式:密码式(`Password`) |
|
||||||
| isClient | Boolean | true | 是否打开模式:凭证式(`Client Credentials`) |
|
| enableClientCredentials | Boolean | true | 是否打开模式:凭证式(`Client Credentials`) |
|
||||||
| isNewRefresh | Boolean | false | 是否在每次 `Refresh-Token` 刷新 `Access-Token` 时,产生一个新的 Refresh-Token |
|
| isNewRefresh | Boolean | false | 是否在每次 `Refresh-Token` 刷新 `Access-Token` 时,产生一个新的 `Refresh-Token` |
|
||||||
| codeTimeout | long | 300 | Code授权码 保存的时间(单位:秒) 默认五分钟 |
|
| codeTimeout | long | 300 | Code授权码 保存的时间(单位:秒) 默认五分钟 |
|
||||||
| accessTokenTimeout | long | 7200 | `Access-Token` 保存的时间(单位:秒)默认两个小时 |
|
| accessTokenTimeout | long | 7200 | `Access-Token` 保存的时间(单位:秒)默认两个小时 |
|
||||||
| refreshTokenTimeout | long | 2592000 | `Refresh-Token` 保存的时间(单位:秒) 默认30 天 |
|
| refreshTokenTimeout | long | 2592000 | `Refresh-Token` 保存的时间(单位:秒) 默认30 天 |
|
||||||
| clientTokenTimeout | long | 7200 | `Client-Token` 保存的时间(单位:秒) 默认两个小时 |
|
| clientTokenTimeout | long | 7200 | `Client-Token` 保存的时间(单位:秒) 默认两个小时 |
|
||||||
| pastClientTokenTimeout | long | 7200 | `Past-Client-Token` 保存的时间(单位:秒) ,默认为-1,代表延续 `Client-Token` 的有效时间 |
|
| pastClientTokenTimeout | long | 7200 | `Past-Client-Token` 保存的时间(单位:秒) ,默认为-1,代表延续 `Client-Token` 的有效时间 |
|
||||||
|
| openidDigestPrefix | String | openid_default_digest_prefix | 默认 openid 生成算法中使用的摘要前缀 |
|
||||||
|
| higherScope | String | | 指定高级权限,多个用逗号隔开 |
|
||||||
|
| lowerScope | String | | 指定低级权限,多个用逗号隔开 |
|
||||||
|
|
||||||
配置示例:
|
配置示例:
|
||||||
<!---------------------------- tabs:start ---------------------------->
|
<!---------------------------- tabs:start ---------------------------->
|
||||||
@@ -313,23 +316,23 @@ sa-token.sso-client.is-slo=true
|
|||||||
``` yaml
|
``` yaml
|
||||||
# Sa-Token 配置
|
# Sa-Token 配置
|
||||||
sa-token:
|
sa-token:
|
||||||
token-name: satoken-server
|
token-name: sa-token-oauth2-server
|
||||||
# OAuth2.0 配置
|
# OAuth2.0 配置
|
||||||
oauth2:
|
oauth2-server:
|
||||||
is-code: true
|
enable-authorization-code: true
|
||||||
is-implicit: true
|
enable-implicit: true
|
||||||
is-password: true
|
enable-password: true
|
||||||
is-client: true
|
enable-client-credentials: true
|
||||||
```
|
```
|
||||||
<!------------- tab:properties 风格 ------------->
|
<!------------- tab:properties 风格 ------------->
|
||||||
``` properties
|
``` properties
|
||||||
# Sa-Token 配置
|
# Sa-Token 配置
|
||||||
sa-token.token-name=satoken-server
|
sa-token.token-name=sa-token-oauth2-server
|
||||||
# OAuth2.0 配置
|
# OAuth2.0 配置
|
||||||
sa-token.oauth2.is-code=true
|
sa-token.oauth2-server.enable-authorization-code=true
|
||||||
sa-token.oauth2.is-implicit=true
|
sa-token.oauth2-server.enable-implicit=true
|
||||||
sa-token.oauth2.is-password=true
|
sa-token.oauth2-server.enable-password=true
|
||||||
sa-token.oauth2.is-client=true
|
sa-token.oauth2-server.enable-client-credentials=true
|
||||||
```
|
```
|
||||||
<!---------------------------- tabs:end ---------------------------->
|
<!---------------------------- tabs:end ---------------------------->
|
||||||
|
|
||||||
@@ -339,13 +342,9 @@ sa-token.oauth2.is-client=true
|
|||||||
| :-------- | :-------- | :-------- | :-------- |
|
| :-------- | :-------- | :-------- | :-------- |
|
||||||
| clientId | String | null | 应用id,应该全局唯一 |
|
| clientId | String | null | 应用id,应该全局唯一 |
|
||||||
| clientSecret | String | null | 应用秘钥 |
|
| clientSecret | String | null | 应用秘钥 |
|
||||||
| contractScope | String | null | 应用签约的所有权限, 多个用逗号隔开 |
|
| contractScopes | List<String> | null | 应用签约的所有权限 |
|
||||||
| allowUrl | String | null | 应用允许授权的所有URL, 多个用逗号隔开 (可以使用 `*` 号通配符) |
|
| allowUrls | List<String> | null | 应用允许授权的所有URL(可以使用 `*` 号通配符) |
|
||||||
| isCode | Boolean | false | 单独配置此 Client 是否打开模式:授权码(`Authorization Code`) |
|
| allowGrantTypes | List<String> | new ArrayList<>() | 应用允许的所有 `grant_type` |
|
||||||
| 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 [ 默认取全局配置 ] |
|
| isNewRefresh | Boolean | 取全局配置 | 单独配置此Client:是否在每次 `Refresh-Token` 刷新 `Access-Token` 时,产生一个新的 Refresh-Token [ 默认取全局配置 ] |
|
||||||
| accessTokenTimeout | long | 取全局配置 | 单独配置此Client:`Access-Token` 保存的时间(单位:秒) [默认取全局配置] |
|
| accessTokenTimeout | long | 取全局配置 | 单独配置此Client:`Access-Token` 保存的时间(单位:秒) [默认取全局配置] |
|
||||||
| refreshTokenTimeout | long | 取全局配置 | 单独配置此Client:`Refresh-Token` 保存的时间(单位:秒) [默认取全局配置] |
|
| refreshTokenTimeout | long | 取全局配置 | 单独配置此Client:`Refresh-Token` 保存的时间(单位:秒) [默认取全局配置] |
|
||||||
@@ -392,14 +391,14 @@ sa-token.oauth2.is-client=true
|
|||||||
|
|
||||||
但是 —— 有的场景下我们又确实需要在登录之前就使用 Token-Session 对象,这时候就把配置项 `tokenSessionCheckLogin` 值改为 `false` 即可。
|
但是 —— 有的场景下我们又确实需要在登录之前就使用 Token-Session 对象,这时候就把配置项 `tokenSessionCheckLogin` 值改为 `false` 即可。
|
||||||
|
|
||||||
|
<!--
|
||||||
#### 配置项详解:isAutoMode
|
#### 配置项详解:isAutoMode
|
||||||
|
|
||||||
配置含义:是否自动判断此 Client 开放的授权模式。
|
配置含义:是否自动判断此 Client 开放的授权模式。
|
||||||
|
|
||||||
- 此值为 true 时:四种模式(`isCode、isImplicit、isPassword、isClient`)是否生效,依靠全局设置;
|
- 此值为 true 时:四种模式(`isCode、isImplicit、isPassword、isClient`)是否生效,依靠全局设置;
|
||||||
- 此值为 false 时:四种模式(`isCode、isImplicit、isPassword、isClient`)是否生效,依靠局部配置+全局配置(两个都为 true 时才打开)
|
- 此值为 false 时:四种模式(`isCode、isImplicit、isPassword、isClient`)是否生效,依靠局部配置+全局配置(两个都为 true 时才打开)
|
||||||
|
-->
|
||||||
|
|
||||||
#### 配置项详解:isHttp
|
#### 配置项详解:isHttp
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package cn.dev33.satoken.oauth2;
|
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.SaOAuth2Dao;
|
||||||
import cn.dev33.satoken.oauth2.dao.SaOAuth2DaoDefaultImpl;
|
import cn.dev33.satoken.oauth2.dao.SaOAuth2DaoDefaultImpl;
|
||||||
import cn.dev33.satoken.oauth2.data.convert.SaOAuth2DataConverter;
|
import cn.dev33.satoken.oauth2.data.convert.SaOAuth2DataConverter;
|
||||||
@@ -41,19 +41,19 @@ public class SaOAuth2Manager {
|
|||||||
/**
|
/**
|
||||||
* OAuth2 配置 Bean
|
* OAuth2 配置 Bean
|
||||||
*/
|
*/
|
||||||
private static volatile SaOAuth2Config config;
|
private static volatile SaOAuth2ServerConfig config;
|
||||||
public static SaOAuth2Config getConfig() {
|
public static SaOAuth2ServerConfig getConfig() {
|
||||||
if (config == null) {
|
if (config == null) {
|
||||||
// 初始化默认值
|
// 初始化默认值
|
||||||
synchronized (SaOAuth2Manager.class) {
|
synchronized (SaOAuth2Manager.class) {
|
||||||
if (config == null) {
|
if (config == null) {
|
||||||
setConfig(new SaOAuth2Config());
|
setConfig(new SaOAuth2ServerConfig());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
public static void setConfig(SaOAuth2Config config) {
|
public static void setConfig(SaOAuth2ServerConfig config) {
|
||||||
SaOAuth2Manager.config = config;
|
SaOAuth2Manager.config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+29
-29
@@ -24,17 +24,17 @@ import cn.dev33.satoken.util.SaResult;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sa-Token-OAuth2 配置类 Model
|
* Sa-Token OAuth2 Server 端 配置类 Model
|
||||||
*
|
*
|
||||||
* @author click33
|
* @author click33
|
||||||
* @since 1.19.0
|
* @since 1.19.0
|
||||||
*/
|
*/
|
||||||
public class SaOAuth2Config implements Serializable {
|
public class SaOAuth2ServerConfig implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = -6541180061782004705L;
|
private static final long serialVersionUID = -6541180061782004705L;
|
||||||
|
|
||||||
/** 是否打开模式:授权码(Authorization Code) */
|
/** 是否打开模式:授权码(Authorization Code) */
|
||||||
public Boolean enableCode = true;
|
public Boolean enableAuthorizationCode = true;
|
||||||
|
|
||||||
/** 是否打开模式:隐藏式(Implicit) */
|
/** 是否打开模式:隐藏式(Implicit) */
|
||||||
public Boolean enableImplicit = true;
|
public Boolean enableImplicit = true;
|
||||||
@@ -43,7 +43,7 @@ public class SaOAuth2Config implements Serializable {
|
|||||||
public Boolean enablePassword = true;
|
public Boolean enablePassword = true;
|
||||||
|
|
||||||
/** 是否打开模式:凭证式(Client Credentials) */
|
/** 是否打开模式:凭证式(Client Credentials) */
|
||||||
public Boolean enableClient = true;
|
public Boolean enableClientCredentials = true;
|
||||||
|
|
||||||
/** 是否在每次 Refresh-Token 刷新 Access-Token 时,产生一个新的 Refresh-Token */
|
/** 是否在每次 Refresh-Token 刷新 Access-Token 时,产生一个新的 Refresh-Token */
|
||||||
public Boolean isNewRefresh = false;
|
public Boolean isNewRefresh = false;
|
||||||
@@ -75,16 +75,16 @@ public class SaOAuth2Config implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* @return enableCode
|
* @return enableCode
|
||||||
*/
|
*/
|
||||||
public Boolean getEnableCode() {
|
public Boolean getEnableAuthorizationCode() {
|
||||||
return enableCode;
|
return enableAuthorizationCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param enableCode 要设置的 enableCode
|
* @param enableAuthorizationCode 要设置的 enableAuthorizationCode
|
||||||
* @return /
|
* @return /
|
||||||
*/
|
*/
|
||||||
public SaOAuth2Config setEnableCode(Boolean enableCode) {
|
public SaOAuth2ServerConfig setEnableAuthorizationCode(Boolean enableAuthorizationCode) {
|
||||||
this.enableCode = enableCode;
|
this.enableAuthorizationCode = enableAuthorizationCode;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ public class SaOAuth2Config implements Serializable {
|
|||||||
* @param enableImplicit 要设置的 enableImplicit
|
* @param enableImplicit 要设置的 enableImplicit
|
||||||
* @return /
|
* @return /
|
||||||
*/
|
*/
|
||||||
public SaOAuth2Config setEnableImplicit(Boolean enableImplicit) {
|
public SaOAuth2ServerConfig setEnableImplicit(Boolean enableImplicit) {
|
||||||
this.enableImplicit = enableImplicit;
|
this.enableImplicit = enableImplicit;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -114,24 +114,24 @@ public class SaOAuth2Config implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* @param enablePassword 要设置的 enablePassword
|
* @param enablePassword 要设置的 enablePassword
|
||||||
*/
|
*/
|
||||||
public SaOAuth2Config setEnablePassword(Boolean enablePassword) {
|
public SaOAuth2ServerConfig setEnablePassword(Boolean enablePassword) {
|
||||||
this.enablePassword = enablePassword;
|
this.enablePassword = enablePassword;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return enableClient
|
* @return enableClientCredentials
|
||||||
*/
|
*/
|
||||||
public Boolean getEnableClient() {
|
public Boolean getEnableClientCredentials() {
|
||||||
return enableClient;
|
return enableClientCredentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param enableClient 要设置的 enableClient
|
* @param enableClientCredentials 要设置的 enableClientCredentials
|
||||||
* @return /
|
* @return /
|
||||||
*/
|
*/
|
||||||
public SaOAuth2Config setEnableClient(Boolean enableClient) {
|
public SaOAuth2ServerConfig setEnableClientCredentials(Boolean enableClientCredentials) {
|
||||||
this.enableClient = enableClient;
|
this.enableClientCredentials = enableClientCredentials;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ public class SaOAuth2Config implements Serializable {
|
|||||||
* @param isNewRefresh 要设置的 isNewRefresh
|
* @param isNewRefresh 要设置的 isNewRefresh
|
||||||
* @return /
|
* @return /
|
||||||
*/
|
*/
|
||||||
public SaOAuth2Config setIsNewRefresh(Boolean isNewRefresh) {
|
public SaOAuth2ServerConfig setIsNewRefresh(Boolean isNewRefresh) {
|
||||||
this.isNewRefresh = isNewRefresh;
|
this.isNewRefresh = isNewRefresh;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -162,7 +162,7 @@ public class SaOAuth2Config implements Serializable {
|
|||||||
* @param codeTimeout 要设置的 codeTimeout
|
* @param codeTimeout 要设置的 codeTimeout
|
||||||
* @return 对象自身
|
* @return 对象自身
|
||||||
*/
|
*/
|
||||||
public SaOAuth2Config setCodeTimeout(long codeTimeout) {
|
public SaOAuth2ServerConfig setCodeTimeout(long codeTimeout) {
|
||||||
this.codeTimeout = codeTimeout;
|
this.codeTimeout = codeTimeout;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -178,7 +178,7 @@ public class SaOAuth2Config implements Serializable {
|
|||||||
* @param accessTokenTimeout 要设置的 accessTokenTimeout
|
* @param accessTokenTimeout 要设置的 accessTokenTimeout
|
||||||
* @return 对象自身
|
* @return 对象自身
|
||||||
*/
|
*/
|
||||||
public SaOAuth2Config setAccessTokenTimeout(long accessTokenTimeout) {
|
public SaOAuth2ServerConfig setAccessTokenTimeout(long accessTokenTimeout) {
|
||||||
this.accessTokenTimeout = accessTokenTimeout;
|
this.accessTokenTimeout = accessTokenTimeout;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -194,7 +194,7 @@ public class SaOAuth2Config implements Serializable {
|
|||||||
* @param refreshTokenTimeout 要设置的 refreshTokenTimeout
|
* @param refreshTokenTimeout 要设置的 refreshTokenTimeout
|
||||||
* @return 对象自身
|
* @return 对象自身
|
||||||
*/
|
*/
|
||||||
public SaOAuth2Config setRefreshTokenTimeout(long refreshTokenTimeout) {
|
public SaOAuth2ServerConfig setRefreshTokenTimeout(long refreshTokenTimeout) {
|
||||||
this.refreshTokenTimeout = refreshTokenTimeout;
|
this.refreshTokenTimeout = refreshTokenTimeout;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -210,7 +210,7 @@ public class SaOAuth2Config implements Serializable {
|
|||||||
* @param clientTokenTimeout 要设置的 clientTokenTimeout
|
* @param clientTokenTimeout 要设置的 clientTokenTimeout
|
||||||
* @return 对象自身
|
* @return 对象自身
|
||||||
*/
|
*/
|
||||||
public SaOAuth2Config setClientTokenTimeout(long clientTokenTimeout) {
|
public SaOAuth2ServerConfig setClientTokenTimeout(long clientTokenTimeout) {
|
||||||
this.clientTokenTimeout = clientTokenTimeout;
|
this.clientTokenTimeout = clientTokenTimeout;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -226,7 +226,7 @@ public class SaOAuth2Config implements Serializable {
|
|||||||
* @param pastClientTokenTimeout 要设置的 pastClientTokenTimeout
|
* @param pastClientTokenTimeout 要设置的 pastClientTokenTimeout
|
||||||
* @return 对象自身
|
* @return 对象自身
|
||||||
*/
|
*/
|
||||||
public SaOAuth2Config setPastClientTokenTimeout(long pastClientTokenTimeout) {
|
public SaOAuth2ServerConfig setPastClientTokenTimeout(long pastClientTokenTimeout) {
|
||||||
this.pastClientTokenTimeout = pastClientTokenTimeout;
|
this.pastClientTokenTimeout = pastClientTokenTimeout;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -242,7 +242,7 @@ public class SaOAuth2Config implements Serializable {
|
|||||||
* @param openidDigestPrefix 要设置的 openidDigestPrefix
|
* @param openidDigestPrefix 要设置的 openidDigestPrefix
|
||||||
* @return 对象自身
|
* @return 对象自身
|
||||||
*/
|
*/
|
||||||
public SaOAuth2Config setOpenidDigestPrefix(String openidDigestPrefix) {
|
public SaOAuth2ServerConfig setOpenidDigestPrefix(String openidDigestPrefix) {
|
||||||
this.openidDigestPrefix = openidDigestPrefix;
|
this.openidDigestPrefix = openidDigestPrefix;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -262,7 +262,7 @@ public class SaOAuth2Config implements Serializable {
|
|||||||
* @param higherScope 指定高级权限,多个用逗号隔开
|
* @param higherScope 指定高级权限,多个用逗号隔开
|
||||||
* @return /
|
* @return /
|
||||||
*/
|
*/
|
||||||
public SaOAuth2Config setHigherScope(String higherScope) {
|
public SaOAuth2ServerConfig setHigherScope(String higherScope) {
|
||||||
this.higherScope = higherScope;
|
this.higherScope = higherScope;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -282,7 +282,7 @@ public class SaOAuth2Config implements Serializable {
|
|||||||
* @param lowerScope 指定低级权限,多个用逗号隔开
|
* @param lowerScope 指定低级权限,多个用逗号隔开
|
||||||
* @return /
|
* @return /
|
||||||
*/
|
*/
|
||||||
public SaOAuth2Config setLowerScope(String lowerScope) {
|
public SaOAuth2ServerConfig setLowerScope(String lowerScope) {
|
||||||
this.lowerScope = lowerScope;
|
this.lowerScope = lowerScope;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -307,11 +307,11 @@ public class SaOAuth2Config implements Serializable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "SaOAuth2Config{" +
|
return "SaOAuth2ServerConfig{" +
|
||||||
"enableCode=" + enableCode +
|
"enableAuthorizationCode=" + enableAuthorizationCode +
|
||||||
", enableImplicit=" + enableImplicit +
|
", enableImplicit=" + enableImplicit +
|
||||||
", enablePassword=" + enablePassword +
|
", enablePassword=" + enablePassword +
|
||||||
", enableClient=" + enableClient +
|
", enableClientCredentials=" + enableClientCredentials +
|
||||||
", isNewRefresh=" + isNewRefresh +
|
", isNewRefresh=" + isNewRefresh +
|
||||||
", codeTimeout=" + codeTimeout +
|
", codeTimeout=" + codeTimeout +
|
||||||
", accessTokenTimeout=" + accessTokenTimeout +
|
", accessTokenTimeout=" + accessTokenTimeout +
|
||||||
+3
-3
@@ -23,7 +23,7 @@ import cn.dev33.satoken.oauth2.data.model.loader.SaClientModel;
|
|||||||
import cn.dev33.satoken.oauth2.strategy.SaOAuth2Strategy;
|
import cn.dev33.satoken.oauth2.strategy.SaOAuth2Strategy;
|
||||||
import cn.dev33.satoken.util.SaFoxUtil;
|
import cn.dev33.satoken.util.SaFoxUtil;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ public class SaOAuth2DataConverterDefaultImpl implements SaOAuth2DataConverter {
|
|||||||
@Override
|
@Override
|
||||||
public List<String> convertScopeStringToList(String scopeString) {
|
public List<String> convertScopeStringToList(String scopeString) {
|
||||||
if(SaFoxUtil.isEmpty(scopeString)) {
|
if(SaFoxUtil.isEmpty(scopeString)) {
|
||||||
return Collections.emptyList();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
// 兼容以下三种分隔符:空格、逗号、%20
|
// 兼容以下三种分隔符:空格、逗号、%20
|
||||||
scopeString = scopeString.replaceAll(" ", ",");
|
scopeString = scopeString.replaceAll(" ", ",");
|
||||||
@@ -63,7 +63,7 @@ public class SaOAuth2DataConverterDefaultImpl implements SaOAuth2DataConverter {
|
|||||||
@Override
|
@Override
|
||||||
public List<String> convertAllowUrlStringToList(String allowUrl) {
|
public List<String> convertAllowUrlStringToList(String allowUrl) {
|
||||||
if(SaFoxUtil.isEmpty(allowUrl)) {
|
if(SaFoxUtil.isEmpty(allowUrl)) {
|
||||||
return Collections.emptyList();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
return SaFoxUtil.convertStringToList(allowUrl);
|
return SaFoxUtil.convertStringToList(allowUrl);
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-18
@@ -16,7 +16,7 @@
|
|||||||
package cn.dev33.satoken.oauth2.data.model.loader;
|
package cn.dev33.satoken.oauth2.data.model.loader;
|
||||||
|
|
||||||
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
|
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.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -49,9 +49,9 @@ public class SaClientModel implements Serializable {
|
|||||||
public List<String> contractScopes;
|
public List<String> contractScopes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 应用允许授权的所有URL
|
* 应用允许授权的所有 redirect_uri
|
||||||
*/
|
*/
|
||||||
public List<String> allowUrls;
|
public List<String> allowRedirectUris;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 应用允许的所有 grant_type
|
* 应用允许的所有 grant_type
|
||||||
@@ -75,19 +75,19 @@ public class SaClientModel implements Serializable {
|
|||||||
|
|
||||||
|
|
||||||
public SaClientModel() {
|
public SaClientModel() {
|
||||||
SaOAuth2Config config = SaOAuth2Manager.getConfig();
|
SaOAuth2ServerConfig config = SaOAuth2Manager.getConfig();
|
||||||
this.isNewRefresh = config.getIsNewRefresh();
|
this.isNewRefresh = config.getIsNewRefresh();
|
||||||
this.accessTokenTimeout = config.getAccessTokenTimeout();
|
this.accessTokenTimeout = config.getAccessTokenTimeout();
|
||||||
this.refreshTokenTimeout = config.getRefreshTokenTimeout();
|
this.refreshTokenTimeout = config.getRefreshTokenTimeout();
|
||||||
this.clientTokenTimeout = config.getClientTokenTimeout();
|
this.clientTokenTimeout = config.getClientTokenTimeout();
|
||||||
this.pastClientTokenTimeout = config.getPastClientTokenTimeout();
|
this.pastClientTokenTimeout = config.getPastClientTokenTimeout();
|
||||||
}
|
}
|
||||||
public SaClientModel(String clientId, String clientSecret, List<String> contractScopes, List<String> allowUrls) {
|
public SaClientModel(String clientId, String clientSecret, List<String> contractScopes, List<String> allowRedirectUris) {
|
||||||
super();
|
super();
|
||||||
this.clientId = clientId;
|
this.clientId = clientId;
|
||||||
this.clientSecret = clientSecret;
|
this.clientSecret = clientSecret;
|
||||||
this.contractScopes = contractScopes;
|
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<String> getAllowUrls() {
|
public List<String> getAllowRedirectUris() {
|
||||||
return allowUrls;
|
return allowRedirectUris;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param allowUrls 应用允许授权的所有URL
|
* @param allowRedirectUris 应用允许授权的所有 redirect_uri
|
||||||
* @return 对象自身
|
* @return 对象自身
|
||||||
*/
|
*/
|
||||||
public SaClientModel setAllowUrls(List<String> allowUrls) {
|
public SaClientModel setAllowRedirectUris(List<String> allowRedirectUris) {
|
||||||
this.allowUrls = allowUrls;
|
this.allowRedirectUris = allowRedirectUris;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,7 +259,7 @@ public class SaClientModel implements Serializable {
|
|||||||
"clientId='" + clientId + '\'' +
|
"clientId='" + clientId + '\'' +
|
||||||
", clientSecret='" + clientSecret + '\'' +
|
", clientSecret='" + clientSecret + '\'' +
|
||||||
", contractScopes=" + contractScopes +
|
", contractScopes=" + contractScopes +
|
||||||
", allowUrls=" + allowUrls +
|
", allowRedirectUris=" + allowRedirectUris +
|
||||||
", allowGrantTypes=" + allowGrantTypes +
|
", allowGrantTypes=" + allowGrantTypes +
|
||||||
", isNewRefresh=" + isNewRefresh +
|
", isNewRefresh=" + isNewRefresh +
|
||||||
", accessTokenTimeout=" + accessTokenTimeout +
|
", accessTokenTimeout=" + accessTokenTimeout +
|
||||||
@@ -285,14 +285,14 @@ public class SaClientModel implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param urls 添加应用允许授权的所有URL
|
* @param redirectUris 添加应用允许授权的所有 redirect_uri
|
||||||
* @return 对象自身
|
* @return 对象自身
|
||||||
*/
|
*/
|
||||||
public SaClientModel addAllowUrls(String... urls) {
|
public SaClientModel addAllowRedirectUris(String... redirectUris) {
|
||||||
if(this.allowUrls == null) {
|
if(this.allowRedirectUris == null) {
|
||||||
this.allowUrls = new ArrayList<>();
|
this.allowRedirectUris = new ArrayList<>();
|
||||||
}
|
}
|
||||||
this.allowUrls.addAll(Arrays.asList(urls));
|
this.allowRedirectUris.addAll(Arrays.asList(redirectUris));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -38,7 +38,7 @@ public class AuthorizationCodeGrantTypeHandler implements SaOAuth2GrantTypeHandl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AccessTokenModel getAccessTokenModel(SaRequest req, String clientId, List<String> scopes) {
|
public AccessTokenModel getAccessToken(SaRequest req, String clientId, List<String> scopes) {
|
||||||
// 获取参数
|
// 获取参数
|
||||||
ClientIdAndSecretModel clientIdAndSecret = SaOAuth2Manager.getDataResolver().readClientIdAndSecret(req);
|
ClientIdAndSecretModel clientIdAndSecret = SaOAuth2Manager.getDataResolver().readClientIdAndSecret(req);
|
||||||
// String clientId = clientIdAndSecret.clientId;
|
// String clientId = clientIdAndSecret.clientId;
|
||||||
|
|||||||
+1
-1
@@ -40,7 +40,7 @@ public class PasswordGrantTypeHandler implements SaOAuth2GrantTypeHandlerInterfa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AccessTokenModel getAccessTokenModel(SaRequest req, String clientId, List<String> scopes) {
|
public AccessTokenModel getAccessToken(SaRequest req, String clientId, List<String> scopes) {
|
||||||
|
|
||||||
// 1、获取请求参数
|
// 1、获取请求参数
|
||||||
String username = req.getParamNotNull(SaOAuth2Consts.Param.username);
|
String username = req.getParamNotNull(SaOAuth2Consts.Param.username);
|
||||||
|
|||||||
+1
-1
@@ -40,7 +40,7 @@ public class RefreshTokenGrantTypeHandler implements SaOAuth2GrantTypeHandlerInt
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AccessTokenModel getAccessTokenModel(SaRequest req, String clientId, List<String> scopes) {
|
public AccessTokenModel getAccessToken(SaRequest req, String clientId, List<String> scopes) {
|
||||||
// 获取参数
|
// 获取参数
|
||||||
String refreshToken = req.getParamNotNull(SaOAuth2Consts.Param.refresh_token);
|
String refreshToken = req.getParamNotNull(SaOAuth2Consts.Param.refresh_token);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -41,6 +41,6 @@ public interface SaOAuth2GrantTypeHandlerInterface {
|
|||||||
* @param req /
|
* @param req /
|
||||||
* @return /
|
* @return /
|
||||||
*/
|
*/
|
||||||
AccessTokenModel getAccessTokenModel(SaRequest req, String clientId, List<String> scopes);
|
AccessTokenModel getAccessToken(SaRequest req, String clientId, List<String> scopes);
|
||||||
|
|
||||||
}
|
}
|
||||||
+7
-7
@@ -19,7 +19,7 @@ import cn.dev33.satoken.context.SaHolder;
|
|||||||
import cn.dev33.satoken.context.model.SaRequest;
|
import cn.dev33.satoken.context.model.SaRequest;
|
||||||
import cn.dev33.satoken.context.model.SaResponse;
|
import cn.dev33.satoken.context.model.SaResponse;
|
||||||
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
|
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.GrantType;
|
||||||
import cn.dev33.satoken.oauth2.consts.SaOAuth2Consts;
|
import cn.dev33.satoken.oauth2.consts.SaOAuth2Consts;
|
||||||
import cn.dev33.satoken.oauth2.consts.SaOAuth2Consts.Api;
|
import cn.dev33.satoken.oauth2.consts.SaOAuth2Consts.Api;
|
||||||
@@ -113,7 +113,7 @@ public class SaOAuth2ServerProcessor {
|
|||||||
// 获取变量
|
// 获取变量
|
||||||
SaRequest req = SaHolder.getRequest();
|
SaRequest req = SaHolder.getRequest();
|
||||||
SaResponse res = SaHolder.getResponse();
|
SaResponse res = SaHolder.getResponse();
|
||||||
SaOAuth2Config cfg = SaOAuth2Manager.getConfig();
|
SaOAuth2ServerConfig cfg = SaOAuth2Manager.getConfig();
|
||||||
SaOAuth2DataGenerate dataGenerate = SaOAuth2Manager.getDataGenerate();
|
SaOAuth2DataGenerate dataGenerate = SaOAuth2Manager.getDataGenerate();
|
||||||
SaOAuth2Template oauth2Template = SaOAuth2Manager.getTemplate();
|
SaOAuth2Template oauth2Template = SaOAuth2Manager.getTemplate();
|
||||||
String responseType = req.getParamNotNull(Param.response_type);
|
String responseType = req.getParamNotNull(Param.response_type);
|
||||||
@@ -218,7 +218,7 @@ public class SaOAuth2ServerProcessor {
|
|||||||
public Object doLogin() {
|
public Object doLogin() {
|
||||||
// 获取变量
|
// 获取变量
|
||||||
SaRequest req = SaHolder.getRequest();
|
SaRequest req = SaHolder.getRequest();
|
||||||
SaOAuth2Config cfg = SaOAuth2Manager.getConfig();
|
SaOAuth2ServerConfig cfg = SaOAuth2Manager.getConfig();
|
||||||
|
|
||||||
return cfg.doLoginHandle.apply(req.getParam(Param.name), req.getParam(Param.pwd));
|
return cfg.doLoginHandle.apply(req.getParam(Param.name), req.getParam(Param.pwd));
|
||||||
}
|
}
|
||||||
@@ -285,14 +285,14 @@ public class SaOAuth2ServerProcessor {
|
|||||||
public Object clientToken() {
|
public Object clientToken() {
|
||||||
// 获取变量
|
// 获取变量
|
||||||
SaRequest req = SaHolder.getRequest();
|
SaRequest req = SaHolder.getRequest();
|
||||||
SaOAuth2Config cfg = SaOAuth2Manager.getConfig();
|
SaOAuth2ServerConfig cfg = SaOAuth2Manager.getConfig();
|
||||||
SaOAuth2Template oauth2Template = SaOAuth2Manager.getTemplate();
|
SaOAuth2Template oauth2Template = SaOAuth2Manager.getTemplate();
|
||||||
|
|
||||||
String grantType = req.getParamNotNull(Param.grant_type);
|
String grantType = req.getParamNotNull(Param.grant_type);
|
||||||
if(!grantType.equals(GrantType.client_credentials)) {
|
if(!grantType.equals(GrantType.client_credentials)) {
|
||||||
throw new SaOAuth2Exception("无效 grant_type:" + grantType).setCode(SaOAuth2ErrorCode.CODE_30126);
|
throw new SaOAuth2Exception("无效 grant_type:" + grantType).setCode(SaOAuth2ErrorCode.CODE_30126);
|
||||||
}
|
}
|
||||||
if(!cfg.enableClient) {
|
if(!cfg.enableClientCredentials) {
|
||||||
throwErrorSystemNotEnableModel();
|
throwErrorSystemNotEnableModel();
|
||||||
}
|
}
|
||||||
if(!currClientModel().getAllowGrantTypes().contains(GrantType.client_credentials)) {
|
if(!currClientModel().getAllowGrantTypes().contains(GrantType.client_credentials)) {
|
||||||
@@ -335,10 +335,10 @@ public class SaOAuth2ServerProcessor {
|
|||||||
/**
|
/**
|
||||||
* 校验 authorize 路由的 ResponseType 参数
|
* 校验 authorize 路由的 ResponseType 参数
|
||||||
*/
|
*/
|
||||||
public void checkAuthorizeResponseType(String responseType, SaRequest req, SaOAuth2Config cfg) {
|
public void checkAuthorizeResponseType(String responseType, SaRequest req, SaOAuth2ServerConfig cfg) {
|
||||||
// 模式一:Code授权码
|
// 模式一:Code授权码
|
||||||
if(responseType.equals(ResponseType.code)) {
|
if(responseType.equals(ResponseType.code)) {
|
||||||
if(!cfg.enableCode) {
|
if(!cfg.enableAuthorizationCode) {
|
||||||
throwErrorSystemNotEnableModel();
|
throwErrorSystemNotEnableModel();
|
||||||
}
|
}
|
||||||
if(!currClientModel().getAllowGrantTypes().contains(GrantType.authorization_code)) {
|
if(!currClientModel().getAllowGrantTypes().contains(GrantType.authorization_code)) {
|
||||||
|
|||||||
+4
-4
@@ -17,7 +17,7 @@ package cn.dev33.satoken.oauth2.strategy;
|
|||||||
|
|
||||||
import cn.dev33.satoken.SaManager;
|
import cn.dev33.satoken.SaManager;
|
||||||
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
|
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.GrantType;
|
||||||
import cn.dev33.satoken.oauth2.consts.SaOAuth2Consts;
|
import cn.dev33.satoken.oauth2.consts.SaOAuth2Consts;
|
||||||
import cn.dev33.satoken.oauth2.data.model.loader.SaClientModel;
|
import cn.dev33.satoken.oauth2.data.model.loader.SaClientModel;
|
||||||
@@ -170,8 +170,8 @@ public final class SaOAuth2Strategy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 看看全局是否开启了此 grantType
|
// 看看全局是否开启了此 grantType
|
||||||
SaOAuth2Config config = SaOAuth2Manager.getConfig();
|
SaOAuth2ServerConfig config = SaOAuth2Manager.getConfig();
|
||||||
if(grantType.equals(GrantType.authorization_code) && !config.getEnableCode() ) {
|
if(grantType.equals(GrantType.authorization_code) && !config.getEnableAuthorizationCode() ) {
|
||||||
throw new SaOAuth2Exception("系统未开放的 grant_type: " + grantType);
|
throw new SaOAuth2Exception("系统未开放的 grant_type: " + grantType);
|
||||||
}
|
}
|
||||||
if(grantType.equals(GrantType.password) && !config.getEnablePassword() ) {
|
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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -224,8 +224,8 @@ public class SaOAuth2Template {
|
|||||||
|
|
||||||
// 4、是否在[允许地址列表]之中
|
// 4、是否在[允许地址列表]之中
|
||||||
SaClientModel clientModel = checkClientModel(clientId);
|
SaClientModel clientModel = checkClientModel(clientId);
|
||||||
checkAllowUrlList(clientModel.allowUrls);
|
checkAllowUrlList(clientModel.allowRedirectUris);
|
||||||
if( ! SaStrategy.instance.hasElement.apply(clientModel.allowUrls, url)) {
|
if( ! SaStrategy.instance.hasElement.apply(clientModel.allowRedirectUris, url)) {
|
||||||
throw new SaOAuth2Exception("非法 redirect_url: " + url).setCode(SaOAuth2ErrorCode.CODE_30114);
|
throw new SaOAuth2Exception("非法 redirect_url: " + url).setCode(SaOAuth2ErrorCode.CODE_30114);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -16,7 +16,7 @@
|
|||||||
package cn.dev33.satoken.solon.oauth2;
|
package cn.dev33.satoken.solon.oauth2;
|
||||||
|
|
||||||
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
|
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.SaOAuth2Template;
|
||||||
import cn.dev33.satoken.oauth2.template.SaOAuth2Util;
|
import cn.dev33.satoken.oauth2.template.SaOAuth2Util;
|
||||||
import org.noear.solon.annotation.Bean;
|
import org.noear.solon.annotation.Bean;
|
||||||
@@ -39,7 +39,7 @@ public class SaOAuth2AutoConfigure {
|
|||||||
SaOAuth2Util.saOAuth2Template = bean;
|
SaOAuth2Util.saOAuth2Template = bean;
|
||||||
});
|
});
|
||||||
|
|
||||||
appContext.subBeansOfType(SaOAuth2Config.class, bean -> {
|
appContext.subBeansOfType(SaOAuth2ServerConfig.class, bean -> {
|
||||||
SaOAuth2Manager.setConfig(bean);
|
SaOAuth2Manager.setConfig(bean);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ public class SaOAuth2AutoConfigure {
|
|||||||
* 获取 OAuth2配置Bean
|
* 获取 OAuth2配置Bean
|
||||||
*/
|
*/
|
||||||
@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;
|
return oAuth2Config;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-2
@@ -16,7 +16,7 @@
|
|||||||
package cn.dev33.satoken.spring.oauth2;
|
package cn.dev33.satoken.spring.oauth2;
|
||||||
|
|
||||||
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
|
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.dao.SaOAuth2Dao;
|
||||||
import cn.dev33.satoken.oauth2.data.convert.SaOAuth2DataConverter;
|
import cn.dev33.satoken.oauth2.data.convert.SaOAuth2DataConverter;
|
||||||
import cn.dev33.satoken.oauth2.data.generate.SaOAuth2DataGenerate;
|
import cn.dev33.satoken.oauth2.data.generate.SaOAuth2DataGenerate;
|
||||||
@@ -52,7 +52,7 @@ public class SaOAuth2BeanInject {
|
|||||||
* @param saOAuth2Config 配置对象
|
* @param saOAuth2Config 配置对象
|
||||||
*/
|
*/
|
||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
public void setSaOAuth2Config(SaOAuth2Config saOAuth2Config) {
|
public void setSaOAuth2Config(SaOAuth2ServerConfig saOAuth2Config) {
|
||||||
SaOAuth2Manager.setConfig(saOAuth2Config);
|
SaOAuth2Manager.setConfig(saOAuth2Config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -16,7 +16,7 @@
|
|||||||
package cn.dev33.satoken.spring.oauth2;
|
package cn.dev33.satoken.spring.oauth2;
|
||||||
|
|
||||||
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
|
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.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
@@ -36,9 +36,9 @@ public class SaOAuth2BeanRegister {
|
|||||||
* @return 配置对象
|
* @return 配置对象
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@ConfigurationProperties(prefix = "sa-token.oauth2")
|
@ConfigurationProperties(prefix = "sa-token.oauth2-server")
|
||||||
public SaOAuth2Config getSaOAuth2Config() {
|
public SaOAuth2ServerConfig getSaOAuth2Config() {
|
||||||
return new SaOAuth2Config();
|
return new SaOAuth2ServerConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user