From 0d4830eb7d502809ebfb4c6fd877d1a81464da55 Mon Sep 17 00:00:00 2001
From: click33 <2393584716@qq.com>
Date: Mon, 7 Feb 2022 19:36:31 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BD=BFOAuth2=E6=A8=A1=E5=9D=97=E9=83=A8?=
=?UTF-8?q?=E5=88=86=E5=B1=9E=E6=80=A7=E6=94=AF=E6=8C=81=E6=AF=8F=E4=B8=AA?=
=?UTF-8?q?Client=E5=8D=95=E7=8B=AC=E9=85=8D=E7=BD=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../satoken/oauth2/config/SaOAuth2Config.java | 2 +-
.../satoken/oauth2/logic/SaOAuth2Handle.java | 1 -
.../oauth2/logic/SaOAuth2Template.java | 44 ++++---
.../satoken/oauth2/model/SaClientModel.java | 119 +++++++++++++++++-
4 files changed, 143 insertions(+), 23 deletions(-)
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/SaOAuth2Config.java
index 6f505bc8..62d3be66 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/SaOAuth2Config.java
@@ -42,7 +42,7 @@ public class SaOAuth2Config implements Serializable {
/** Client-Token 保存的时间(单位:秒) 默认两个小时 */
public long clientTokenTimeout = 60 * 60 * 2;
- /** Past-Client-Token 保存的时间(单位:秒) 默认為 null */
+ /** Past-Client-Token 保存的时间(单位:秒) 默认为 null,代表取 clientTokenTimeout 值 */
public Long pastClientTokenTimeout = null;
diff --git a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/logic/SaOAuth2Handle.java b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/logic/SaOAuth2Handle.java
index 7aefc0fd..e1a9684a 100644
--- a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/logic/SaOAuth2Handle.java
+++ b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/logic/SaOAuth2Handle.java
@@ -88,7 +88,6 @@ public class SaOAuth2Handle {
return password(req, res, cfg);
}
throw new SaOAuth2Exception("暂未开放的授权模式");
-
}
// 模式四:凭证式
diff --git a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/logic/SaOAuth2Template.java b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/logic/SaOAuth2Template.java
index c3ec9900..c5b9a316 100644
--- a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/logic/SaOAuth2Template.java
+++ b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/logic/SaOAuth2Template.java
@@ -181,9 +181,9 @@ public class SaOAuth2Template {
// 获取 Refresh-Token 信息
RefreshTokenModel rt = getRefreshToken(refreshToken);
SaOAuth2Exception.throwBy(rt == null, "无效refresh_token: " + refreshToken);
-
+
// 如果配置了[每次刷新产生新的Refresh-Token]
- if(SaOAuth2Manager.getConfig().getIsNewRefresh()) {
+ if(checkClientModel(rt.clientId).getIsNewRefresh()) {
// 删除旧 Refresh-Token
deleteRefreshToken(rt.refreshToken);
@@ -224,7 +224,7 @@ public class SaOAuth2Template {
String newAtValue = randomAccessToken(ra.clientId, ra.loginId, ra.scope);
AccessTokenModel at = new AccessTokenModel(newAtValue, ra.clientId, ra.loginId, ra.scope);
at.openid = getOpenid(ra.clientId, ra.loginId);
- at.expiresTime = System.currentTimeMillis() + (SaOAuth2Manager.getConfig().getAccessTokenTimeout() * 1000);
+ at.expiresTime = System.currentTimeMillis() + (checkClientModel(ra.clientId).getAccessTokenTimeout() * 1000);
// 3、生成&保存 Refresh-Token
if(isCreateRt) {
@@ -247,18 +247,25 @@ public class SaOAuth2Template {
* @return Client-Token Model
*/
public ClientTokenModel generateClientToken(String clientId, String scope) {
- // 1、删掉 Past-Token
+ // 1、删掉旧 Past-Token
deleteClientToken(getPastTokenValue(clientId));
- // 2、将Client-Token 标记 Past-Token
- String ctValue = getClientTokenValue(clientId);
- savePastTokenIndex(getClientToken(ctValue));
+ // 2、将旧Client-Token 标记为新 Past-Token
+ ClientTokenModel oldCt = getClientToken(getClientTokenValue(clientId));
+ savePastTokenIndex(oldCt);
+
+ // 2.5、如果配置了 PastClientToken 的 ttl ,则需要更新一下
+ SaClientModel cm = checkClientModel(clientId);
+ if(oldCt != null && cm.getPastClientTokenTimeout() != null) {
+ oldCt.expiresTime = System.currentTimeMillis() + (cm.getPastClientTokenTimeout() * 1000);
+ saveClientToken(oldCt);
+ }
- // 3、生成新Token
+ // 3、生成新Client-Token
ClientTokenModel ct = new ClientTokenModel(randomClientToken(clientId, scope), clientId, scope);
- ct.expiresTime = System.currentTimeMillis() + (SaOAuth2Manager.getConfig().getClientTokenTimeout() * 1000);
+ ct.expiresTime = System.currentTimeMillis() + (cm.getClientTokenTimeout() * 1000);
- // 3、保存新Token
+ // 3、保存新Client-Token
saveClientToken(ct);
saveClientTokenIndex(ct);
@@ -454,8 +461,8 @@ public class SaOAuth2Template {
at.loginId = cm.loginId;
at.scope = cm.scope;
at.openid = getOpenid(cm.clientId, cm.loginId);
- at.expiresTime = System.currentTimeMillis() + (SaOAuth2Manager.getConfig().getAccessTokenTimeout() * 1000);
- // at.refreshExpiresTime = System.currentTimeMillis() + (SaOAuth2Manager.getConfig().getRefreshTokenTimeout() * 1000);
+ at.expiresTime = System.currentTimeMillis() + (checkClientModel(cm.clientId).getAccessTokenTimeout() * 1000);
+ // at.refreshExpiresTime = System.currentTimeMillis() + (checkClientModel(cm.clientId).getRefreshTokenTimeout() * 1000);
return at;
}
/**
@@ -470,7 +477,7 @@ public class SaOAuth2Template {
rt.loginId = at.loginId;
rt.scope = at.scope;
rt.openid = at.openid;
- rt.expiresTime = System.currentTimeMillis() + (SaOAuth2Manager.getConfig().getRefreshTokenTimeout() * 1000);
+ rt.expiresTime = System.currentTimeMillis() + (checkClientModel(at.clientId).getRefreshTokenTimeout() * 1000);
// 改变at属性
at.refreshToken = rt.refreshToken;
at.refreshExpiresTime = rt.expiresTime;
@@ -489,7 +496,7 @@ public class SaOAuth2Template {
at.loginId = rt.loginId;
at.scope = rt.scope;
at.openid = rt.openid;
- at.expiresTime = System.currentTimeMillis() + (SaOAuth2Manager.getConfig().getAccessTokenTimeout() * 1000);
+ at.expiresTime = System.currentTimeMillis() + (checkClientModel(rt.clientId).getAccessTokenTimeout() * 1000);
at.refreshExpiresTime = rt.expiresTime;
return at;
}
@@ -501,7 +508,7 @@ public class SaOAuth2Template {
public RefreshTokenModel convertRefreshTokenToRefreshToken(RefreshTokenModel rt) {
RefreshTokenModel newRt = new RefreshTokenModel();
newRt.refreshToken = randomRefreshToken(rt.clientId, rt.loginId, rt.scope);
- newRt.expiresTime = System.currentTimeMillis() + (SaOAuth2Manager.getConfig().getRefreshTokenTimeout() * 1000);
+ newRt.expiresTime = System.currentTimeMillis() + (checkClientModel(rt.clientId).getRefreshTokenTimeout() * 1000);
newRt.clientId = rt.clientId;
newRt.scope = rt.scope;
newRt.loginId = rt.loginId;
@@ -599,8 +606,9 @@ public class SaOAuth2Template {
return;
}
Long ttl = ct.getExpiresIn();
- if (null != SaOAuth2Manager.getConfig().getPastClientTokenTimeout()) {
- ttl = SaOAuth2Manager.getConfig().getPastClientTokenTimeout();
+ SaClientModel cm = checkClientModel(ct.clientId);
+ if (null != cm.getPastClientTokenTimeout()) {
+ ttl = cm.getPastClientTokenTimeout();
}
SaManager.getSaTokenDao().set(splicingPastTokenIndexKey(ct.clientId), ct.clientToken, ttl);
}
@@ -612,7 +620,7 @@ public class SaOAuth2Template {
*/
public void saveGrantScope(String clientId, Object loginId, String scope) {
if(SaFoxUtil.isEmpty(scope) == false) {
- long ttl = SaOAuth2Manager.getConfig().getAccessTokenTimeout();
+ long ttl = checkClientModel(clientId).getAccessTokenTimeout();
SaManager.getSaTokenDao().set(splicingGrantScopeKey(clientId, loginId), scope, ttl);
}
}
diff --git a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/model/SaClientModel.java b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/model/SaClientModel.java
index 8c6fd31c..ea0ff687 100644
--- a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/model/SaClientModel.java
+++ b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/model/SaClientModel.java
@@ -2,6 +2,9 @@ package cn.dev33.satoken.oauth2.model;
import java.io.Serializable;
+import cn.dev33.satoken.oauth2.SaOAuth2Manager;
+import cn.dev33.satoken.oauth2.config.SaOAuth2Config;
+
/**
* Client应用信息 Model
* @author kong
@@ -43,11 +46,36 @@ public class SaClientModel implements Serializable {
/** 此 Client 是否打开模式:凭证式(Client Credentials) */
public Boolean isClient = false;
- /** 是否自动判断开放的授权模式,此值为true时单独设置(isCode、isImplicit、isPassword、isClient)不再有效,而是跟随全局设置 */
+ /**
+ * 是否自动判断开放的授权模式
+ *
此值为true时:四种模式(isCode、isImplicit、isPassword、isClient)是否生效,依靠全局设置
+ *
此值为false时:四种模式(isCode、isImplicit、isPassword、isClient)是否生效,依靠局部配置+全局配置
+ */
public Boolean isAutoMode = false;
+ /** 单独配置此Client:是否在每次 Refresh-Token 刷新 Access-Token 时,产生一个新的 Refresh-Token [默认取全局配置] */
+ public Boolean isNewRefresh;
+
+ /** 单独配置此Client:Access-Token 保存的时间(单位秒) [默认取全局配置] */
+ public long accessTokenTimeout;
+
+ /** 单独配置此Client:Refresh-Token 保存的时间(单位秒) [默认取全局配置] */
+ public long refreshTokenTimeout;
+
+ /** 单独配置此Client:Client-Token 保存的时间(单位秒) [默认取全局配置] */
+ public long clientTokenTimeout;
+
+ /** 单独配置此Client:Past-Client-Token 保存的时间(单位:秒) [默认取全局配置] */
+ public Long pastClientTokenTimeout;
+
+
public SaClientModel() {
-
+ SaOAuth2Config 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, String contractScope, String allowUrl) {
super();
@@ -202,12 +230,97 @@ public class SaClientModel implements Serializable {
return this;
}
+
+ /**
+ * @return 此Client:是否在每次 Refresh-Token 刷新 Access-Token 时,产生一个新的 Refresh-Token [默认取全局配置]
+ */
+ public Boolean getIsNewRefresh() {
+ return isNewRefresh;
+ }
+
+ /**
+ * @param isNewRefresh 单独配置此Client:是否在每次 Refresh-Token 刷新 Access-Token 时,产生一个新的 Refresh-Token [默认取全局配置]
+ * @return 对象自身
+ */
+ public SaClientModel setIsNewRefresh(Boolean isNewRefresh) {
+ this.isNewRefresh = isNewRefresh;
+ return this;
+ }
+
+ /**
+ * @return 此Client:Access-Token 保存的时间(单位秒) [默认取全局配置]
+ */
+ public long getAccessTokenTimeout() {
+ return accessTokenTimeout;
+ }
+
+ /**
+ * @param accessTokenTimeout 单独配置此Client:Access-Token 保存的时间(单位秒) [默认取全局配置]
+ * @return 对象自身
+ */
+ public SaClientModel setAccessTokenTimeout(long accessTokenTimeout) {
+ this.accessTokenTimeout = accessTokenTimeout;
+ return this;
+ }
+
+ /**
+ * @return 此Client:Refresh-Token 保存的时间(单位秒) [默认取全局配置]
+ */
+ public long getRefreshTokenTimeout() {
+ return refreshTokenTimeout;
+ }
+
+ /**
+ * @param refreshTokenTimeout 单独配置此Client:Refresh-Token 保存的时间(单位秒) [默认取全局配置]
+ * @return 对象自身
+ */
+ public SaClientModel setRefreshTokenTimeout(long refreshTokenTimeout) {
+ this.refreshTokenTimeout = refreshTokenTimeout;
+ return this;
+ }
+
+ /**
+ * @return 此Client:Client-Token 保存的时间(单位秒) [默认取全局配置]
+ */
+ public long getClientTokenTimeout() {
+ return clientTokenTimeout;
+ }
+
+ /**
+ * @param clientTokenTimeout 单独配置此Client:Client-Token 保存的时间(单位秒) [默认取全局配置]
+ * @return 对象自身
+ */
+ public SaClientModel setClientTokenTimeout(long clientTokenTimeout) {
+ this.clientTokenTimeout = clientTokenTimeout;
+ return this;
+ }
+
+ /**
+ * @return 此Client:Past-Client-Token 保存的时间(单位:秒) [默认取全局配置]
+ */
+ public Long getPastClientTokenTimeout() {
+ return pastClientTokenTimeout;
+ }
+
+ /**
+ * @param pastClientTokenTimeout 单独配置此Client:Past-Client-Token 保存的时间(单位:秒) [默认取全局配置]
+ * @return 对象自身
+ */
+ public SaClientModel setPastClientTokenTimeout(Long pastClientTokenTimeout) {
+ this.pastClientTokenTimeout = pastClientTokenTimeout;
+ return this;
+ }
+
//
@Override
public String toString() {
return "SaClientModel [clientId=" + clientId + ", clientSecret=" + clientSecret + ", contractScope="
+ contractScope + ", allowUrl=" + allowUrl + ", isCode=" + isCode + ", isImplicit=" + isImplicit
- + ", isPassword=" + isPassword + ", isClient=" + isClient + ", isAutoMode=" + isAutoMode + "]";
+ + ", isPassword=" + isPassword + ", isClient=" + isClient + ", isAutoMode=" + isAutoMode
+ + ", isNewRefresh=" + isNewRefresh + ", accessTokenTimeout=" + accessTokenTimeout
+ + ", refreshTokenTimeout=" + refreshTokenTimeout + ", clientTokenTimeout=" + clientTokenTimeout
+ + ", pastClientTokenTimeout=" + pastClientTokenTimeout + "]";
}
+
}