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 fda31bc0..b90ab968 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 @@ -18,7 +18,7 @@ import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.util.SaResult; /** - * Sa-Token-OAuth2 请求处理类封装 + * Sa-Token-OAuth2 请求处理类封装 * @author kong * */ @@ -26,195 +26,195 @@ public class SaOAuth2Handle { /** * 处理Server端请求, 路由分发 - * @return 处理结果 + * @return 处理结果 */ public static Object serverRequest() { - - // 获取变量 + + // 获取变量 SaRequest req = SaHolder.getRequest(); SaResponse res = SaHolder.getResponse(); SaOAuth2Config cfg = SaOAuth2Manager.getConfig(); - - // ------------------ 路由分发 ------------------ - + + // ------------------ 路由分发 ------------------ + // 模式一:Code授权码 if(req.isPath(Api.authorize) && req.isParam(Param.response_type, ResponseType.code) && cfg.isCode) { return authorize(req, res, cfg); } - // Code授权码 获取 Access-Token + // Code授权码 获取 Access-Token if(req.isPath(Api.token) && req.isParam(Param.grant_type, GrantType.authorization_code)) { return token(req, res, cfg); } - - // Refresh-Token 刷新 Access-Token + + // Refresh-Token 刷新 Access-Token if(req.isPath(Api.refresh) && req.isParam(Param.grant_type, GrantType.refresh_token)) { return refreshToken(req); } - // 回收 Access-Token + // 回收 Access-Token if(req.isPath(Api.revoke)) { return revokeToken(req); } - - // doLogin 登录接口 + + // doLogin 登录接口 if(req.isPath(Api.doLogin)) { return doLogin(req, res, cfg); } - - // doConfirm 确认授权接口 + + // doConfirm 确认授权接口 if(req.isPath(Api.doConfirm)) { return doConfirm(req); } - - // 模式二:隐藏式 + + // 模式二:隐藏式 if(req.isPath(Api.authorize) && req.isParam(Param.response_type, ResponseType.token) && cfg.isImplicit) { return authorize(req, res, cfg); } - - // 模式三:密码式 + + // 模式三:密码式 if(req.isPath(Api.token) && req.isParam(Param.grant_type, GrantType.password) && cfg.isPassword) { return password(req, res, cfg); } - // 模式四:凭证式 + // 模式四:凭证式 if(req.isPath(Api.client_token) && req.isParam(Param.grant_type, GrantType.client_credentials) && cfg.isClient) { return clientToken(req, res, cfg); } - - // 默认返回 + + // 默认返回 return SaOAuth2Consts.NOT_HANDLE; } - - /** - * 模式一:Code授权码 / 模式二:隐藏式 - * @param req 请求对象 - * @param res 响应对象 - * @param cfg 配置对象 - * @return 处理结果 - */ - public static Object authorize(SaRequest req, SaResponse res, SaOAuth2Config cfg) { - // 1、如果尚未登录, 则先去登录 + /** + * 模式一:Code授权码 / 模式二:隐藏式 + * @param req 请求对象 + * @param res 响应对象 + * @param cfg 配置对象 + * @return 处理结果 + */ + public static Object authorize(SaRequest req, SaResponse res, SaOAuth2Config cfg) { + + // 1、如果尚未登录, 则先去登录 if(StpUtil.isLogin() == false) { return cfg.notLoginView.get(); } - // 2、构建请求Model + // 2、构建请求Model RequestAuthModel ra = SaOAuth2Util.generateRequestAuth(req, StpUtil.getLoginId()); - // 3、校验:重定向域名是否合法 + // 3、校验:重定向域名是否合法 SaOAuth2Util.checkRightUrl(ra.clientId, ra.redirectUri); - // 4、校验:此次申请的Scope,该Client是否已经签约 + // 4、校验:此次申请的Scope,该Client是否已经签约 SaOAuth2Util.checkContract(ra.clientId, ra.scope); - // 5、判断:如果此次申请的Scope,该用户尚未授权,则转到授权页面 + // 5、判断:如果此次申请的Scope,该用户尚未授权,则转到授权页面 boolean isGrant = SaOAuth2Util.isGrant(ra.loginId, ra.clientId, ra.scope); if(isGrant == false) { return cfg.confirmView.apply(ra.clientId, ra.scope); } - - // 6、判断授权类型 - // 如果是 授权码式,则:开始重定向授权,下放code + + // 6、判断授权类型 + // 如果是 授权码式,则:开始重定向授权,下放code if(ResponseType.code.equals(ra.responseType)) { - CodeModel codeModel = SaOAuth2Util.generateCode(ra); + CodeModel codeModel = SaOAuth2Util.generateCode(ra); String redirectUri = SaOAuth2Util.buildRedirectUri(ra.redirectUri, codeModel.code, ra.state); - return res.redirect(redirectUri); + return res.redirect(redirectUri); } - // 如果是 隐藏式,则:开始重定向授权,下放 token + // 如果是 隐藏式,则:开始重定向授权,下放 token if(ResponseType.token.equals(ra.responseType)) { - AccessTokenModel at = SaOAuth2Util.generateAccessToken(ra, false); + AccessTokenModel at = SaOAuth2Util.generateAccessToken(ra, false); String redirectUri = SaOAuth2Util.buildImplicitRedirectUri(ra.redirectUri, at.accessToken, ra.state); - return res.redirect(redirectUri); + return res.redirect(redirectUri); } - - // 默认返回 - throw new SaOAuth2Exception("无效response_type: " + ra.responseType); + + // 默认返回 + throw new SaOAuth2Exception("无效response_type: " + ra.responseType); } - + /** - * Code授权码 获取 Access-Token - * @param req 请求对象 - * @param res 响应对象 - * @param cfg 配置对象 - * @return 处理结果 + * Code授权码 获取 Access-Token + * @param req 请求对象 + * @param res 响应对象 + * @param cfg 配置对象 + * @return 处理结果 */ public static Object token(SaRequest req, SaResponse res, SaOAuth2Config cfg) { - // 获取参数 - String code = req.getParamNotNull(Param.code); - String clientId = req.getParamNotNull(Param.client_id); + // 获取参数 + String code = req.getParamNotNull(Param.code); + String clientId = req.getParamNotNull(Param.client_id); String clientSecret = req.getParamNotNull(Param.client_secret); - String redirectUri = req.getParam(Param.redirect_uri); + String redirectUri = req.getParam(Param.redirect_uri); // 校验参数 SaOAuth2Util.checkGainTokenParam(code, clientId, clientSecret, redirectUri); - // 构建 Access-Token + // 构建 Access-Token AccessTokenModel token = SaOAuth2Util.generateAccessToken(code); - - // 返回 - return SaResult.data(token.toLineMap()); + + // 返回 + return SaResult.data(token.toLineMap()); } /** - * Refresh-Token 刷新 Access-Token - * @param req 请求对象 - * @return 处理结果 + * Refresh-Token 刷新 Access-Token + * @param req 请求对象 + * @return 处理结果 */ public static Object refreshToken(SaRequest req) { - // 获取参数 + // 获取参数 String clientId = req.getParamNotNull(Param.client_id); String clientSecret = req.getParamNotNull(Param.client_secret); String refreshToken = req.getParamNotNull(Param.refresh_token); - - // 校验参数 + + // 校验参数 SaOAuth2Util.checkRefreshTokenParam(clientId, clientSecret, refreshToken); - // 获取新Token返回 + // 获取新Token返回 Object data = SaOAuth2Util.refreshAccessToken(refreshToken).toLineMap(); - return SaResult.data(data); + return SaResult.data(data); } /** - * 回收 Access-Token - * @param req 请求对象 - * @return 处理结果 + * 回收 Access-Token + * @param req 请求对象 + * @return 处理结果 */ public static Object revokeToken(SaRequest req) { - // 获取参数 + // 获取参数 String clientId = req.getParamNotNull(Param.client_id); String clientSecret = req.getParamNotNull(Param.client_secret); String accessToken = req.getParamNotNull(Param.access_token); - + // 如果 Access-Token 不存在,直接返回 if(SaOAuth2Util.getAccessToken(accessToken) == null) { return SaResult.ok("access_token不存在:" + accessToken); } - - // 校验参数 + + // 校验参数 SaOAuth2Util.checkAccessTokenParam(clientId, clientSecret, accessToken); - // 获取新Token返回 + // 获取新Token返回 SaOAuth2Util.revokeAccessToken(accessToken); - return SaResult.ok(); + return SaResult.ok(); } - + /** - * doLogin 登录接口 - * @param req 请求对象 - * @param res 响应对象 - * @param cfg 配置对象 - * @return 处理结果 + * doLogin 登录接口 + * @param req 请求对象 + * @param res 响应对象 + * @param cfg 配置对象 + * @return 处理结果 */ public static Object doLogin(SaRequest req, SaResponse res, SaOAuth2Config cfg) { return cfg.doLoginHandle.apply(req.getParamNotNull(Param.name), req.getParamNotNull("pwd")); } /** - * doConfirm 确认授权接口 - * @param req 请求对象 - * @return 处理结果 + * doConfirm 确认授权接口 + * @param req 请求对象 + * @return 处理结果 */ public static Object doConfirm(SaRequest req) { String clientId = req.getParamNotNull(Param.client_id); @@ -223,68 +223,71 @@ public class SaOAuth2Handle { SaOAuth2Util.saveGrantScope(clientId, loginId, scope); return SaResult.ok(); } - + /** - * 模式三:密码式 - * @param req 请求对象 - * @param res 响应对象 - * @param cfg 配置对象 - * @return 处理结果 + * 模式三:密码式 + * @param req 请求对象 + * @param res 响应对象 + * @param cfg 配置对象 + * @return 处理结果 */ public static Object password(SaRequest req, SaResponse res, SaOAuth2Config cfg) { - - // 1、获取请求参数 + + // 1、获取请求参数 String username = req.getParamNotNull(Param.username); String password = req.getParamNotNull(Param.password); String clientId = req.getParamNotNull(Param.client_id); - + // 2、校验client_id SaOAuth2Util.checkClientModel(clientId); - // 3、防止因前端误传token造成逻辑干扰 + // 3、防止因前端误传token造成逻辑干扰 SaHolder.getStorage().set(StpUtil.stpLogic.splicingKeyJustCreatedSave(), "no-token"); - + // 4、调用API 开始登录,如果没能成功登录,则直接退出 - Object retObj = cfg.doLoginHandle.apply(username, password); + Object retObj = cfg.doLoginHandle.apply(username, password); if(StpUtil.isLogin() == false) { return retObj; } - - // 5、构建 ra对象 + + // 5、构建 ra对象 RequestAuthModel ra = new RequestAuthModel(); ra.clientId = clientId; - ra.loginId = StpUtil.getLoginId(); - ra.scope = req.getParam(Param.scope, ""); - - // 6、生成 Access-Token - AccessTokenModel at = SaOAuth2Util.generateAccessToken(ra, true); - - // 7、返回 Access-Token + ra.loginId = StpUtil.getLoginId(); + ra.scope = req.getParam(Param.scope, ""); + + // 6、生成 Access-Token + AccessTokenModel at = SaOAuth2Util.generateAccessToken(ra, true); + + // 7、返回 Access-Token return SaResult.data(at.toLineMap()); } /** - * 模式四:凭证式 - * @param req 请求对象 - * @param res 响应对象 - * @param cfg 配置对象 - * @return 处理结果 + * 模式四:凭证式 + * @param req 请求对象 + * @param res 响应对象 + * @param cfg 配置对象 + * @return 处理结果 */ public static Object clientToken(SaRequest req, SaResponse res, SaOAuth2Config cfg) { - - // 获取参数 + + // 获取参数 String clientId = req.getParamNotNull(Param.client_id); String clientSecret = req.getParamNotNull(Param.client_secret); String scope = req.getParam(Param.scope); - + + //校验 ClientScope + SaOAuth2Util.checkContract(clientId, scope); + // 校验 ClientSecret SaOAuth2Util.checkClientSecret(clientId, clientSecret); - + // 返回 Client-Token ClientTokenModel ct = SaOAuth2Util.generateClientToken(clientId, scope); - + // 返回 Client-Token - return SaResult.data(ct.toLineMap()); + return SaResult.data(ct.toLineMap()); } - + }