From 155fa7b2058a21087294e25bfb18ca2360f45436 Mon Sep 17 00:00:00 2001 From: "Michelle.Chung" <1242874891@qq.com> Date: Tue, 30 May 2023 21:51:53 +0800 Subject: [PATCH] =?UTF-8?q?add=20=E6=96=B0=E5=A2=9E=20OAuth2=20=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E4=BE=9D=E8=B5=96=E4=BB=A5=E5=8F=8A=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=20;=20update=20=E6=9B=B4=E6=96=B0=E7=99=BB=E5=BD=95=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3,=20=E8=BF=94=E5=9B=9E=20AccessToken=20(=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E6=8E=A5=E5=8F=A3=E6=AD=A3=E5=B8=B8,=20=E4=BD=86?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E8=8E=B7=E5=8F=96=20LoginUser)=20;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 7 +++ .../web/controller/AuthController.java | 6 +- .../dromara/web/service/IAuthStrategy.java | 2 +- .../web/service/impl/EmailAuthStrategy.java | 2 +- .../service/impl/PasswordAuthStrategy.java | 13 +++- .../web/service/impl/SmsAuthStrategy.java | 2 +- .../web/service/impl/XcxAuthStrategy.java | 2 +- .../common/core/domain/model/AuthBody.java | 40 +++++++++++++ .../common/core/service/AuthService.java | 19 ++++++ ruoyi-common/ruoyi-common-satoken/pom.xml | 6 ++ .../core/service/SaOAuth2TemplateImpl.java | 60 +++++++++++++++++++ .../service/impl/SysAuthServiceImpl.java | 17 +++++- 12 files changed, 168 insertions(+), 8 deletions(-) create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/AuthBody.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/AuthService.java create mode 100644 ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/service/SaOAuth2TemplateImpl.java diff --git a/pom.xml b/pom.xml index b20e7f059..b5ea53896 100644 --- a/pom.xml +++ b/pom.xml @@ -191,6 +191,13 @@ ${satoken.version} + + + cn.dev33 + sa-token-oauth2 + ${satoken.version} + + com.baomidou diff --git a/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java b/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java index 7759e959a..fa01e1430 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java @@ -53,13 +53,17 @@ public class AuthController { @PostMapping("/login/{clientId}/{authType}") public R login(@PathVariable String clientId, @PathVariable String authType, + @RequestParam(required = false) String tenantId, @Validated @RequestBody T loginBody) { + // FIXME 后续不用泛型传参,考虑改为 req 获取 // 校验类型和id loginService.checkAuthType(clientId, authType); + // FIXME 抽取出来,校验租户,前端没改暂时注释 +// loginService.checkTenant(tenantId); // 登录 LoginVo loginVo = new LoginVo(); IAuthStrategy authStrategy = AuthFactory.instance(authType); - String token = authStrategy.login(authStrategy.getLoginBody(loginBody)); + String token = authStrategy.login(clientId, authStrategy.getLoginBody(loginBody)); loginVo.setToken(token); return R.ok(loginVo); } diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/IAuthStrategy.java b/ruoyi-admin/src/main/java/org/dromara/web/service/IAuthStrategy.java index 51352f802..b524d973e 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/service/IAuthStrategy.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/service/IAuthStrategy.java @@ -16,6 +16,6 @@ public interface IAuthStrategy { /** * 登录 */ - String login(T loginBody); + String login(String clientId, T loginBody); } diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/EmailAuthStrategy.java b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/EmailAuthStrategy.java index 704330811..763661566 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/EmailAuthStrategy.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/EmailAuthStrategy.java @@ -46,7 +46,7 @@ public class EmailAuthStrategy implements IAuthStrategy { } @Override - public String login(EmailLoginBody loginBody) { + public String login(String clientId, EmailLoginBody loginBody) { String tenantId = loginBody.getTenantId(); String email = loginBody.getEmail(); String emailCode = loginBody.getEmailCode(); diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/PasswordAuthStrategy.java b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/PasswordAuthStrategy.java index e68f282d9..fc065b01e 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/PasswordAuthStrategy.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/PasswordAuthStrategy.java @@ -1,5 +1,8 @@ package org.dromara.web.service.impl; +import cn.dev33.satoken.oauth2.logic.SaOAuth2Util; +import cn.dev33.satoken.oauth2.model.AccessTokenModel; +import cn.dev33.satoken.oauth2.model.RequestAuthModel; import cn.dev33.satoken.secure.BCrypt; import cn.dev33.satoken.stp.StpUtil; import cn.hutool.core.bean.BeanUtil; @@ -51,7 +54,7 @@ public class PasswordAuthStrategy implements IAuthStrategy { } @Override - public String login(LoginBody loginBody) { + public String login(String clientId, LoginBody loginBody) { String tenantId = loginBody.getTenantId(); String username = loginBody.getUsername(); String password = loginBody.getPassword(); @@ -75,7 +78,13 @@ public class PasswordAuthStrategy implements IAuthStrategy { loginService.recordLogininfor(loginUser.getTenantId(), username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); loginService.recordLoginInfo(user.getUserId()); - return StpUtil.getTokenValue(); + + // FIXME 参考 demo 生成 AccessToken,但是 loginUser 获取不到值,未解决 + RequestAuthModel ra = new RequestAuthModel(); + ra.clientId = clientId; + ra.loginId = StpUtil.getLoginId(); + AccessTokenModel at = SaOAuth2Util.generateAccessToken(ra, true); + return at.accessToken; } /** diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SmsAuthStrategy.java b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SmsAuthStrategy.java index 2c12ac7f4..26b49db18 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SmsAuthStrategy.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SmsAuthStrategy.java @@ -46,7 +46,7 @@ public class SmsAuthStrategy implements IAuthStrategy { } @Override - public String login(SmsLoginBody loginBody) { + public String login(String clientId, SmsLoginBody loginBody) { String tenantId = loginBody.getTenantId(); String phonenumber = loginBody.getPhonenumber(); String smsCode = loginBody.getSmsCode(); diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/XcxAuthStrategy.java b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/XcxAuthStrategy.java index 3e4266abe..7186a293f 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/XcxAuthStrategy.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/XcxAuthStrategy.java @@ -35,7 +35,7 @@ public class XcxAuthStrategy implements IAuthStrategy { } @Override - public String login(XcxLoginBody loginBody) { + public String login(String clientId, XcxLoginBody loginBody) { // xcxCode 为 小程序调用 wx.login 授权后获取 String xcxCode = loginBody.getXcxCode(); // todo 以下自行实现 diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/AuthBody.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/AuthBody.java new file mode 100644 index 000000000..99af0556b --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/AuthBody.java @@ -0,0 +1,40 @@ +package org.dromara.common.core.domain.model; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + + +/** + * 授权管理对象 + * + * @author Michelle.Chung + */ +@Data +public class AuthBody implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 客户端id + */ + private String clientId; + + /** + * 客户端key + */ + private String clientKey; + + /** + * 客户端秘钥 + */ + private String clientSecret; + + /** + * 授权类型 + */ + private String authType; + +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/AuthService.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/AuthService.java new file mode 100644 index 000000000..0526fd85f --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/AuthService.java @@ -0,0 +1,19 @@ +package org.dromara.common.core.service; + +import org.dromara.common.core.domain.model.AuthBody; + +/** + * 通用 认证服务 + * + * @author Michelle.Chung + */ +public interface AuthService { + + /** + * 获取认证授权对象 + * + * @param clientId 客户端id + */ + AuthBody getAuthBody(String clientId); + +} diff --git a/ruoyi-common/ruoyi-common-satoken/pom.xml b/ruoyi-common/ruoyi-common-satoken/pom.xml index 01c282b63..ac2a543a1 100644 --- a/ruoyi-common/ruoyi-common-satoken/pom.xml +++ b/ruoyi-common/ruoyi-common-satoken/pom.xml @@ -36,6 +36,12 @@ sa-token-jwt + + + cn.dev33 + sa-token-oauth2 + + diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/service/SaOAuth2TemplateImpl.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/service/SaOAuth2TemplateImpl.java new file mode 100644 index 000000000..07062f24f --- /dev/null +++ b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/service/SaOAuth2TemplateImpl.java @@ -0,0 +1,60 @@ +package org.dromara.common.satoken.core.service; + +import cn.dev33.satoken.oauth2.logic.SaOAuth2Template; +import cn.dev33.satoken.oauth2.model.SaClientModel; +import cn.dev33.satoken.stp.StpUtil; +import org.dromara.common.core.domain.model.AuthBody; +import org.dromara.common.core.service.AuthService; +import org.dromara.common.core.utils.SpringUtils; +import org.springframework.stereotype.Component; + +/** + * Sa-Token-OAuth2 模块实现类 + * + * @author Michelle.Chung + */ +@Component +public class SaOAuth2TemplateImpl extends SaOAuth2Template { + + /** + * 重写 Access-Token 生成策略:复用登录会话的Token + * + * @param clientId 应用id + * @param loginId 账号id + * @param scope 权限 + */ + @Override + public String randomAccessToken(String clientId, Object loginId, String scope) { + String tokenValue = StpUtil.createLoginSession(loginId); + return tokenValue; + } + + /** + * 根据 id 获取 Client 信息 + * + * @param clientId 应用id + */ + @Override + public SaClientModel getClientModel(String clientId) { + AuthService authService = SpringUtils.getBean(AuthService.class); + AuthBody authBody = authService.getAuthBody(clientId); + return new SaClientModel() + .setClientId(clientId) + .setClientSecret(authBody.getClientSecret()) + .setAllowUrl("*") + .setIsPassword(true); + } + + /** + * 根据ClientId 和 LoginId 获取openid + * + * @param clientId 应用id + * @param loginId 账号id + */ + @Override + public String getOpenid(String clientId, Object loginId) { + // 此为模拟数据,真实环境需要从数据库查询 + return "gr_SwoIN0MC1ewxHX_vfCW3BothWDZMMtx__"; + } + +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysAuthServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysAuthServiceImpl.java index d61b5c22b..f63fffc31 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysAuthServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysAuthServiceImpl.java @@ -1,5 +1,11 @@ package org.dromara.system.service.impl; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ObjectUtil; +import org.dromara.common.core.domain.model.AuthBody; +import org.dromara.common.core.exception.ServiceException; +import org.dromara.common.core.exception.user.AuthTypeErrorException; +import org.dromara.common.core.service.AuthService; import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.mybatis.core.page.TableDataInfo; @@ -27,7 +33,7 @@ import java.util.Collection; */ @RequiredArgsConstructor @Service -public class SysAuthServiceImpl implements ISysAuthService { +public class SysAuthServiceImpl implements ISysAuthService, AuthService { private final SysAuthMapper baseMapper; @@ -111,4 +117,13 @@ public class SysAuthServiceImpl implements ISysAuthService { return baseMapper.deleteBatchIds(ids) > 0; } + @Override + public AuthBody getAuthBody(String clientId) { + SysAuth sysAuth = baseMapper.selectOne( + new LambdaQueryWrapper().eq(SysAuth::getClientId, clientId)); + if (ObjectUtil.isEmpty(sysAuth)) { + throw new ServiceException("clientId 错误"); + } + return BeanUtil.toBean(sysAuth, AuthBody.class); + } }