feat(oauth2): 新增 SaOAuth2Strategy.instance.userAuthorizeClientCheck 策略,用于检查指定用户是否可以授权指定应用

This commit is contained in:
click33 2025-05-13 03:59:35 +08:00
parent f1089f697c
commit 0ed0c277df
3 changed files with 27 additions and 10 deletions

View File

@ -88,9 +88,8 @@ public class SaOAuth2DataGenerateDefaultImpl implements SaOAuth2DataGenerate {
CodeModel cm = dao.getCode(code);
SaOAuth2AuthorizationCodeException.throwBy(cm == null, "无效 code: " + code, code, SaOAuth2ErrorCode.CODE_30110);
// 2删除旧TokenTODO 目测不用删保存索引的时候如果超出了会自动删
// dao.deleteAccessToken(dao.getAccessTokenList(cm.clientId, cm.loginId));
// dao.deleteRefreshToken(dao.getRefreshTokenValue(cm.clientId, cm.loginId));
// 2开发者自定义的授权前置检查
SaOAuth2Strategy.instance.userAuthorizeClientCheck.run(cm.loginId, cm.clientId);
// 3生成token
AccessTokenModel at = dataConverter.convertCodeToAccessToken(cm);
@ -128,7 +127,10 @@ public class SaOAuth2DataGenerateDefaultImpl implements SaOAuth2DataGenerate {
RefreshTokenModel rt = dao.getRefreshToken(refreshToken);
SaOAuth2RefreshTokenException.throwBy(rt == null, "无效 refresh_token: " + refreshToken, refreshToken, SaOAuth2ErrorCode.CODE_30111);
// 如果配置了[每次刷新产生新的Refresh-Token]
// 开发者自定义的授权前置检查
SaOAuth2Strategy.instance.userAuthorizeClientCheck.run(rt.loginId, rt.clientId);
// 如果配置了 [每次刷新产生新的Refresh-Token]
SaClientModel clientModel = SaOAuth2Manager.getDataLoader().getClientModelNotNull(rt.clientId);
if(clientModel.getIsNewRefresh()) {
// 删除旧 Refresh-Token
@ -174,6 +176,9 @@ public class SaOAuth2DataGenerateDefaultImpl implements SaOAuth2DataGenerate {
// dao.deleteRefreshToken(dao.getRefreshTokenValue(ra.clientId, ra.loginId));
// }
// 1开发者自定义的授权前置检查
SaOAuth2Strategy.instance.userAuthorizeClientCheck.run(ra.loginId, ra.clientId);
// 2生成 新Access-Token
String newAtValue = SaOAuth2Strategy.instance.createAccessToken.execute(ra.clientId, ra.loginId, ra.scopes);
AccessTokenModel at = new AccessTokenModel(newAtValue, ra.clientId, ra.loginId, ra.scopes);

View File

@ -122,20 +122,24 @@ public class SaOAuth2ServerProcessor {
checkAuthorizeResponseType(responseType, req, cfg);
// 2如果尚未登录, 则先去登录
if( ! SaOAuth2Manager.getStpLogic().isLogin()) {
Object loginId = SaOAuth2Manager.getStpLogic().getLoginIdDefaultNull();
if( loginId == null) {
return SaOAuth2Strategy.instance.notLoginView.get();
}
// 3构建请求 Model
RequestAuthModel ra = SaOAuth2Manager.getDataResolver().readRequestAuthModel(req, SaOAuth2Manager.getStpLogic().getLoginId());
RequestAuthModel ra = SaOAuth2Manager.getDataResolver().readRequestAuthModel(req, loginId);
// 4校验重定向域名是否合法
// 4开发者自定义的授权前置检查
SaOAuth2Strategy.instance.userAuthorizeClientCheck.run(ra.loginId, ra.clientId);
// 5校验重定向域名是否合法
oauth2Template.checkRedirectUri(ra.clientId, ra.redirectUri);
// 5校验此次申请的Scope该Client是否已经签约
// 6校验此次申请的Scope该Client是否已经签约
oauth2Template.checkContractScope(ra.clientId, ra.scopes);
// 6判断如果此次申请的Scope该用户尚未授权则转到授权页面
// 7判断如果此次申请的Scope该用户尚未授权则转到授权页面
boolean isNeedCarefulConfirm = oauth2Template.isNeedCarefulConfirm(ra.loginId, ra.clientId, ra.scopes);
if(isNeedCarefulConfirm) {
SaClientModel cm = oauth2Template.checkClientModel(ra.clientId);
@ -144,7 +148,7 @@ public class SaOAuth2ServerProcessor {
}
}
// 7判断授权类型重定向到不同地址
// 8判断授权类型重定向到不同地址
// 如果是 授权码式开始重定向授权下放code
if(ResponseType.code.equals(ra.responseType)) {
CodeModel codeModel = dataGenerate.generateCode(ra);

View File

@ -16,6 +16,7 @@
package cn.dev33.satoken.oauth2.strategy;
import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.fun.SaTwoParamFunction;
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
import cn.dev33.satoken.oauth2.config.SaOAuth2ServerConfig;
import cn.dev33.satoken.oauth2.consts.GrantType;
@ -260,6 +261,13 @@ public final class SaOAuth2Strategy {
*/
public SaOAuth2DoLoginHandleFunction doLoginHandle = (name, pwd) -> SaResult.error();
/**
* OAuth-Server端用户在授权指定 client 前的检查如果检查不通过请直接抛出异常
*/
public SaTwoParamFunction<Object, String> userAuthorizeClientCheck = (loginId, clientId) -> {
};
}