From caa163ed6bb04bcb07089a900c2b2dd5fd59ff12 Mon Sep 17 00:00:00 2001 From: haoran <18755438303@163.com> Date: Mon, 14 Apr 2025 14:54:29 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E9=87=87=E7=94=A8=E5=AE=A2?= =?UTF-8?q?=E6=88=B7=E7=AB=AF=E6=8E=88=E6=9D=83=E6=A8=A1=E5=BC=8F=20=20?= =?UTF-8?q?=E7=9B=B8=E5=85=B3yudao=E4=BB=A3=E7=A0=81=E6=9B=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/finance/FinanceController.java | 3 +- .../admin/oauth2/OAuth2OpenController.java | 2 + .../oauth2/GXSKOAuth2GrantServiceImpl.java | 109 ++++++++++++++++++ .../src/main/resources/application.yaml | 1 + 4 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/GXSKOAuth2GrantServiceImpl.java diff --git a/sk-module-data/sk-module-data-biz/src/main/java/org/sk/module/data/controller/finance/FinanceController.java b/sk-module-data/sk-module-data-biz/src/main/java/org/sk/module/data/controller/finance/FinanceController.java index 07cbef63a..621d1d22e 100644 --- a/sk-module-data/sk-module-data-biz/src/main/java/org/sk/module/data/controller/finance/FinanceController.java +++ b/sk-module-data/sk-module-data-biz/src/main/java/org/sk/module/data/controller/finance/FinanceController.java @@ -10,6 +10,7 @@ import org.sk.module.data.dal.param.finance.IncomeAndTaxParam; import org.sk.module.data.dal.vo.FinanceVO; import org.sk.module.data.service.finance.FinanceService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -47,7 +48,7 @@ public class FinanceController { * @param param * @return */ - @PermitAll +// @PermitAll @GetMapping("/getIncomeAndTax") public CommonResult> getIncomeAndTax(@Valid @RequestBody IncomeAndTaxParam param) { return CommonResult.success(financeService.getIncomeAndTax(param)); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2OpenController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2OpenController.java index 0b6675c0f..11100f98f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2OpenController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2OpenController.java @@ -26,6 +26,7 @@ import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.Operation; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -61,6 +62,7 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti @Slf4j public class OAuth2OpenController { + @Qualifier("GXSKOAuth2GrantServiceImpl") @Resource private OAuth2GrantService oauth2GrantService; @Resource diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/GXSKOAuth2GrantServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/GXSKOAuth2GrantServiceImpl.java new file mode 100644 index 000000000..bcb4af7fd --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/GXSKOAuth2GrantServiceImpl.java @@ -0,0 +1,109 @@ +package cn.iocoder.yudao.module.system.service.oauth2; + +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; +import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2CodeDO; +import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; +import cn.iocoder.yudao.module.system.enums.ErrorCodeConstants; +import cn.iocoder.yudao.module.system.service.auth.AdminAuthService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; + +/** + * OAuth2 授予 Service 实现类 + * + * @author 芋道源码 + */ +@Service +public class GXSKOAuth2GrantServiceImpl implements OAuth2GrantService { + + @Resource + private OAuth2TokenService oauth2TokenService; + @Resource + private OAuth2CodeService oauth2CodeService; + @Resource + private AdminAuthService adminAuthService; + + @Override + public OAuth2AccessTokenDO grantImplicit(Long userId, Integer userType, + String clientId, List scopes) { + return oauth2TokenService.createAccessToken(userId, userType, clientId, scopes); + } + + @Override + public String grantAuthorizationCodeForCode(Long userId, Integer userType, + String clientId, List scopes, + String redirectUri, String state) { + return oauth2CodeService.createAuthorizationCode(userId, userType, clientId, scopes, + redirectUri, state).getCode(); + } + + @Override + public OAuth2AccessTokenDO grantAuthorizationCodeForAccessToken(String clientId, String code, + String redirectUri, String state) { + OAuth2CodeDO codeDO = oauth2CodeService.consumeAuthorizationCode(code); + Assert.notNull(codeDO, "授权码不能为空"); // 防御性编程 + // 校验 clientId 是否匹配 + if (!StrUtil.equals(clientId, codeDO.getClientId())) { + throw exception(ErrorCodeConstants.OAUTH2_GRANT_CLIENT_ID_MISMATCH); + } + // 校验 redirectUri 是否匹配 + if (!StrUtil.equals(redirectUri, codeDO.getRedirectUri())) { + throw exception(ErrorCodeConstants.OAUTH2_GRANT_REDIRECT_URI_MISMATCH); + } + // 校验 state 是否匹配 + state = StrUtil.nullToDefault(state, ""); // 数据库 state 为 null 时,会设置为 "" 空串 + if (!StrUtil.equals(state, codeDO.getState())) { + throw exception(ErrorCodeConstants.OAUTH2_GRANT_STATE_MISMATCH); + } + + // 创建访问令牌 + return oauth2TokenService.createAccessToken(codeDO.getUserId(), codeDO.getUserType(), + codeDO.getClientId(), codeDO.getScopes()); + } + + @Override + public OAuth2AccessTokenDO grantPassword(String username, String password, String clientId, List scopes) { + // 使用账号 + 密码进行登录 + AdminUserDO user = adminAuthService.authenticate(username, password); + Assert.notNull(user, "用户不能为空!"); // 防御性编程 + + // 创建访问令牌 + return oauth2TokenService.createAccessToken(user.getId(), UserTypeEnum.ADMIN.getValue(), clientId, scopes); + } + + @Override + public OAuth2AccessTokenDO grantRefreshToken(String refreshToken, String clientId) { + return oauth2TokenService.refreshAccessToken(refreshToken, clientId); + } + + @Override + public OAuth2AccessTokenDO grantClientCredentials(String clientId, List scopes) { + // TODO 芋艿:项目中使用 OAuth2 解决的是三方应用的授权,内部的 SSO 等问题,所以暂时不考虑 client_credentials 这个场景 +// throw new UnsupportedOperationException("暂时不支持 client_credentials 授权模式"); + + // 创建访问令牌 + return oauth2TokenService.createAccessToken(IdUtil.getSnowflakeNextId(), UserTypeEnum.MEMBER.getValue(), + clientId, scopes); + } + + @Override + public boolean revokeToken(String clientId, String accessToken) { + // 先查询,保证 clientId 时匹配的 + OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.getAccessToken(accessToken); + if (accessTokenDO == null || ObjectUtil.notEqual(clientId, accessTokenDO.getClientId())) { + return false; + } + // 再删除 + return oauth2TokenService.removeAccessToken(accessToken) != null; + } + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/application.yaml b/yudao-module-system/yudao-module-system-biz/src/main/resources/application.yaml index 061dfe04a..7e37fe956 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/application.yaml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/application.yaml @@ -165,6 +165,7 @@ yudao: tenant: # 多租户相关配置项 enable: true ignore-urls: + - /admin-api/system/oauth2/token # - /admin-api/system/tenant/get-id-by-name # 基于名字获取租户,不许带租户编号 - /admin-api/system/tenant/get-by-website # 基于域名获取租户,不许带租户编号 - /admin-api/system/captcha/get-image # 获取图片验证码,和租户无关