抽离 SaOAuth2Dao 接口,负责数据持久

This commit is contained in:
click33 2024-08-17 18:29:54 +08:00
parent d9f9238591
commit b4c06f2265
6 changed files with 667 additions and 426 deletions

View File

@ -16,6 +16,8 @@
package cn.dev33.satoken.oauth2;
import cn.dev33.satoken.oauth2.config.SaOAuth2Config;
import cn.dev33.satoken.oauth2.dao.SaOAuth2Dao;
import cn.dev33.satoken.oauth2.dao.SaOAuth2DaoDefaultImpl;
import cn.dev33.satoken.oauth2.data.convert.SaOAuth2DataConverter;
import cn.dev33.satoken.oauth2.data.convert.SaOAuth2DataConverterDefaultImpl;
import cn.dev33.satoken.oauth2.data.loader.SaOAuth2DataLoader;
@ -104,4 +106,22 @@ public class SaOAuth2Manager {
SaOAuth2Manager.dataConverter = dataConverter;
}
/**
* OAuth2 数据持久 Bean
*/
private static volatile SaOAuth2Dao dao;
public static SaOAuth2Dao getDao() {
if (dao == null) {
synchronized (SaOAuth2Manager.class) {
if (dao == null) {
setDao(new SaOAuth2DaoDefaultImpl());
}
}
}
return dao;
}
public static void setDao(SaOAuth2Dao dao) {
SaOAuth2Manager.dao = dao;
}
}

View File

