diff --git a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/generate/SaOAuth2DataGenerateDefaultImpl.java b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/generate/SaOAuth2DataGenerateDefaultImpl.java index 824165d7..42a69243 100644 --- a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/generate/SaOAuth2DataGenerateDefaultImpl.java +++ b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/generate/SaOAuth2DataGenerateDefaultImpl.java @@ -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、删除旧Token,TODO 目测不用删,保存索引的时候如果超出了会自动删 -// 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); diff --git a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/processor/SaOAuth2ServerProcessor.java b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/processor/SaOAuth2ServerProcessor.java index a800e157..8e4e5566 100644 --- a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/processor/SaOAuth2ServerProcessor.java +++ b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/processor/SaOAuth2ServerProcessor.java @@ -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); diff --git a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/strategy/SaOAuth2Strategy.java b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/strategy/SaOAuth2Strategy.java index 75d37816..d6d013d2 100644 --- a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/strategy/SaOAuth2Strategy.java +++ b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/strategy/SaOAuth2Strategy.java @@ -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 userAuthorizeClientCheck = (loginId, clientId) -> { + + }; + }