mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-04-05 17:37:53 +08:00
抽取数据构建器接口
This commit is contained in:
parent
b4c06f2265
commit
2b46d27b87
@ -20,6 +20,8 @@ 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.generate.SaOAuth2DataGenerate;
|
||||
import cn.dev33.satoken.oauth2.data.generate.SaOAuth2DataGenerateDefaultImpl;
|
||||
import cn.dev33.satoken.oauth2.data.loader.SaOAuth2DataLoader;
|
||||
import cn.dev33.satoken.oauth2.data.loader.SaOAuth2DataLoaderDefaultImpl;
|
||||
import cn.dev33.satoken.oauth2.data.resolver.SaOAuth2DataResolver;
|
||||
@ -89,7 +91,7 @@ public class SaOAuth2Manager {
|
||||
}
|
||||
|
||||
/**
|
||||
* OAuth2 数据格式转换器
|
||||
* OAuth2 数据格式转换器 Bean
|
||||
*/
|
||||
private static volatile SaOAuth2DataConverter dataConverter;
|
||||
public static SaOAuth2DataConverter getDataConverter() {
|
||||
@ -106,6 +108,24 @@ public class SaOAuth2Manager {
|
||||
SaOAuth2Manager.dataConverter = dataConverter;
|
||||
}
|
||||
|
||||
/**
|
||||
* OAuth2 数据构建器 Bean
|
||||
*/
|
||||
private static volatile SaOAuth2DataGenerate dataGenerate;
|
||||
public static SaOAuth2DataGenerate getDataGenerate() {
|
||||
if (dataGenerate == null) {
|
||||
synchronized (SaOAuth2Manager.class) {
|
||||
if (dataGenerate == null) {
|
||||
setDataGenerate(new SaOAuth2DataGenerateDefaultImpl());
|
||||
}
|
||||
}
|
||||
}
|
||||
return dataGenerate;
|
||||
}
|
||||
public static void setDataGenerate(SaOAuth2DataGenerate dataGenerate) {
|
||||
SaOAuth2Manager.dataGenerate = dataGenerate;
|
||||
}
|
||||
|
||||
/**
|
||||
* OAuth2 数据持久 Bean
|
||||
*/
|
||||
|
@ -15,6 +15,10 @@
|
||||
*/
|
||||
package cn.dev33.satoken.oauth2.data.convert;
|
||||
|
||||
import cn.dev33.satoken.oauth2.data.model.AccessTokenModel;
|
||||
import cn.dev33.satoken.oauth2.data.model.CodeModel;
|
||||
import cn.dev33.satoken.oauth2.data.model.RefreshTokenModel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -46,4 +50,33 @@ public interface SaOAuth2DataConverter {
|
||||
*/
|
||||
List<String> convertAllowUrlStringToList(String allowUrl);
|
||||
|
||||
|
||||
/**
|
||||
* 将 Code 转换为 Access-Token
|
||||
* @param cm CodeModel对象
|
||||
* @return AccessToken对象
|
||||
*/
|
||||
AccessTokenModel convertCodeToAccessToken(CodeModel cm);
|
||||
|
||||
/**
|
||||
* 将 Access-Token 转换为 Refresh-Token
|
||||
* @param at /
|
||||
* @return /
|
||||
*/
|
||||
RefreshTokenModel convertAccessTokenToRefreshToken(AccessTokenModel at);
|
||||
|
||||
/**
|
||||
* 将 Refresh-Token 转换为 Access-Token
|
||||
* @param rt /
|
||||
* @return /
|
||||
*/
|
||||
AccessTokenModel convertRefreshTokenToAccessToken(RefreshTokenModel rt);
|
||||
|
||||
/**
|
||||
* 根据 Refresh-Token 创建一个新的 Refresh-Token
|
||||
* @param rt /
|
||||
* @return /
|
||||
*/
|
||||
RefreshTokenModel convertRefreshTokenToRefreshToken(RefreshTokenModel rt);
|
||||
|
||||
}
|
||||
|
@ -15,6 +15,11 @@
|
||||
*/
|
||||
package cn.dev33.satoken.oauth2.data.convert;
|
||||
|
||||
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
|
||||
import cn.dev33.satoken.oauth2.data.model.AccessTokenModel;
|
||||
import cn.dev33.satoken.oauth2.data.model.CodeModel;
|
||||
import cn.dev33.satoken.oauth2.data.model.RefreshTokenModel;
|
||||
import cn.dev33.satoken.oauth2.data.model.SaClientModel;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
|
||||
import java.util.Collections;
|
||||
@ -61,5 +66,82 @@ public class SaOAuth2DataConverterDefaultImpl implements SaOAuth2DataConverter {
|
||||
return SaFoxUtil.convertStringToList(allowUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 Code 转换为 Access-Token
|
||||
*/
|
||||
@Override
|
||||
public AccessTokenModel convertCodeToAccessToken(CodeModel cm) {
|
||||
AccessTokenModel at = new AccessTokenModel();
|
||||
at.accessToken = SaOAuth2Manager.getDataLoader().randomAccessToken(cm.clientId, cm.loginId, cm.scopes);
|
||||
// at.refreshToken = randomRefreshToken(cm.clientId, cm.loginId, cm.scope);
|
||||
at.clientId = cm.clientId;
|
||||
at.loginId = cm.loginId;
|
||||
at.scopes = cm.scopes;
|
||||
at.openid = SaOAuth2Manager.getDataLoader().getOpenid(cm.clientId, cm.loginId);
|
||||
SaClientModel clientModel = SaOAuth2Manager.getDataLoader().getClientModelNotNull(cm.clientId);
|
||||
at.expiresTime = System.currentTimeMillis() + (clientModel.getAccessTokenTimeout() * 1000);
|
||||
// at.refreshExpiresTime = System.currentTimeMillis() + (checkClientModel(cm.clientId).getRefreshTokenTimeout() * 1000);
|
||||
return at;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 Access-Token 转换为 Refresh-Token
|
||||
* @param at .
|
||||
* @return .
|
||||
*/
|
||||
@Override
|
||||
public RefreshTokenModel convertAccessTokenToRefreshToken(AccessTokenModel at) {
|
||||
RefreshTokenModel rt = new RefreshTokenModel();
|
||||
rt.refreshToken = SaOAuth2Manager.getDataLoader().randomRefreshToken(at.clientId, at.loginId, at.scopes);
|
||||
rt.clientId = at.clientId;
|
||||
rt.loginId = at.loginId;
|
||||
rt.scopes = at.scopes;
|
||||
rt.openid = at.openid;
|
||||
SaClientModel clientModel = SaOAuth2Manager.getDataLoader().getClientModelNotNull(at.clientId);
|
||||
rt.expiresTime = System.currentTimeMillis() + (clientModel.getRefreshTokenTimeout() * 1000);
|
||||
// 改变at属性
|
||||
at.refreshToken = rt.refreshToken;
|
||||
at.refreshExpiresTime = rt.expiresTime;
|
||||
return rt;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 Refresh-Token 转换为 Access-Token
|
||||
* @param rt .
|
||||
* @return .
|
||||
*/
|
||||
@Override
|
||||
public AccessTokenModel convertRefreshTokenToAccessToken(RefreshTokenModel rt) {
|
||||
AccessTokenModel at = new AccessTokenModel();
|
||||
at.accessToken = SaOAuth2Manager.getDataLoader().randomAccessToken(rt.clientId, rt.loginId, rt.scopes);
|
||||
at.refreshToken = rt.refreshToken;
|
||||
at.clientId = rt.clientId;
|
||||
at.loginId = rt.loginId;
|
||||
at.scopes = rt.scopes;
|
||||
at.openid = rt.openid;
|
||||
SaClientModel clientModel = SaOAuth2Manager.getDataLoader().getClientModelNotNull(rt.clientId);
|
||||
at.expiresTime = System.currentTimeMillis() + (clientModel.getAccessTokenTimeout() * 1000);
|
||||
at.refreshExpiresTime = rt.expiresTime;
|
||||
return at;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 Refresh-Token 创建一个新的 Refresh-Token
|
||||
* @param rt .
|
||||
* @return .
|
||||
*/
|
||||
@Override
|
||||
public RefreshTokenModel convertRefreshTokenToRefreshToken(RefreshTokenModel rt) {
|
||||
RefreshTokenModel newRt = new RefreshTokenModel();
|
||||
newRt.refreshToken = SaOAuth2Manager.getDataLoader().randomRefreshToken(rt.clientId, rt.loginId, rt.scopes);
|
||||
SaClientModel clientModel = SaOAuth2Manager.getDataLoader().getClientModelNotNull(rt.clientId);
|
||||
newRt.expiresTime = System.currentTimeMillis() + (clientModel.getRefreshTokenTimeout() * 1000);
|
||||
newRt.clientId = rt.clientId;
|
||||
newRt.scopes = rt.scopes;
|
||||
newRt.loginId = rt.loginId;
|
||||
newRt.openid = rt.openid;
|
||||
return newRt;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.data.generate;
|
||||
|
||||
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.RequestAuthModel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Sa-Token OAuth2 数据构建器,负责相关 Model 数据构建
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.39.0
|
||||
*/
|
||||
public interface SaOAuth2DataGenerate {
|
||||
|
||||
// ------------------- generate 构建数据
|
||||
|
||||
/**
|
||||
* 构建Model:Code授权码
|
||||
* @param ra 请求参数Model
|
||||
* @return 授权码Model
|
||||
*/
|
||||
public CodeModel generateCode(RequestAuthModel ra);
|
||||
|
||||
/**
|
||||
* 构建Model:Access-Token
|
||||
* @param code 授权码Model
|
||||
* @return AccessToken Model
|
||||
*/
|
||||
public AccessTokenModel generateAccessToken(String code);
|
||||
|
||||
/**
|
||||
* 刷新Model:根据 Refresh-Token 生成一个新的 Access-Token
|
||||
* @param refreshToken Refresh-Token值
|
||||
* @return 新的 Access-Token
|
||||
*/
|
||||
public AccessTokenModel refreshAccessToken(String refreshToken);
|
||||
|
||||
/**
|
||||
* 构建Model:Access-Token (根据RequestAuthModel构建,用于隐藏式 and 密码式)
|
||||
* @param ra 请求参数Model
|
||||
* @param isCreateRt 是否生成对应的Refresh-Token
|
||||
* @return Access-Token Model
|
||||
*/
|
||||
public AccessTokenModel generateAccessToken(RequestAuthModel ra, boolean isCreateRt);
|
||||
|
||||
/**
|
||||
* 构建Model:Client-Token
|
||||
* @param clientId 应用id
|
||||
* @param scopes 授权范围
|
||||
* @return Client-Token Model
|
||||
*/
|
||||
public ClientTokenModel generateClientToken(String clientId, List<String> scopes);
|
||||
|
||||
/**
|
||||
* 构建URL:下放Code URL (Authorization Code 授权码)
|
||||
* @param redirectUri 下放地址
|
||||
* @param code code参数
|
||||
* @param state state参数
|
||||
* @return 构建完毕的URL
|
||||
*/
|
||||
public String buildRedirectUri(String redirectUri, String code, String state);
|
||||
|
||||
/**
|
||||
* 构建URL:下放Access-Token URL (implicit 隐藏式)
|
||||
* @param redirectUri 下放地址
|
||||
* @param token token
|
||||
* @param state state参数
|
||||
* @return 构建完毕的URL
|
||||
*/
|
||||
public String buildImplicitRedirectUri(String redirectUri, String token, String state);
|
||||
|
||||
/**
|
||||
* 回收 Access-Token
|
||||
* @param accessToken Access-Token值
|
||||
*/
|
||||
public void revokeAccessToken(String accessToken);
|
||||
|
||||
}
|
@ -0,0 +1,274 @@
|
||||
/*
|
||||
* 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.data.generate;
|
||||
|
||||
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
|
||||
import cn.dev33.satoken.oauth2.consts.SaOAuth2Consts;
|
||||
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;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Sa-Token OAuth2 数据构建器,默认实现类
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.39.0
|
||||
*/
|
||||
public class SaOAuth2DataGenerateDefaultImpl implements SaOAuth2DataGenerate {
|
||||
// ------------------- generate 构建数据
|
||||
|
||||
/**
|
||||
* 构建Model:Code授权码
|
||||
* @param ra 请求参数Model
|
||||
* @return 授权码Model
|
||||
*/
|
||||
@Override
|
||||
public CodeModel generateCode(RequestAuthModel ra) {
|
||||
|
||||
SaOAuth2Dao dao = SaOAuth2Manager.getDao();
|
||||
|
||||
// 删除旧Code
|
||||
dao.deleteCode(dao.getCodeValue(ra.clientId, ra.loginId));
|
||||
|
||||
// 生成新Code
|
||||
String codeValue = SaOAuth2Manager.getDataLoader().randomCode(ra.clientId, ra.loginId, ra.scopes);
|
||||
CodeModel cm = new CodeModel(codeValue, ra.clientId, ra.scopes, ra.loginId, ra.redirectUri);
|
||||
|
||||
// 保存新Code
|
||||
dao.saveCode(cm);
|
||||
dao.saveCodeIndex(cm);
|
||||
|
||||
// 返回
|
||||
return cm;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建Model:Access-Token
|
||||
* @param code 授权码Model
|
||||
* @return AccessToken Model
|
||||
*/
|
||||
@Override
|
||||
public AccessTokenModel generateAccessToken(String code) {
|
||||
|
||||
SaOAuth2Dao dao = SaOAuth2Manager.getDao();
|
||||
|
||||
// 1、先校验
|
||||
CodeModel cm = dao.getCode(code);
|
||||
SaOAuth2Exception.throwBy(cm == null, "无效code", SaOAuth2ErrorCode.CODE_30110);
|
||||
|
||||
// 2、删除旧Token
|
||||
dao.deleteAccessToken(dao.getAccessTokenValue(cm.clientId, cm.loginId));
|
||||
dao.deleteRefreshToken(dao.getRefreshTokenValue(cm.clientId, cm.loginId));
|
||||
|
||||
// 3、生成token
|
||||
AccessTokenModel at = SaOAuth2Manager.getDataConverter().convertCodeToAccessToken(cm);
|
||||
RefreshTokenModel rt = SaOAuth2Manager.getDataConverter().convertAccessTokenToRefreshToken(at);
|
||||
at.refreshToken = rt.refreshToken;
|
||||
at.refreshExpiresTime = rt.expiresTime;
|
||||
|
||||
// 4、保存token
|
||||
dao.saveAccessToken(at);
|
||||
dao.saveAccessTokenIndex(at);
|
||||
dao.saveRefreshToken(rt);
|
||||
dao.saveRefreshTokenIndex(rt);
|
||||
|
||||
// 5、删除此Code
|
||||
dao.deleteCode(code);
|
||||
dao.deleteCodeIndex(cm.clientId, cm.loginId);
|
||||
|
||||
// 6、返回 Access-Token
|
||||
return at;
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新Model:根据 Refresh-Token 生成一个新的 Access-Token
|
||||
* @param refreshToken Refresh-Token值
|
||||
* @return 新的 Access-Token
|
||||
*/
|
||||
@Override
|
||||
public AccessTokenModel refreshAccessToken(String refreshToken) {
|
||||
|
||||
SaOAuth2Dao dao = SaOAuth2Manager.getDao();
|
||||
|
||||
// 获取 Refresh-Token 信息
|
||||
RefreshTokenModel rt = dao.getRefreshToken(refreshToken);
|
||||
SaOAuth2Exception.throwBy(rt == null, "无效refresh_token: " + refreshToken, SaOAuth2ErrorCode.CODE_30111);
|
||||
|
||||
// 如果配置了[每次刷新产生新的Refresh-Token]
|
||||
SaClientModel clientModel = SaOAuth2Manager.getDataLoader().getClientModelNotNull(rt.clientId);
|
||||
if(clientModel.getIsNewRefresh()) {
|
||||
// 删除旧 Refresh-Token
|
||||
dao.deleteRefreshToken(rt.refreshToken);
|
||||
|
||||
// 创建并保持新的 Refresh-Token
|
||||
rt = SaOAuth2Manager.getDataConverter().convertRefreshTokenToRefreshToken(rt);
|
||||
dao.saveRefreshToken(rt);
|
||||
dao.saveRefreshTokenIndex(rt);
|
||||
}
|
||||
|
||||
// 删除旧 Access-Token
|
||||
dao.deleteAccessToken(dao.getAccessTokenValue(rt.clientId, rt.loginId));
|
||||
|
||||
// 生成新 Access-Token
|
||||
AccessTokenModel at = SaOAuth2Manager.getDataConverter().convertRefreshTokenToAccessToken(rt);
|
||||
|
||||
// 保存新 Access-Token
|
||||
dao.saveAccessToken(at);
|
||||
dao.saveAccessTokenIndex(at);
|
||||
|
||||
// 返回新 Access-Token
|
||||
return at;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建Model:Access-Token (根据RequestAuthModel构建,用于隐藏式 and 密码式)
|
||||
* @param ra 请求参数Model
|
||||
* @param isCreateRt 是否生成对应的Refresh-Token
|
||||
* @return Access-Token Model
|
||||
*/
|
||||
@Override
|
||||
public AccessTokenModel generateAccessToken(RequestAuthModel ra, boolean isCreateRt) {
|
||||
|
||||
SaOAuth2Dao dao = SaOAuth2Manager.getDao();
|
||||
|
||||
// 1、删除 旧Token
|
||||
dao.deleteAccessToken(dao.getAccessTokenValue(ra.clientId, ra.loginId));
|
||||
if(isCreateRt) {
|
||||
dao.deleteRefreshToken(dao.getRefreshTokenValue(ra.clientId, ra.loginId));
|
||||
}
|
||||
|
||||
// 2、生成 新Access-Token
|
||||
String newAtValue = SaOAuth2Manager.getDataLoader().randomAccessToken(ra.clientId, ra.loginId, ra.scopes);
|
||||
AccessTokenModel at = new AccessTokenModel(newAtValue, ra.clientId, ra.loginId, ra.scopes);
|
||||
at.openid = SaOAuth2Manager.getDataLoader().getOpenid(ra.clientId, ra.loginId);
|
||||
SaClientModel clientModel = SaOAuth2Manager.getDataLoader().getClientModelNotNull(ra.clientId);
|
||||
at.expiresTime = System.currentTimeMillis() + (clientModel.getAccessTokenTimeout() * 1000);
|
||||
|
||||
// 3、生成&保存 Refresh-Token
|
||||
if(isCreateRt) {
|
||||
RefreshTokenModel rt = SaOAuth2Manager.getDataConverter().convertAccessTokenToRefreshToken(at);
|
||||
dao.saveRefreshToken(rt);
|
||||
dao.saveRefreshTokenIndex(rt);
|
||||
}
|
||||
|
||||
// 5、保存 新Access-Token
|
||||
dao.saveAccessToken(at);
|
||||
dao.saveAccessTokenIndex(at);
|
||||
|
||||
// 6、返回 新Access-Token
|
||||
return at;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建Model:Client-Token
|
||||
* @param clientId 应用id
|
||||
* @param scopes 授权范围
|
||||
* @return Client-Token Model
|
||||
*/
|
||||
@Override
|
||||
public ClientTokenModel generateClientToken(String clientId, List<String> scopes) {
|
||||
|
||||
SaOAuth2Dao dao = SaOAuth2Manager.getDao();
|
||||
|
||||
// 1、删掉旧 Past-Token
|
||||
dao.deleteClientToken(dao.getPastTokenValue(clientId));
|
||||
|
||||
// 2、将旧Client-Token 标记为新 Past-Token
|
||||
ClientTokenModel oldCt = dao.getClientToken(dao.getClientTokenValue(clientId));
|
||||
dao.savePastTokenIndex(oldCt);
|
||||
|
||||
// 2.5、如果配置了 PastClientToken 的 ttl ,则需要更新一下
|
||||
SaClientModel cm = SaOAuth2Manager.getDataLoader().getClientModelNotNull(clientId);
|
||||
if(oldCt != null && cm.getPastClientTokenTimeout() != -1) {
|
||||
oldCt.expiresTime = System.currentTimeMillis() + (cm.getPastClientTokenTimeout() * 1000);
|
||||
dao.saveClientToken(oldCt);
|
||||
}
|
||||
|
||||
// 3、生成新Client-Token
|
||||
ClientTokenModel ct = new ClientTokenModel(SaOAuth2Manager.getDataLoader().randomClientToken(clientId, scopes), clientId, scopes);
|
||||
ct.expiresTime = System.currentTimeMillis() + (cm.getClientTokenTimeout() * 1000);
|
||||
|
||||
// 3、保存新Client-Token
|
||||
dao.saveClientToken(ct);
|
||||
dao.saveClientTokenIndex(ct);
|
||||
|
||||
// 4、返回
|
||||
return ct;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建URL:下放Code URL (Authorization Code 授权码)
|
||||
* @param redirectUri 下放地址
|
||||
* @param code code参数
|
||||
* @param state state参数
|
||||
* @return 构建完毕的URL
|
||||
*/
|
||||
@Override
|
||||
public String buildRedirectUri(String redirectUri, String code, String state) {
|
||||
String url = SaFoxUtil.joinParam(redirectUri, SaOAuth2Consts.Param.code, code);
|
||||
if( ! SaFoxUtil.isEmpty(state)) {
|
||||
url = SaFoxUtil.joinParam(url, SaOAuth2Consts.Param.state, state);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建URL:下放Access-Token URL (implicit 隐藏式)
|
||||
* @param redirectUri 下放地址
|
||||
* @param token token
|
||||
* @param state state参数
|
||||
* @return 构建完毕的URL
|
||||
*/
|
||||
@Override
|
||||
public String buildImplicitRedirectUri(String redirectUri, String token, String state) {
|
||||
String url = SaFoxUtil.joinSharpParam(redirectUri, SaOAuth2Consts.Param.token, token);
|
||||
if( ! SaFoxUtil.isEmpty(state)) {
|
||||
url = SaFoxUtil.joinSharpParam(url, SaOAuth2Consts.Param.state, state);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 回收 Access-Token
|
||||
* @param accessToken Access-Token值
|
||||
*/
|
||||
@Override
|
||||
public void revokeAccessToken(String accessToken) {
|
||||
|
||||
SaOAuth2Dao dao = SaOAuth2Manager.getDao();
|
||||
|
||||
// 如果查不到任何东西, 直接返回
|
||||
AccessTokenModel at = dao.getAccessToken(accessToken);
|
||||
if(at == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 删除 Access-Token
|
||||
dao.deleteAccessToken(accessToken);
|
||||
dao.deleteAccessTokenIndex(at.clientId, at.loginId);
|
||||
|
||||
// 删除对应的 Refresh-Token
|
||||
String refreshToken = dao.getRefreshTokenValue(at.clientId, at.loginId);
|
||||
dao.deleteRefreshToken(refreshToken);
|
||||
dao.deleteRefreshTokenIndex(at.clientId, at.loginId);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,6 +16,10 @@
|
||||
package cn.dev33.satoken.oauth2.data.loader;
|
||||
|
||||
import cn.dev33.satoken.oauth2.data.model.SaClientModel;
|
||||
import cn.dev33.satoken.oauth2.exception.SaOAuth2Exception;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Sa-Token OAuth2 数据加载器
|
||||
@ -47,5 +51,64 @@ public interface SaOAuth2DataLoader {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据 id 获取 Client 信息,不允许为 null
|
||||
*
|
||||
* @param clientId 应用id
|
||||
* @return ClientModel
|
||||
*/
|
||||
default SaClientModel getClientModelNotNull(String clientId) {
|
||||
SaClientModel clientModel = getClientModel(clientId);
|
||||
if(clientModel == null) {
|
||||
throw new SaOAuth2Exception("未找到对应的 Client 信息");
|
||||
}
|
||||
return clientModel;
|
||||
}
|
||||
|
||||
|
||||
// ------------------- 创建对应 token 的算法
|
||||
|
||||
/**
|
||||
* 随机一个 Code
|
||||
* @param clientId 应用id
|
||||
* @param loginId 账号id
|
||||
* @param scopes 权限
|
||||
* @return Code
|
||||
*/
|
||||
default String randomCode(String clientId, Object loginId, List<String> scopes) {
|
||||
return SaFoxUtil.getRandomString(60);
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机一个 Access-Token
|
||||
* @param clientId 应用id
|
||||
* @param loginId 账号id
|
||||
* @param scopes 权限
|
||||
* @return Access-Token
|
||||
*/
|
||||
default String randomAccessToken(String clientId, Object loginId, List<String> scopes) {
|
||||
return SaFoxUtil.getRandomString(60);
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机一个 Refresh-Token
|
||||
* @param clientId 应用id
|
||||
* @param loginId 账号id
|
||||
* @param scopes 权限
|
||||
* @return Refresh-Token
|
||||
*/
|
||||
default String randomRefreshToken(String clientId, Object loginId, List<String> scopes) {
|
||||
return SaFoxUtil.getRandomString(60);
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机一个 Client-Token
|
||||
* @param clientId 应用id
|
||||
* @param scopes 权限
|
||||
* @return Client-Token
|
||||
*/
|
||||
default String randomClientToken(String clientId, List<String> scopes) {
|
||||
return SaFoxUtil.getRandomString(60);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -74,6 +74,7 @@ public class SaOAuth2DataResolverDefaultImpl implements SaOAuth2DataResolver {
|
||||
/**
|
||||
* 构建返回值: 获取 token
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> buildTokenReturnValue(AccessTokenModel at) {
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
map.put("token_type", TokenType.bearer);
|
||||
|
@ -164,15 +164,15 @@ public class SaOAuth2ServerProcessor {
|
||||
// 6、判断授权类型
|
||||
// 如果是 授权码式,则:开始重定向授权,下放code
|
||||
if(ResponseType.code.equals(ra.responseType)) {
|
||||
CodeModel codeModel = oauth2Template.generateCode(ra);
|
||||
String redirectUri = oauth2Template.buildRedirectUri(ra.redirectUri, codeModel.code, ra.state);
|
||||
CodeModel codeModel = SaOAuth2Manager.getDataGenerate().generateCode(ra);
|
||||
String redirectUri = SaOAuth2Manager.getDataGenerate().buildRedirectUri(ra.redirectUri, codeModel.code, ra.state);
|
||||
return res.redirect(redirectUri);
|
||||
}
|
||||
|
||||
// 如果是 隐藏式,则:开始重定向授权,下放 token
|
||||
if(ResponseType.token.equals(ra.responseType)) {
|
||||
AccessTokenModel at = oauth2Template.generateAccessToken(ra, false);
|
||||
String redirectUri = oauth2Template.buildImplicitRedirectUri(ra.redirectUri, at.accessToken, ra.state);
|
||||
AccessTokenModel at = SaOAuth2Manager.getDataGenerate().generateAccessToken(ra, false);
|
||||
String redirectUri = SaOAuth2Manager.getDataGenerate().buildImplicitRedirectUri(ra.redirectUri, at.accessToken, ra.state);
|
||||
return res.redirect(redirectUri);
|
||||
}
|
||||
|
||||
@ -199,7 +199,7 @@ public class SaOAuth2ServerProcessor {
|
||||
oauth2Template.checkGainTokenParam(code, clientId, clientSecret, redirectUri);
|
||||
|
||||
// 构建 Access-Token
|
||||
AccessTokenModel accessTokenModel = oauth2Template.generateAccessToken(code);
|
||||
AccessTokenModel accessTokenModel = SaOAuth2Manager.getDataGenerate().generateAccessToken(code);
|
||||
|
||||
// 返回
|
||||
return SaOAuth2Manager.getDataResolver().buildTokenReturnValue(accessTokenModel);
|
||||
@ -224,7 +224,7 @@ public class SaOAuth2ServerProcessor {
|
||||
oauth2Template.checkRefreshTokenParam(clientId, clientSecret, refreshToken);
|
||||
|
||||
// 获取新 Access-Token
|
||||
AccessTokenModel accessTokenModel = oauth2Template.refreshAccessToken(refreshToken);
|
||||
AccessTokenModel accessTokenModel = SaOAuth2Manager.getDataGenerate().refreshAccessToken(refreshToken);
|
||||
|
||||
// 返回
|
||||
return SaOAuth2Manager.getDataResolver().buildRefreshTokenReturnValue(accessTokenModel);
|
||||
@ -253,7 +253,7 @@ public class SaOAuth2ServerProcessor {
|
||||
oauth2Template.checkAccessTokenParam(clientId, clientSecret, accessToken);
|
||||
|
||||
// 回收 Access-Token
|
||||
oauth2Template.revokeAccessToken(accessToken);
|
||||
SaOAuth2Manager.getDataGenerate().revokeAccessToken(accessToken);
|
||||
|
||||
// 返回
|
||||
return SaOAuth2Manager.getDataResolver().buildRevokeTokenReturnValue();
|
||||
@ -324,7 +324,7 @@ public class SaOAuth2ServerProcessor {
|
||||
ra.scopes = scopes;
|
||||
|
||||
// 5、生成 Access-Token
|
||||
AccessTokenModel at = oauth2Template.generateAccessToken(ra, true);
|
||||
AccessTokenModel at = SaOAuth2Manager.getDataGenerate().generateAccessToken(ra, true);
|
||||
|
||||
// 6、返回 Access-Token
|
||||
return SaOAuth2Manager.getDataResolver().buildPasswordReturnValue(at);
|
||||
@ -352,7 +352,7 @@ public class SaOAuth2ServerProcessor {
|
||||
oauth2Template.checkClientSecret(clientId, clientSecret);
|
||||
|
||||
// 生成
|
||||
ClientTokenModel ct = oauth2Template.generateClientToken(clientId, scopes);
|
||||
ClientTokenModel ct = SaOAuth2Manager.getDataGenerate().generateClientToken(clientId, scopes);
|
||||
|
||||
// 返回
|
||||
return SaOAuth2Manager.getDataResolver().buildClientTokenReturnValue(ct);
|
||||
|
@ -148,225 +148,6 @@ public class SaOAuth2Template {
|
||||
ra.loginId = loginId;
|
||||
return ra;
|
||||
}
|
||||
/**
|
||||
* 构建Model:Code授权码
|
||||
* @param ra 请求参数Model
|
||||
* @return 授权码Model
|
||||
*/
|
||||
public CodeModel generateCode(RequestAuthModel ra) {
|
||||
|
||||
SaOAuth2Dao dao = SaOAuth2Manager.getDao();
|
||||
|
||||
// 删除旧Code
|
||||
String oldCodeValue = SaOAuth2Manager.getDao().getCodeValue(ra.clientId, ra.loginId);
|
||||
dao.deleteCode(oldCodeValue);
|
||||
|
||||
// 生成新Code
|
||||
String codeValue = randomCode(ra.clientId, ra.loginId, ra.scopes);
|
||||
CodeModel cm = new CodeModel(codeValue, ra.clientId, ra.scopes, ra.loginId, ra.redirectUri);
|
||||
|
||||
// 保存新Code
|
||||
dao.saveCode(cm);
|
||||
dao.saveCodeIndex(cm);
|
||||
|
||||
// 返回
|
||||
return cm;
|
||||
}
|
||||
/**
|
||||
* 构建Model:Access-Token
|
||||
* @param code 授权码Model
|
||||
* @return AccessToken Model
|
||||
*/
|
||||
public AccessTokenModel generateAccessToken(String code) {
|
||||
|
||||
SaOAuth2Dao dao = SaOAuth2Manager.getDao();
|
||||
|
||||
// 1、先校验
|
||||
CodeModel cm = dao.getCode(code);
|
||||
SaOAuth2Exception.throwBy(cm == null, "无效code", SaOAuth2ErrorCode.CODE_30110);
|
||||
|
||||
// 2、删除旧Token
|
||||
dao.deleteAccessToken(dao.getAccessTokenValue(cm.clientId, cm.loginId));
|
||||
dao.deleteRefreshToken(dao.getRefreshTokenValue(cm.clientId, cm.loginId));
|
||||
|
||||
// 3、生成token
|
||||
AccessTokenModel at = convertCodeToAccessToken(cm);
|
||||
RefreshTokenModel rt = convertAccessTokenToRefreshToken(at);
|
||||
at.refreshToken = rt.refreshToken;
|
||||
at.refreshExpiresTime = rt.expiresTime;
|
||||
|
||||
// 4、保存token
|
||||
dao.saveAccessToken(at);
|
||||
dao.saveAccessTokenIndex(at);
|
||||
dao.saveRefreshToken(rt);
|
||||
dao.saveRefreshTokenIndex(rt);
|
||||
|
||||
// 5、删除此Code
|
||||
dao.deleteCode(code);
|
||||
dao.deleteCodeIndex(cm.clientId, cm.loginId);
|
||||
|
||||
// 6、返回 Access-Token
|
||||
return at;
|
||||
}
|
||||
/**
|
||||
* 刷新Model:根据 Refresh-Token 生成一个新的 Access-Token
|
||||
* @param refreshToken Refresh-Token值
|
||||
* @return 新的 Access-Token
|
||||
*/
|
||||
public AccessTokenModel refreshAccessToken(String refreshToken) {
|
||||
|
||||
SaOAuth2Dao dao = SaOAuth2Manager.getDao();
|
||||
|
||||
// 获取 Refresh-Token 信息
|
||||
RefreshTokenModel rt = dao.getRefreshToken(refreshToken);
|
||||
SaOAuth2Exception.throwBy(rt == null, "无效refresh_token: " + refreshToken, SaOAuth2ErrorCode.CODE_30111);
|
||||
|
||||
// 如果配置了[每次刷新产生新的Refresh-Token]
|
||||
if(checkClientModel(rt.clientId).getIsNewRefresh()) {
|
||||
// 删除旧 Refresh-Token
|
||||
dao.deleteRefreshToken(rt.refreshToken);
|
||||
|
||||
// 创建并保持新的 Refresh-Token
|
||||
rt = convertRefreshTokenToRefreshToken(rt);
|
||||
dao.saveRefreshToken(rt);
|
||||
dao.saveRefreshTokenIndex(rt);
|
||||
}
|
||||
|
||||
// 删除旧 Access-Token
|
||||
dao.deleteAccessToken(dao.getAccessTokenValue(rt.clientId, rt.loginId));
|
||||
|
||||
// 生成新 Access-Token
|
||||
AccessTokenModel at = convertRefreshTokenToAccessToken(rt);
|
||||
|
||||
// 保存新 Access-Token
|
||||
dao.saveAccessToken(at);
|
||||
dao.saveAccessTokenIndex(at);
|
||||
|
||||
// 返回新 Access-Token
|
||||
return at;
|
||||
}
|
||||
/**
|
||||
* 构建Model:Access-Token (根据RequestAuthModel构建,用于隐藏式 and 密码式)
|
||||
* @param ra 请求参数Model
|
||||
* @param isCreateRt 是否生成对应的Refresh-Token
|
||||
* @return Access-Token Model
|
||||
*/
|
||||
public AccessTokenModel generateAccessToken(RequestAuthModel ra, boolean isCreateRt) {
|
||||
|
||||
SaOAuth2Dao dao = SaOAuth2Manager.getDao();
|
||||
|
||||
// 1、删除 旧Token
|
||||
dao.deleteAccessToken(dao.getAccessTokenValue(ra.clientId, ra.loginId));
|
||||
if(isCreateRt) {
|
||||
dao.deleteRefreshToken(dao.getRefreshTokenValue(ra.clientId, ra.loginId));
|
||||
}
|
||||
|
||||
// 2、生成 新Access-Token
|
||||
String newAtValue = randomAccessToken(ra.clientId, ra.loginId, ra.scopes);
|
||||
AccessTokenModel at = new AccessTokenModel(newAtValue, ra.clientId, ra.loginId, ra.scopes);
|
||||
at.openid = getOpenid(ra.clientId, ra.loginId);
|
||||
at.expiresTime = System.currentTimeMillis() + (checkClientModel(ra.clientId).getAccessTokenTimeout() * 1000);
|
||||
|
||||
// 3、生成&保存 Refresh-Token
|
||||
if(isCreateRt) {
|
||||
RefreshTokenModel rt = convertAccessTokenToRefreshToken(at);
|
||||
dao.saveRefreshToken(rt);
|
||||
dao.saveRefreshTokenIndex(rt);
|
||||
}
|
||||
|
||||
// 5、保存 新Access-Token
|
||||
dao.saveAccessToken(at);
|
||||
dao.saveAccessTokenIndex(at);
|
||||
|
||||
// 6、返回 新Access-Token
|
||||
return at;
|
||||
}
|
||||
/**
|
||||
* 构建Model:Client-Token
|
||||
* @param clientId 应用id
|
||||
* @param scopes 授权范围
|
||||
* @return Client-Token Model
|
||||
*/
|
||||
public ClientTokenModel generateClientToken(String clientId, List<String> scopes) {
|
||||
|
||||
SaOAuth2Dao dao = SaOAuth2Manager.getDao();
|
||||
|
||||
// 1、删掉旧 Past-Token
|
||||
dao.deleteClientToken(dao.getPastTokenValue(clientId));
|
||||
|
||||
// 2、将旧Client-Token 标记为新 Past-Token
|
||||
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);
|
||||
dao.saveClientToken(oldCt);
|
||||
}
|
||||
|
||||
// 3、生成新Client-Token
|
||||
ClientTokenModel ct = new ClientTokenModel(randomClientToken(clientId, scopes), clientId, scopes);
|
||||
ct.expiresTime = System.currentTimeMillis() + (cm.getClientTokenTimeout() * 1000);
|
||||
|
||||
// 3、保存新Client-Token
|
||||
dao.saveClientToken(ct);
|
||||
dao.saveClientTokenIndex(ct);
|
||||
|
||||
// 4、返回
|
||||
return ct;
|
||||
}
|
||||
/**
|
||||
* 构建URL:下放Code URL (Authorization Code 授权码)
|
||||
* @param redirectUri 下放地址
|
||||
* @param code code参数
|
||||
* @param state state参数
|
||||
* @return 构建完毕的URL
|
||||
*/
|
||||
public String buildRedirectUri(String redirectUri, String code, String state) {
|
||||
String url = SaFoxUtil.joinParam(redirectUri, Param.code, code);
|
||||
if( ! SaFoxUtil.isEmpty(state)) {
|
||||
url = SaFoxUtil.joinParam(url, Param.state, state);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
/**
|
||||
* 构建URL:下放Access-Token URL (implicit 隐藏式)
|
||||
* @param redirectUri 下放地址
|
||||
* @param token token
|
||||
* @param state state参数
|
||||
* @return 构建完毕的URL
|
||||
*/
|
||||
public String buildImplicitRedirectUri(String redirectUri, String token, String state) {
|
||||
String url = SaFoxUtil.joinSharpParam(redirectUri, Param.token, token);
|
||||
if( ! SaFoxUtil.isEmpty(state)) {
|
||||
url = SaFoxUtil.joinSharpParam(url, Param.state, state);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
/**
|
||||
* 回收 Access-Token
|
||||
* @param accessToken Access-Token值
|
||||
*/
|
||||
public void revokeAccessToken(String accessToken) {
|
||||
|
||||
SaOAuth2Dao dao = SaOAuth2Manager.getDao();
|
||||
|
||||
// 如果查不到任何东西, 直接返回
|
||||
AccessTokenModel at = dao.getAccessToken(accessToken);
|
||||
if(at == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 删除 Access-Token
|
||||
dao.deleteAccessToken(accessToken);
|
||||
dao.deleteAccessTokenIndex(at.clientId, at.loginId);
|
||||
|
||||
// 删除对应的 Refresh-Token
|
||||
String refreshToken = dao.getRefreshTokenValue(at.clientId, at.loginId);
|
||||
dao.deleteRefreshToken(refreshToken);
|
||||
dao.deleteRefreshTokenIndex(at.clientId, at.loginId);
|
||||
}
|
||||
|
||||
// ------------------- check 数据校验
|
||||
/**
|
||||
@ -586,115 +367,6 @@ public class SaOAuth2Template {
|
||||
return at;
|
||||
}
|
||||
|
||||
// ------------------- convert 数据转换
|
||||
/**
|
||||
* 将 Code 转换为 Access-Token
|
||||
* @param cm CodeModel对象
|
||||
* @return AccessToken对象
|
||||
*/
|
||||
public AccessTokenModel convertCodeToAccessToken(CodeModel cm) {
|
||||
AccessTokenModel at = new AccessTokenModel();
|
||||
at.accessToken = randomAccessToken(cm.clientId, cm.loginId, cm.scopes);
|
||||
// at.refreshToken = randomRefreshToken(cm.clientId, cm.loginId, cm.scope);
|
||||
at.clientId = cm.clientId;
|
||||
at.loginId = cm.loginId;
|
||||
at.scopes = cm.scopes;
|
||||
at.openid = getOpenid(cm.clientId, cm.loginId);
|
||||
at.expiresTime = System.currentTimeMillis() + (checkClientModel(cm.clientId).getAccessTokenTimeout() * 1000);
|
||||
// at.refreshExpiresTime = System.currentTimeMillis() + (checkClientModel(cm.clientId).getRefreshTokenTimeout() * 1000);
|
||||
return at;
|
||||
}
|
||||
/**
|
||||
* 将 Access-Token 转换为 Refresh-Token
|
||||
* @param at .
|
||||
* @return .
|
||||
*/
|
||||
public RefreshTokenModel convertAccessTokenToRefreshToken(AccessTokenModel at) {
|
||||
RefreshTokenModel rt = new RefreshTokenModel();
|
||||
rt.refreshToken = randomRefreshToken(at.clientId, at.loginId, at.scopes);
|
||||
rt.clientId = at.clientId;
|
||||
rt.loginId = at.loginId;
|
||||
rt.scopes = at.scopes;
|
||||
rt.openid = at.openid;
|
||||
rt.expiresTime = System.currentTimeMillis() + (checkClientModel(at.clientId).getRefreshTokenTimeout() * 1000);
|
||||
// 改变at属性
|
||||
at.refreshToken = rt.refreshToken;
|
||||
at.refreshExpiresTime = rt.expiresTime;
|
||||
return rt;
|
||||
}
|
||||
/**
|
||||
* 将 Refresh-Token 转换为 Access-Token
|
||||
* @param rt .
|
||||
* @return .
|
||||
*/
|
||||
public AccessTokenModel convertRefreshTokenToAccessToken(RefreshTokenModel rt) {
|
||||
AccessTokenModel at = new AccessTokenModel();
|
||||
at.accessToken = randomAccessToken(rt.clientId, rt.loginId, rt.scopes);
|
||||
at.refreshToken = rt.refreshToken;
|
||||
at.clientId = rt.clientId;
|
||||
at.loginId = rt.loginId;
|
||||
at.scopes = rt.scopes;
|
||||
at.openid = rt.openid;
|
||||
at.expiresTime = System.currentTimeMillis() + (checkClientModel(rt.clientId).getAccessTokenTimeout() * 1000);
|
||||
at.refreshExpiresTime = rt.expiresTime;
|
||||
return at;
|
||||
}
|
||||
/**
|
||||
* 根据 Refresh-Token 创建一个新的 Refresh-Token
|
||||
* @param rt .
|
||||
* @return .
|
||||
*/
|
||||
public RefreshTokenModel convertRefreshTokenToRefreshToken(RefreshTokenModel rt) {
|
||||
RefreshTokenModel newRt = new RefreshTokenModel();
|
||||
newRt.refreshToken = randomRefreshToken(rt.clientId, rt.loginId, rt.scopes);
|
||||
newRt.expiresTime = System.currentTimeMillis() + (checkClientModel(rt.clientId).getRefreshTokenTimeout() * 1000);
|
||||
newRt.clientId = rt.clientId;
|
||||
newRt.scopes = rt.scopes;
|
||||
newRt.loginId = rt.loginId;
|
||||
newRt.openid = rt.openid;
|
||||
return newRt;
|
||||
}
|
||||
|
||||
// ------------------- Random数据
|
||||
/**
|
||||
* 随机一个 Code
|
||||
* @param clientId 应用id
|
||||
* @param loginId 账号id
|
||||
* @param scopes 权限
|
||||
* @return Code
|
||||
*/
|
||||
public String randomCode(String clientId, Object loginId, List<String> scopes) {
|
||||
return SaFoxUtil.getRandomString(60);
|
||||
}
|
||||
/**
|
||||
* 随机一个 Access-Token
|
||||
* @param clientId 应用id
|
||||
* @param loginId 账号id
|
||||
* @param scopes 权限
|
||||
* @return Access-Token
|
||||
*/
|
||||
public String randomAccessToken(String clientId, Object loginId, List<String> scopes) {
|
||||
return SaFoxUtil.getRandomString(60);
|
||||
}
|
||||
/**
|
||||
* 随机一个 Refresh-Token
|
||||
* @param clientId 应用id
|
||||
* @param loginId 账号id
|
||||
* @param scopes 权限
|
||||
* @return Refresh-Token
|
||||
*/
|
||||
public String randomRefreshToken(String clientId, Object loginId, List<String> scopes) {
|
||||
return SaFoxUtil.getRandomString(60);
|
||||
}
|
||||
/**
|
||||
* 随机一个 Client-Token
|
||||
* @param clientId 应用id
|
||||
* @param scopes 权限
|
||||
* @return Client-Token
|
||||
*/
|
||||
public String randomClientToken(String clientId, List<String> scopes) {
|
||||
return SaFoxUtil.getRandomString(60);
|
||||
}
|
||||
|
||||
|
||||
// ------------------- 包装其它 bean 的方法
|
||||
|
@ -97,84 +97,7 @@ public class SaOAuth2Util {
|
||||
public static RequestAuthModel generateRequestAuth(SaRequest req, Object loginId) {
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.generateRequestAuth(req, loginId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建Model:Code授权码
|
||||
* @param ra 请求参数Model
|
||||
* @return 授权码Model
|
||||
*/
|
||||
public static CodeModel generateCode(RequestAuthModel ra) {
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.generateCode(ra);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建Model:Access-Token
|
||||
* @param code 授权码Model
|
||||
* @return AccessToken Model
|
||||
*/
|
||||
public static AccessTokenModel generateAccessToken(String code) {
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.generateAccessToken(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新Model:根据 Refresh-Token 生成一个新的 Access-Token
|
||||
* @param refreshToken Refresh-Token值
|
||||
* @return 新的 Access-Token
|
||||
*/
|
||||
public static AccessTokenModel refreshAccessToken(String refreshToken) {
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.refreshAccessToken(refreshToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建Model:Access-Token (根据RequestAuthModel构建,用于隐藏式 and 密码式)
|
||||
* @param ra 请求参数Model
|
||||
* @param isCreateRt 是否生成对应的Refresh-Token
|
||||
* @return Access-Token Model
|
||||
*/
|
||||
public static AccessTokenModel generateAccessToken(RequestAuthModel ra, boolean isCreateRt) {
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.generateAccessToken(ra, isCreateRt);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建Model:Client-Token
|
||||
* @param clientId 应用id
|
||||
* @param scopes 授权范围
|
||||
* @return Client-Token Model
|
||||
*/
|
||||
public static ClientTokenModel generateClientToken(String clientId, List<String> scopes) {
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.generateClientToken(clientId, scopes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建URL:下放Code URL (Authorization Code 授权码)
|
||||
* @param redirectUri 下放地址
|
||||
* @param code code参数
|
||||
* @param state state参数
|
||||
* @return 构建完毕的URL
|
||||
*/
|
||||
public static String buildRedirectUri(String redirectUri, String code, String state) {
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.buildRedirectUri(redirectUri, code, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建URL:下放Access-Token URL (implicit 隐藏式)
|
||||
* @param redirectUri 下放地址
|
||||
* @param token token
|
||||
* @param state state参数
|
||||
* @return 构建完毕的URL
|
||||
*/
|
||||
public static String buildImplicitRedirectUri(String redirectUri, String token, String state) {
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.buildImplicitRedirectUri(redirectUri, token, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* 回收 Access-Token
|
||||
* @param accessToken Access-Token值
|
||||
*/
|
||||
public static void revokeAccessToken(String accessToken) {
|
||||
SaOAuth2ServerProcessor.instance.oauth2Template.revokeAccessToken(accessToken);
|
||||
}
|
||||
|
||||
// ------------------- 数据校验
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user