@ -0,0 +1,484 @@
/*
* Copyright 2020-2099 sa-token.cc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.dev33.satoken.oauth2.dao;
import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.config.SaTokenConfig;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
import cn.dev33.satoken.oauth2.data.model.AccessTokenModel;
import cn.dev33.satoken.oauth2.data.model.ClientTokenModel;
import cn.dev33.satoken.oauth2.data.model.CodeModel;
import cn.dev33.satoken.oauth2.data.model.RefreshTokenModel;
import cn.dev33.satoken.util.SaFoxUtil;
import java.util.List;
/**
* Sa-Token OAuth2 数据持久层
*
* @author click33
* @since 1.39.0
*/
public interface SaOAuth2Dao {
// ------------------- save 数据
/**
* 持久化Code-Model
* @param c .
*/
default void saveCode(CodeModel c) {
if(c == null) {
return;
}
getSaTokenDao().setObject(splicingCodeSaveKey(c.code), c, SaOAuth2Manager.getConfig().getCodeTimeout());
}
/**
* 持久化Code-索引
* @param c .
*/
default void saveCodeIndex(CodeModel c) {
if(c == null) {
return;
}
getSaTokenDao().set(splicingCodeIndexKey(c.clientId, c.loginId), c.code, SaOAuth2Manager.getConfig().getCodeTimeout());
}
/**
* 持久化AccessToken-Model
* @param at .
*/
default void saveAccessToken(AccessTokenModel at) {
if(at == null) {
return;
}
getSaTokenDao().setObject(splicingAccessTokenSaveKey(at.accessToken), at, at.getExpiresIn());
}
/**
* 持久化AccessToken-索引
* @param at .
*/
default void saveAccessTokenIndex(AccessTokenModel at) {
if(at == null) {
return;
}
getSaTokenDao().set(splicingAccessTokenIndexKey(at.clientId, at.loginId), at.accessToken, at.getExpiresIn());
}
/**
* 持久化RefreshToken-Model
* @param rt .
*/
default void saveRefreshToken(RefreshTokenModel rt) {
if(rt == null) {
return;
}
getSaTokenDao().setObject(splicingRefreshTokenSaveKey(rt.refreshToken), rt, rt.getExpiresIn());
}
/**
* 持久化RefreshToken-索引
* @param rt .
*/
default void saveRefreshTokenIndex(RefreshTokenModel rt) {
if(rt == null) {
return;
}
getSaTokenDao().set(splicingRefreshTokenIndexKey(rt.clientId, rt.loginId), rt.refreshToken, rt.getExpiresIn());
}
/**
* 持久化ClientToken-Model
* @param ct .
*/
default void saveClientToken(ClientTokenModel ct) {
if(ct == null) {
return;
}
getSaTokenDao().setObject(splicingClientTokenSaveKey(ct.clientToken), ct, ct.getExpiresIn());
}
/**
* 持久化ClientToken-索引
* @param ct .
*/
default void saveClientTokenIndex(ClientTokenModel ct) {
if(ct == null) {
return;
}
getSaTokenDao().set(splicingClientTokenIndexKey(ct.clientId), ct.clientToken, ct.getExpiresIn());
}
/**
* 持久化Past-Token-索引
* @param ct /
*/
default void savePastTokenIndex(ClientTokenModel ct) {
if(ct == null) {
return;
}
long ttl = ct.getExpiresIn();
// TODO PastToken ttl 是否有必要单独配置个字段
// SaClientModel cm = checkClientModel(ct.clientId);
// if (cm.getPastClientTokenTimeout() != -1) {
// ttl = cm.getPastClientTokenTimeout();
// }
getSaTokenDao().set(splicingPastTokenIndexKey(ct.clientId), ct.clientToken, ttl);
}
/**
* 持久化用户授权记录
* @param clientId 应用id
* @param loginId 账号id
* @param scopes 权限列表
*/
default void saveGrantScope(String clientId, Object loginId, List<String> scopes) {
if( ! SaFoxUtil.isEmpty(scopes)) {
// TODO ttl 计算规则优化
long ttl = SaOAuth2Manager.getConfig().getAccessTokenTimeout();
// long ttl = checkClientModel(clientId).getAccessTokenTimeout();
String value = SaOAuth2Manager.getDataConverter().convertScopeListToString(scopes);
getSaTokenDao().set(splicingGrantScopeKey(clientId, loginId), value, ttl);
}
}
// ------------------- delete数据
/**
* 删除Code
* @param code
*/
default void deleteCode(String code) {
if(code != null) {
getSaTokenDao().deleteObject(splicingCodeSaveKey(code));
}
}
/**
* 删除Code索引
* @param clientId 应用id
* @param loginId 账号id
*/
default void deleteCodeIndex(String clientId, Object loginId) {
getSaTokenDao().delete(splicingCodeIndexKey(clientId, loginId));
}
/**
* 删除Access-Token
* @param accessToken
*/
default void deleteAccessToken(String accessToken) {
if(accessToken != null) {
getSaTokenDao().deleteObject(splicingAccessTokenSaveKey(accessToken));
}
}
/**
* 删除Access-Token索引
* @param clientId 应用id
* @param loginId 账号id
*/
default void deleteAccessTokenIndex(String clientId, Object loginId) {
getSaTokenDao().delete(splicingAccessTokenIndexKey(clientId, loginId));
}
/**
* 删除Refresh-Token
* @param refreshToken
*/
default void deleteRefreshToken(String refreshToken) {
if(refreshToken != null) {
getSaTokenDao().deleteObject(splicingRefreshTokenSaveKey(refreshToken));
}
}
/**
* 删除Refresh-Token索引
* @param clientId 应用id
* @param loginId 账号id
*/
default void deleteRefreshTokenIndex(String clientId, Object loginId) {
getSaTokenDao().delete(splicingRefreshTokenIndexKey(clientId, loginId));
}
/**
* 删除Client-Token
* @param clientToken
*/
default void deleteClientToken(String clientToken) {
if(clientToken != null) {
getSaTokenDao().deleteObject(splicingClientTokenSaveKey(clientToken));
}
}
/**
* 删除Client-Token索引
* @param clientId 应用id
*/
default void deleteClientTokenIndex(String clientId) {
getSaTokenDao().delete(splicingClientTokenIndexKey(clientId));
}
/**
* 删除Past-Token索引
* @param clientId 应用id
*/
default void deletePastTokenIndex(String clientId) {
getSaTokenDao().delete(splicingPastTokenIndexKey(clientId));
}
/**
* 删除用户授权记录
* @param clientId 应用id
* @param loginId 账号id
*/
default void deleteGrantScope(String clientId, Object loginId) {
getSaTokenDao().delete(splicingGrantScopeKey(clientId, loginId));
}
// ------------------- get 数据
/**
* 获取Code Model
* @param code .
* @return .
*/
default CodeModel getCode(String code) {
if(code == null) {
return null;
}
return (CodeModel)getSaTokenDao().getObject(splicingCodeSaveKey(code));
}
/**
* 获取Code Value
* @param clientId 应用id
* @param loginId 账号id
* @return .
*/
default String getCodeValue(String clientId, Object loginId) {
return getSaTokenDao().get(splicingCodeIndexKey(clientId, loginId));
}
/**
* 获取Access-Token Model
* @param accessToken .
* @return .
*/
default AccessTokenModel getAccessToken(String accessToken) {
if(accessToken == null) {
return null;
}
return (AccessTokenModel)getSaTokenDao().getObject(splicingAccessTokenSaveKey(accessToken));
}
/**
* 获取Access-Token Value
* @param clientId 应用id
* @param loginId 账号id
* @return .
*/
default String getAccessTokenValue(String clientId, Object loginId) {
return getSaTokenDao().get(splicingAccessTokenIndexKey(clientId, loginId));
}
/**
* 获取Refresh-Token Model
* @param refreshToken .
* @return .
*/
default RefreshTokenModel getRefreshToken(String refreshToken) {
if(refreshToken == null) {
return null;
}
return (RefreshTokenModel)getSaTokenDao().getObject(splicingRefreshTokenSaveKey(refreshToken));
}
/**
* 获取Refresh-Token Value
* @param clientId 应用id
* @param loginId 账号id
* @return .
*/
default String getRefreshTokenValue(String clientId, Object loginId) {
return getSaTokenDao().get(splicingRefreshTokenIndexKey(clientId, loginId));
}
/**
* 获取Client-Token Model
* @param clientToken .
* @return .
*/
default ClientTokenModel getClientToken(String clientToken) {
if(clientToken == null) {
return null;
}
return (ClientTokenModel)getSaTokenDao().getObject(splicingClientTokenSaveKey(clientToken));
}
/**
* 获取Client-Token Value
* @param clientId 应用id
* @return .
*/
default String getClientTokenValue(String clientId) {
return getSaTokenDao().get(splicingClientTokenIndexKey(clientId));
}
/**
* 获取Past-Token Value
* @param clientId 应用id
* @return .
*/
default String getPastTokenValue(String clientId) {
return getSaTokenDao().get(splicingPastTokenIndexKey(clientId));
}
/**
* 获取用户授权记录
* @param clientId 应用id
* @param loginId 账号id
* @return 权限
*/
default List<String> getGrantScope(String clientId, Object loginId) {
String value = getSaTokenDao().get(splicingGrantScopeKey(clientId, loginId));
return SaOAuth2Manager.getDataConverter().convertScopeStringToList(value);
}
// ------------------- 拼接key
/**
* 拼接keyCode持久化
* @param code 授权码
* @return key
*/
default String splicingCodeSaveKey(String code) {
return getSaTokenConfig().getTokenName() + ":oauth2:code:" + code;
}
/**
* 拼接keyCode索引
* @param clientId 应用id
* @param loginId 账号id
* @return key
*/
default String splicingCodeIndexKey(String clientId, Object loginId) {
return getSaTokenConfig().getTokenName() + ":oauth2:code-index:" + clientId + ":" + loginId;
}
/**
* 拼接keyAccess-Token持久化
* @param accessToken accessToken
* @return key
*/
default String splicingAccessTokenSaveKey(String accessToken) {
return getSaTokenConfig().getTokenName() + ":oauth2:access-token:" + accessToken;
}
/**
* 拼接keyAccess-Token索引
* @param clientId 应用id
* @param loginId 账号id
* @return key
*/
default String splicingAccessTokenIndexKey(String clientId, Object loginId) {
return getSaTokenConfig().getTokenName() + ":oauth2:access-token-index:" + clientId + ":" + loginId;
}
/**
* 拼接keyRefresh-Token持久化
* @param refreshToken refreshToken
* @return key
*/
default String splicingRefreshTokenSaveKey(String refreshToken) {
return getSaTokenConfig().getTokenName() + ":oauth2:refresh-token:" + refreshToken;
}
/**
* 拼接keyRefresh-Token索引
* @param clientId 应用id
* @param loginId 账号id
* @return key
*/
default String splicingRefreshTokenIndexKey(String clientId, Object loginId) {
return getSaTokenConfig().getTokenName() + ":oauth2:refresh-token-index:" + clientId + ":" + loginId;
}
/**
* 拼接keyClient-Token持久化
* @param clientToken clientToken
* @return key
*/
default String splicingClientTokenSaveKey(String clientToken) {
return getSaTokenConfig().getTokenName() + ":oauth2:client-token:" + clientToken;
}
/**
* 拼接keyClient-Token 索引
* @param clientId clientId
* @return key
*/
default String splicingClientTokenIndexKey(String clientId) {
return getSaTokenConfig().getTokenName() + ":oauth2:client-token-index:" + clientId;
}
/**
* 拼接keyPast-Token 索引
* @param clientId clientId
* @return key
*/
default String splicingPastTokenIndexKey(String clientId) {
return getSaTokenConfig().getTokenName() + ":oauth2:past-token-index:" + clientId;
}
/**
* 拼接key用户授权记录
* @param clientId 应用id
* @param loginId 账号id
* @return key
*/
default String splicingGrantScopeKey(String clientId, Object loginId) {
return getSaTokenConfig().getTokenName() + ":oauth2:grant-scope:" + clientId + ":" + loginId;
}
// -------- bean 对象代理
/**
* 获取使用的 getSaTokenDao 实例
*
* @return /
*/
default SaTokenDao getSaTokenDao() {
return SaManager.getSaTokenDao();
}
/**
* 获取使用的 SaTokenConfig 实例
*
* @return /
*/
default SaTokenConfig getSaTokenConfig() {
return SaManager.getConfig();
}
}

View File

@ -0,0 +1,26 @@
/*
* Copyright 2020-2099 sa-token.cc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.dev33.satoken.oauth2.dao;
/**
* Sa-Token OAuth2 数据持久层默认实现
*
* @author click33
* @since 1.39.0
*/
public class SaOAuth2DaoDefaultImpl implements SaOAuth2Dao {
}

View File

@ -0,0 +1,44 @@
/*
* Copyright 2020-2099 sa-token.cc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.dev33.satoken.oauth2.scope;
/**
* OAuth2 常见权限定义
*
* @author click33
* @since 1.39.0
*/
public final class CommonScope {
private CommonScope() {
}
/**
* 获取 openid
*/
public static final String OPENID = "openid";
/**
* 获取用户信息
*/
public static final String USERINFO = "userinfo";
/**
* 获取 id_token
*/
public static final String OIDC = "oidc";
}

View File

@ -15,10 +15,10 @@
*/
package cn.dev33.satoken.oauth2.template;
import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.context.model.SaRequest;
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
import cn.dev33.satoken.oauth2.consts.SaOAuth2Consts.Param;
import cn.dev33.satoken.oauth2.dao.SaOAuth2Dao;
import cn.dev33.satoken.oauth2.data.model.*;
import cn.dev33.satoken.oauth2.error.SaOAuth2ErrorCode;
import cn.dev33.satoken.oauth2.exception.SaOAuth2Exception;
@ -76,7 +76,7 @@ public class SaOAuth2Template {
* @return .
*/
public AccessTokenModel checkAccessToken(String accessToken) {
AccessTokenModel at = getAccessToken(accessToken);
AccessTokenModel at = SaOAuth2Manager.getDao().getAccessToken(accessToken);
SaOAuth2Exception.throwBy(at == null, "无效access_token" + accessToken, SaOAuth2ErrorCode.CODE_30106);
return at;
}
@ -86,7 +86,7 @@ public class SaOAuth2Template {
* @return .
*/
public ClientTokenModel checkClientToken(String clientToken) {
ClientTokenModel ct = getClientToken(clientToken);
ClientTokenModel ct = SaOAuth2Manager.getDao().getClientToken(clientToken);
SaOAuth2Exception.throwBy(ct == null, "无效client_token" + clientToken, SaOAuth2ErrorCode.CODE_30107);
return ct;
}
@ -155,16 +155,19 @@ public class SaOAuth2Template {
*/
public CodeModel generateCode(RequestAuthModel ra) {
SaOAuth2Dao dao = SaOAuth2Manager.getDao();
// 删除旧Code
deleteCode(getCodeValue(ra.clientId, ra.loginId));
String oldCodeValue = SaOAuth2Manager.getDao().getCodeValue(ra.clientId, ra.loginId);
dao.deleteCode(oldCodeValue);
// 生成新Code
String code = randomCode(ra.clientId, ra.loginId, ra.scopes);
CodeModel cm = new CodeModel(code, ra.clientId, ra.scopes, ra.loginId, ra.redirectUri);
String codeValue = randomCode(ra.clientId, ra.loginId, ra.scopes);
CodeModel cm = new CodeModel(codeValue, ra.clientId, ra.scopes, ra.loginId, ra.redirectUri);
// 保存新Code
saveCode(cm);
saveCodeIndex(cm);
dao.saveCode(cm);
dao.saveCodeIndex(cm);
// 返回
return cm;
@ -176,13 +179,15 @@ public class SaOAuth2Template {
*/
public AccessTokenModel generateAccessToken(String code) {
SaOAuth2Dao dao = SaOAuth2Manager.getDao();
// 1先校验
CodeModel cm = getCode(code);
CodeModel cm = dao.getCode(code);
SaOAuth2Exception.throwBy(cm == null, "无效code", SaOAuth2ErrorCode.CODE_30110);
// 2删除旧Token
deleteAccessToken(getAccessTokenValue(cm.clientId, cm.loginId));
deleteRefreshToken(getRefreshTokenValue(cm.clientId, cm.loginId));
dao.deleteAccessToken(dao.getAccessTokenValue(cm.clientId, cm.loginId));
dao.deleteRefreshToken(dao.getRefreshTokenValue(cm.clientId, cm.loginId));
// 3生成token
AccessTokenModel at = convertCodeToAccessToken(cm);
@ -191,14 +196,14 @@ public class SaOAuth2Template {
at.refreshExpiresTime = rt.expiresTime;
// 4保存token
saveAccessToken(at);
saveAccessTokenIndex(at);
saveRefreshToken(rt);
saveRefreshTokenIndex(rt);
dao.saveAccessToken(at);
dao.saveAccessTokenIndex(at);
dao.saveRefreshToken(rt);
dao.saveRefreshTokenIndex(rt);
// 5删除此Code
deleteCode(code);
deleteCodeIndex(cm.clientId, cm.loginId);
dao.deleteCode(code);
dao.deleteCodeIndex(cm.clientId, cm.loginId);
// 6返回 Access-Token
return at;
@ -210,30 +215,32 @@ public class SaOAuth2Template {
*/
public AccessTokenModel refreshAccessToken(String refreshToken) {
SaOAuth2Dao dao = SaOAuth2Manager.getDao();
// 获取 Refresh-Token 信息
RefreshTokenModel rt = getRefreshToken(refreshToken);
RefreshTokenModel rt = dao.getRefreshToken(refreshToken);
SaOAuth2Exception.throwBy(rt == null, "无效refresh_token: " + refreshToken, SaOAuth2ErrorCode.CODE_30111);
// 如果配置了[每次刷新产生新的Refresh-Token]
if(checkClientModel(rt.clientId).getIsNewRefresh()) {
// 删除旧 Refresh-Token
deleteRefreshToken(rt.refreshToken);
dao.deleteRefreshToken(rt.refreshToken);
// 创建并保持新的 Refresh-Token
rt = convertRefreshTokenToRefreshToken(rt);
saveRefreshToken(rt);
saveRefreshTokenIndex(rt);
dao.saveRefreshToken(rt);
dao.saveRefreshTokenIndex(rt);
}
// 删除旧 Access-Token
deleteAccessToken(getAccessTokenValue(rt.clientId, rt.loginId));
dao.deleteAccessToken(dao.getAccessTokenValue(rt.clientId, rt.loginId));
// 生成新 Access-Token
AccessTokenModel at = convertRefreshTokenToAccessToken(rt);
// 保存新 Access-Token
saveAccessToken(at);
saveAccessTokenIndex(at);
dao.saveAccessToken(at);
dao.saveAccessTokenIndex(at);
// 返回新 Access-Token
return at;
@ -246,10 +253,12 @@ public class SaOAuth2Template {
*/
public AccessTokenModel generateAccessToken(RequestAuthModel ra, boolean isCreateRt) {
SaOAuth2Dao dao = SaOAuth2Manager.getDao();
// 1删除 旧Token
deleteAccessToken(getAccessTokenValue(ra.clientId, ra.loginId));
dao.deleteAccessToken(dao.getAccessTokenValue(ra.clientId, ra.loginId));
if(isCreateRt) {
deleteRefreshToken(getRefreshTokenValue(ra.clientId, ra.loginId));
dao.deleteRefreshToken(dao.getRefreshTokenValue(ra.clientId, ra.loginId));
}
// 2生成 新Access-Token
@ -261,13 +270,13 @@ public class SaOAuth2Template {
// 3生成&保存 Refresh-Token
if(isCreateRt) {
RefreshTokenModel rt = convertAccessTokenToRefreshToken(at);
saveRefreshToken(rt);
saveRefreshTokenIndex(rt);
dao.saveRefreshToken(rt);
dao.saveRefreshTokenIndex(rt);
}
// 5保存 新Access-Token
saveAccessToken(at);
saveAccessTokenIndex(at);
dao.saveAccessToken(at);
dao.saveAccessTokenIndex(at);
// 6返回 新Access-Token
return at;
@ -279,18 +288,21 @@ public class SaOAuth2Template {
* @return Client-Token Model
*/
public ClientTokenModel generateClientToken(String clientId, List<String> scopes) {
SaOAuth2Dao dao = SaOAuth2Manager.getDao();
// 1删掉旧 Past-Token
deleteClientToken(getPastTokenValue(clientId));
dao.deleteClientToken(dao.getPastTokenValue(clientId));
// 2将旧Client-Token 标记为新 Past-Token
ClientTokenModel oldCt = getClientToken(getClientTokenValue(clientId));
savePastTokenIndex(oldCt);
ClientTokenModel oldCt = dao.getClientToken(dao.getClientTokenValue(clientId));
dao.savePastTokenIndex(oldCt);
// 2.5如果配置了 PastClientToken ttl 则需要更新一下
SaClientModel cm = checkClientModel(clientId);
if(oldCt != null && cm.getPastClientTokenTimeout() != -1) {
oldCt.expiresTime = System.currentTimeMillis() + (cm.getPastClientTokenTimeout() * 1000);
saveClientToken(oldCt);
dao.saveClientToken(oldCt);
}
// 3生成新Client-Token
@ -298,8 +310,8 @@ public class SaOAuth2Template {
ct.expiresTime = System.currentTimeMillis() + (cm.getClientTokenTimeout() * 1000);
// 3保存新Client-Token
saveClientToken(ct);
saveClientTokenIndex(ct);
dao.saveClientToken(ct);
dao.saveClientTokenIndex(ct);
// 4返回
return ct;
@ -338,20 +350,22 @@ public class SaOAuth2Template {
*/
public void revokeAccessToken(String accessToken) {
SaOAuth2Dao dao = SaOAuth2Manager.getDao();
// 如果查不到任何东西, 直接返回
AccessTokenModel at = getAccessToken(accessToken);
AccessTokenModel at = dao.getAccessToken(accessToken);
if(at == null) {
return;
}
// 删除 Access-Token
deleteAccessToken(accessToken);
deleteAccessTokenIndex(at.clientId, at.loginId);
dao.deleteAccessToken(accessToken);
dao.deleteAccessTokenIndex(at.clientId, at.loginId);
// 删除对应的 Refresh-Token
String refreshToken = getRefreshTokenValue(at.clientId, at.loginId);
deleteRefreshToken(refreshToken);
deleteRefreshTokenIndex(at.clientId, at.loginId);
String refreshToken = dao.getRefreshTokenValue(at.clientId, at.loginId);
dao.deleteRefreshToken(refreshToken);
dao.deleteRefreshTokenIndex(at.clientId, at.loginId);
}
// ------------------- check 数据校验
@ -363,7 +377,8 @@ public class SaOAuth2Template {
* @return 是否已经授权
*/
public boolean isGrant(Object loginId, String clientId, List<String> scopes) {
List<String> grantScopeList = getGrantScope(clientId, loginId);
SaOAuth2Dao dao = SaOAuth2Manager.getDao();
List<String> grantScopeList = dao.getGrantScope(clientId, loginId);
return scopes.isEmpty() || new HashSet<>(grantScopeList).containsAll(scopes);
}
/**
@ -511,8 +526,10 @@ public class SaOAuth2Template {
*/
public CodeModel checkGainTokenParam(String code, String clientId, String clientSecret, String redirectUri) {
SaOAuth2Dao dao = SaOAuth2Manager.getDao();
// 校验Code是否存在
CodeModel cm = getCode(code);
CodeModel cm = dao.getCode(code);
SaOAuth2Exception.throwBy(cm == null, "无效code: " + code, SaOAuth2ErrorCode.CODE_30117);
// 校验ClientId是否一致
@ -539,8 +556,10 @@ public class SaOAuth2Template {
*/
public RefreshTokenModel checkRefreshTokenParam(String clientId, String clientSecret, String refreshToken) {
SaOAuth2Dao dao = SaOAuth2Manager.getDao();
// 校验Refresh-Token是否存在
RefreshTokenModel rt = getRefreshToken(refreshToken);
RefreshTokenModel rt = dao.getRefreshToken(refreshToken);
SaOAuth2Exception.throwBy(rt == null, "无效refresh_token: " + refreshToken, SaOAuth2ErrorCode.CODE_30121);
// 校验ClientId是否一致
@ -636,299 +655,6 @@ public class SaOAuth2Template {
return newRt;
}
// ------------------- save 数据
/**
* 持久化Code-Model
* @param c .
*/
public void saveCode(CodeModel c) {
if(c == null) {
return;
}
SaManager.getSaTokenDao().setObject(splicingCodeSaveKey(c.code), c, SaOAuth2Manager.getConfig().getCodeTimeout());
}
/**
* 持久化Code-索引
* @param c .
*/
public void saveCodeIndex(CodeModel c) {
if(c == null) {
return;
}
SaManager.getSaTokenDao().set(splicingCodeIndexKey(c.clientId, c.loginId), c.code, SaOAuth2Manager.getConfig().getCodeTimeout());
}
/**
* 持久化AccessToken-Model
* @param at .
*/
public void saveAccessToken(AccessTokenModel at) {
if(at == null) {
return;
}
SaManager.getSaTokenDao().setObject(splicingAccessTokenSaveKey(at.accessToken), at, at.getExpiresIn());
}
/**
* 持久化AccessToken-索引
* @param at .
*/
public void saveAccessTokenIndex(AccessTokenModel at) {
if(at == null) {
return;
}
SaManager.getSaTokenDao().set(splicingAccessTokenIndexKey(at.clientId, at.loginId), at.accessToken, at.getExpiresIn());
}
/**
* 持久化RefreshToken-Model
* @param rt .
*/
public void saveRefreshToken(RefreshTokenModel rt) {
if(rt == null) {
return;
}
SaManager.getSaTokenDao().setObject(splicingRefreshTokenSaveKey(rt.refreshToken), rt, rt.getExpiresIn());
}
/**
* 持久化RefreshToken-索引
* @param rt .
*/
public void saveRefreshTokenIndex(RefreshTokenModel rt) {
if(rt == null) {
return;
}
SaManager.getSaTokenDao().set(splicingRefreshTokenIndexKey(rt.clientId, rt.loginId), rt.refreshToken, rt.getExpiresIn());
}
/**
* 持久化ClientToken-Model
* @param ct .
*/
public void saveClientToken(ClientTokenModel ct) {
if(ct == null) {
return;
}
SaManager.getSaTokenDao().setObject(splicingClientTokenSaveKey(ct.clientToken), ct, ct.getExpiresIn());
}
/**
* 持久化ClientToken-索引
* @param ct .
*/
public void saveClientTokenIndex(ClientTokenModel ct) {
if(ct == null) {
return;
}
SaManager.getSaTokenDao().set(splicingClientTokenIndexKey(ct.clientId), ct.clientToken, ct.getExpiresIn());
}
/**
* 持久化Past-Token-索引
* @param ct .
*/
public void savePastTokenIndex(ClientTokenModel ct) {
if(ct == null) {
return;
}
long ttl = ct.getExpiresIn();
SaClientModel cm = checkClientModel(ct.clientId);
if (cm.getPastClientTokenTimeout() != -1) {
ttl = cm.getPastClientTokenTimeout();
}
SaManager.getSaTokenDao().set(splicingPastTokenIndexKey(ct.clientId), ct.clientToken, ttl);
}
/**
* 持久化用户授权记录
* @param clientId 应用id
* @param loginId 账号id
* @param scopes 权限列表
*/
public void saveGrantScope(String clientId, Object loginId, List<String> scopes) {
if( ! SaFoxUtil.isEmpty(scopes)) {
long ttl = checkClientModel(clientId).getAccessTokenTimeout();
String value = SaOAuth2Manager.getDataConverter().convertScopeListToString(scopes);
SaManager.getSaTokenDao().set(splicingGrantScopeKey(clientId, loginId), value, ttl);
}
}
// ------------------- get 数据
/**
* 获取Code Model
* @param code .
* @return .
*/
public CodeModel getCode(String code) {
if(code == null) {
return null;
}
return (CodeModel)SaManager.getSaTokenDao().getObject(splicingCodeSaveKey(code));
}
/**
* 获取Code Value
* @param clientId 应用id
* @param loginId 账号id
* @return .
*/
public String getCodeValue(String clientId, Object loginId) {
return SaManager.getSaTokenDao().get(splicingCodeIndexKey(clientId, loginId));
}
/**
* 获取Access-Token Model
* @param accessToken .
* @return .
*/
public AccessTokenModel getAccessToken(String accessToken) {
if(accessToken == null) {
return null;
}
return (AccessTokenModel)SaManager.getSaTokenDao().getObject(splicingAccessTokenSaveKey(accessToken));
}
/**
* 获取Access-Token Value
* @param clientId 应用id
* @param loginId 账号id
* @return .
*/
public String getAccessTokenValue(String clientId, Object loginId) {
return SaManager.getSaTokenDao().get(splicingAccessTokenIndexKey(clientId, loginId));
}
/**
* 获取Refresh-Token Model
* @param refreshToken .
* @return .
*/
public RefreshTokenModel getRefreshToken(String refreshToken) {
if(refreshToken == null) {
return null;
}
return (RefreshTokenModel)SaManager.getSaTokenDao().getObject(splicingRefreshTokenSaveKey(refreshToken));
}
/**
* 获取Refresh-Token Value
* @param clientId 应用id
* @param loginId 账号id
* @return .
*/
public String getRefreshTokenValue(String clientId, Object loginId) {
return SaManager.getSaTokenDao().get(splicingRefreshTokenIndexKey(clientId, loginId));
}
/**
* 获取Client-Token Model
* @param clientToken .
* @return .
*/
public ClientTokenModel getClientToken(String clientToken) {
if(clientToken == null) {
return null;
}
return (ClientTokenModel)SaManager.getSaTokenDao().getObject(splicingClientTokenSaveKey(clientToken));
}
/**
* 获取Client-Token Value
* @param clientId 应用id
* @return .
*/
public String getClientTokenValue(String clientId) {
return SaManager.getSaTokenDao().get(splicingClientTokenIndexKey(clientId));
}
/**
* 获取Past-Token Value
* @param clientId 应用id
* @return .
*/
public String getPastTokenValue(String clientId) {
return SaManager.getSaTokenDao().get(splicingPastTokenIndexKey(clientId));
}
/**
* 获取用户授权记录
* @param clientId 应用id
* @param loginId 账号id
* @return 权限
*/
public List<String> getGrantScope(String clientId, Object loginId) {
String value = SaManager.getSaTokenDao().get(splicingGrantScopeKey(clientId, loginId));
return SaOAuth2Manager.getDataConverter().convertScopeStringToList(value);
}
// ------------------- delete数据
/**
* 删除Code
* @param code
*/
public void deleteCode(String code) {
if(code != null) {
SaManager.getSaTokenDao().deleteObject(splicingCodeSaveKey(code));
}
}
/**
* 删除Code索引
* @param clientId 应用id
* @param loginId 账号id
*/
public void deleteCodeIndex(String clientId, Object loginId) {
SaManager.getSaTokenDao().delete(splicingCodeIndexKey(clientId, loginId));
}
/**
* 删除Access-Token
* @param accessToken
*/
public void deleteAccessToken(String accessToken) {
if(accessToken != null) {
SaManager.getSaTokenDao().deleteObject(splicingAccessTokenSaveKey(accessToken));
}
}
/**
* 删除Access-Token索引
* @param clientId 应用id
* @param loginId 账号id
*/
public void deleteAccessTokenIndex(String clientId, Object loginId) {
SaManager.getSaTokenDao().delete(splicingAccessTokenIndexKey(clientId, loginId));
}
/**
* 删除Refresh-Token
* @param refreshToken
*/
public void deleteRefreshToken(String refreshToken) {
if(refreshToken != null) {
SaManager.getSaTokenDao().deleteObject(splicingRefreshTokenSaveKey(refreshToken));
}
}
/**
* 删除Refresh-Token索引
* @param clientId 应用id
* @param loginId 账号id
*/
public void deleteRefreshTokenIndex(String clientId, Object loginId) {
SaManager.getSaTokenDao().delete(splicingRefreshTokenIndexKey(clientId, loginId));
}
/**
* 删除Client-Token
* @param clientToken
*/
public void deleteClientToken(String clientToken) {
if(clientToken != null) {
SaManager.getSaTokenDao().deleteObject(splicingClientTokenSaveKey(clientToken));
}
}
/**
* 删除Client-Token索引
* @param clientId 应用id
*/
public void deleteClientTokenIndex(String clientId) {
SaManager.getSaTokenDao().delete(splicingClientTokenIndexKey(clientId));
}
/**
* 删除Past-Token索引
* @param clientId 应用id
*/
public void deletePastTokenIndex(String clientId) {
SaManager.getSaTokenDao().delete(splicingPastTokenIndexKey(clientId));
}
/**
* 删除用户授权记录
* @param clientId 应用id
* @param loginId 账号id
*/
public void deleteGrantScope(String clientId, Object loginId) {
SaManager.getSaTokenDao().delete(splicingGrantScopeKey(clientId, loginId));
}
// ------------------- Random数据
/**
* 随机一个 Code
@ -970,90 +696,30 @@ public class SaOAuth2Template {
return SaFoxUtil.getRandomString(60);
}
// ------------------- 拼接key
// ------------------- 包装其它 bean 的方法
/**
* 拼接keyCode持久化
* @param code 授权码
* @return key
* 获取Access-Token Model
* @param accessToken /
* @return /
*/
public String splicingCodeSaveKey(String code) {
return SaManager.getConfig().getTokenName() + ":oauth2:code:" + code;
}
/**
* 拼接keyCode索引
* @param clientId 应用id
* @param loginId 账号id
* @return key
*/
public String splicingCodeIndexKey(String clientId, Object loginId) {
return SaManager.getConfig().getTokenName() + ":oauth2:code-index:" + clientId + ":" + loginId;
}
/**
* 拼接keyAccess-Token持久化
* @param accessToken accessToken
* @return key
*/
public String splicingAccessTokenSaveKey(String accessToken) {
return SaManager.getConfig().getTokenName() + ":oauth2:access-token:" + accessToken;
}
/**
* 拼接keyAccess-Token索引
* @param clientId 应用id
* @param loginId 账号id
* @return key
*/
public String splicingAccessTokenIndexKey(String clientId, Object loginId) {
return SaManager.getConfig().getTokenName() + ":oauth2:access-token-index:" + clientId + ":" + loginId;
}
/**
* 拼接keyRefresh-Token持久化
* @param refreshToken refreshToken
* @return key
*/
public String splicingRefreshTokenSaveKey(String refreshToken) {
return SaManager.getConfig().getTokenName() + ":oauth2:refresh-token:" + refreshToken;
}
/**
* 拼接keyRefresh-Token索引
* @param clientId 应用id
* @param loginId 账号id
* @return key
*/
public String splicingRefreshTokenIndexKey(String clientId, Object loginId) {
return SaManager.getConfig().getTokenName() + ":oauth2:refresh-token-index:" + clientId + ":" + loginId;
}
/**
* 拼接keyClient-Token持久化
* @param clientToken clientToken
* @return key
*/
public String splicingClientTokenSaveKey(String clientToken) {
return SaManager.getConfig().getTokenName() + ":oauth2:client-token:" + clientToken;
}
/**
* 拼接keyClient-Token 索引
* @param clientId clientId
* @return key
*/
public String splicingClientTokenIndexKey(String clientId) {
return SaManager.getConfig().getTokenName() + ":oauth2:client-token-index:" + clientId;
}
/**
* 拼接keyPast-Token 索引
* @param clientId clientId
* @return key
*/
public String splicingPastTokenIndexKey(String clientId) {
return SaManager.getConfig().getTokenName() + ":oauth2:past-token-index:" + clientId;
}
/**
* 拼接key用户授权记录
* @param clientId 应用id
* @param loginId 账号id
* @return key
*/
public String splicingGrantScopeKey(String clientId, Object loginId) {
return SaManager.getConfig().getTokenName() + ":oauth2:grant-scope:" + clientId + ":" + loginId;
public AccessTokenModel getAccessToken(String accessToken) {
return SaOAuth2Manager.getDao().getAccessToken(accessToken);
}
/**
* 持久化用户授权记录
* @param clientId 应用id
* @param loginId 账号id
* @param scopes 权限列表
*/
public void saveGrantScope(String clientId, Object loginId, List<String> scopes) {
SaOAuth2Manager.getDao().saveGrantScope(clientId, loginId, scopes);
}
}

View File

@ -16,6 +16,7 @@
package cn.dev33.satoken.oauth2.template;
import cn.dev33.satoken.context.model.SaRequest;
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
import cn.dev33.satoken.oauth2.data.model.*;
import cn.dev33.satoken.oauth2.processor.SaOAuth2ServerProcessor;
@ -281,7 +282,7 @@ public class SaOAuth2Util {
* @return .
*/
public static CodeModel getCode(String code) {
return SaOAuth2ServerProcessor.instance.oauth2Template.getCode(code);
return SaOAuth2Manager.getDao().getCode(code);
}
/**
@ -290,7 +291,7 @@ public class SaOAuth2Util {
* @return .
*/
public static AccessTokenModel getAccessToken(String accessToken) {
return SaOAuth2ServerProcessor.instance.oauth2Template.getAccessToken(accessToken);
return SaOAuth2Manager.getDao().getAccessToken(accessToken);
}
/**
@ -299,7 +300,7 @@ public class SaOAuth2Util {
* @return .
*/
public static RefreshTokenModel getRefreshToken(String refreshToken) {
return SaOAuth2ServerProcessor.instance.oauth2Template.getRefreshToken(refreshToken);
return SaOAuth2Manager.getDao().getRefreshToken(refreshToken);
}
/**
@ -308,7 +309,7 @@ public class SaOAuth2Util {
* @return .
*/
public static ClientTokenModel getClientToken(String clientToken) {
return SaOAuth2ServerProcessor.instance.oauth2Template.getClientToken(clientToken);
return SaOAuth2Manager.getDao().getClientToken(clientToken);
}
/**
@ -318,7 +319,7 @@ public class SaOAuth2Util {
* @return 权限
*/
public static List<String> getGrantScope(String clientId, Object loginId) {
return SaOAuth2ServerProcessor.instance.oauth2Template.getGrantScope(clientId, loginId);
return SaOAuth2Manager.getDao().getGrantScope(clientId, loginId);
}
}