From 18e919bde3d925ee76fe29c7a6621c2716b1e4e4 Mon Sep 17 00:00:00 2001 From: baoshiwei <baoshiwei@shlanbao.cn> Date: 星期五, 21 三月 2025 09:43:31 +0800 Subject: [PATCH] feat(social): 添加 Keycloak社交登录支持 --- ruoyi-admin/src/main/java/org/dromara/web/service/impl/SocialAuthStrategy.java | 145 ++++++++++++++++++++++++++++++++++-------------- 1 files changed, 103 insertions(+), 42 deletions(-) diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SocialAuthStrategy.java b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SocialAuthStrategy.java index 85c0bbb..9d62dd8 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SocialAuthStrategy.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SocialAuthStrategy.java @@ -2,31 +2,35 @@ import cn.dev33.satoken.stp.SaLoginModel; import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpUtil; import cn.hutool.http.Method; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import me.zhyd.oauth.model.AuthResponse; +import me.zhyd.oauth.model.AuthToken; import me.zhyd.oauth.model.AuthUser; -import org.dromara.common.core.constant.Constants; +import org.dromara.common.core.constant.SystemConstants; import org.dromara.common.core.domain.model.LoginUser; +import org.dromara.common.core.domain.model.PasswordLoginBody; import org.dromara.common.core.domain.model.SocialLoginBody; -import org.dromara.common.core.enums.UserStatus; import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.exception.user.UserException; -import org.dromara.common.core.utils.MessageUtils; +import org.dromara.common.core.utils.StreamUtils; import org.dromara.common.core.utils.ValidatorUtils; import org.dromara.common.json.utils.JsonUtils; import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.social.config.properties.SocialProperties; +import org.dromara.common.social.keycloak.AuthKeycloakRequest; import org.dromara.common.social.utils.SocialUtils; import org.dromara.common.tenant.helper.TenantHelper; -import org.dromara.system.domain.SysClient; +import org.dromara.system.domain.SysSocial; import org.dromara.system.domain.SysUser; +import org.dromara.system.domain.bo.SysSocialBo; +import org.dromara.system.domain.bo.SysUserBo; +import org.dromara.system.domain.vo.SysClientVo; import org.dromara.system.domain.vo.SysSocialVo; import org.dromara.system.domain.vo.SysUserVo; import org.dromara.system.mapper.SysUserMapper; @@ -35,6 +39,9 @@ import org.dromara.web.service.IAuthStrategy; import org.dromara.web.service.SysLoginService; import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; /** * 绗笁鏂规巿鏉冪瓥鐣� @@ -54,21 +61,39 @@ /** * 鐧诲綍-绗笁鏂规巿鏉冪櫥褰� * - * @param clientId 瀹㈡埛绔痠d * @param body 鐧诲綍淇℃伅 * @param client 瀹㈡埛绔俊鎭� */ @Override - public LoginVo login(String clientId, String body, SysClient client) { - SocialLoginBody loginBody = JsonUtils.parseObject(body, SocialLoginBody.class); - ValidatorUtils.validate(loginBody); - AuthResponse<AuthUser> response = SocialUtils.loginAuth( + public LoginVo login(String body, SysClientVo client) { + // 濡傛灉bodyp瀛楃涓蹭腑鍖呭惈login_type瀛楁锛屽垯灏哹ody杞负password鐧诲綍 + AuthUser authUserData = null; + String tenantId = null; + if (body.contains("login_type")) { + PasswordLoginBody passwordLoginBody = JsonUtils.parseObject(body, PasswordLoginBody.class); + tenantId = passwordLoginBody.getTenantId(); + ValidatorUtils.validate(passwordLoginBody); + AuthKeycloakRequest authRequest = SocialUtils.getAuthKeyloakRequest("keycloak", socialProperties); + AuthToken accessToken = authRequest.getAccessToken(passwordLoginBody); + authUserData = authRequest.getUserInfo(accessToken); + + + } else { + SocialLoginBody loginBody = JsonUtils.parseObject(body, SocialLoginBody.class); + tenantId =loginBody.getTenantId(); + ValidatorUtils.validate(loginBody); + AuthResponse<AuthUser> response = SocialUtils.loginAuth( loginBody.getSource(), loginBody.getSocialCode(), loginBody.getSocialState(), socialProperties); - if (!response.ok()) { - throw new ServiceException(response.getMsg()); + if (!response.ok()) { + throw new ServiceException(response.getMsg()); + } + authUserData = response.getData(); } - AuthUser authUserData = response.getData(); + + + + if ("GITEE".equals(authUserData.getSource())) { // 濡傜敤鎴蜂娇鐢� gitee 鐧诲綍椤烘墜 star 缁欎綔鑰呬竴鐐规敮鎸� 鎷掔粷鐧藉珫 HttpUtil.createRequest(Method.PUT, "https://gitee.com/api/v5/user/starred/dromara/RuoYi-Vue-Plus") @@ -78,23 +103,68 @@ .formStr(MapUtil.of("access_token", authUserData.getToken().getAccessToken())) .executeAsync(); } + if ("KEYCLOAK".equals(authUserData.getSource())) { + // 鏂板KEYCLOAK鐢ㄦ埛鑷姩鍒涘缓閫昏緫 + String authId = authUserData.getSource() + authUserData.getUuid(); + List<SysSocialVo> list = sysSocialService.selectByAuthId(authId); + if (CollUtil.isEmpty(list)) { + // 鑷姩鍒涘缓鏂扮敤鎴� + SysUser newUser = new SysUser(); + newUser.setUserName(authUserData.getUsername()); + newUser.setEmail(authUserData.getEmail()); + newUser.setNickName(authUserData.getNickname()); + newUser.setPassword("Initial123@"); // 鍒濆瀵嗙爜闇�绗﹀悎瀹夊叏绛栫暐 + newUser.setStatus(SystemConstants.NORMAL); - SysSocialVo social = sysSocialService.selectByAuthId(authUserData.getSource() + authUserData.getUuid()); - if (!ObjectUtil.isNotNull(social)) { + userMapper.insert(newUser); // 鍋囪瀛樺湪鎻掑叆鏂规硶 + + // 鍒涘缓绀句氦缁戝畾璁板綍 + SysSocialBo newSocial = new SysSocialBo(); + newSocial.setUserId(newUser.getUserId()); + newSocial.setUserName(newUser.getUserName()); + newSocial.setAuthId(authId); + newSocial.setSource(authUserData.getSource()); + newSocial.setTenantId(newUser.getTenantId()); + newSocial.setOpenId(authUserData.getUuid()); + newSocial.setAccessToken(authUserData.getToken().getAccessToken()); + newSocial.setRefreshToken(authUserData.getToken().getRefreshToken()); + newSocial.setIdToken(authUserData.getToken().getIdToken()); + sysSocialService.insertByBo(newSocial); // 闇�纭繚鏈嶅姟鏈夋柊澧炴柟娉� + + // 閲嶆柊鏌ヨ纭繚鏁版嵁鍙敤 + list = sysSocialService.selectByAuthId(authId); + } else { + // 鏇存柊绀句氦缁戝畾璁板綍 + SysSocialBo socialBo = new SysSocialBo(); + socialBo.setId(list.get(0).getId()); + socialBo.setAccessToken(authUserData.getToken().getAccessToken()); + socialBo.setRefreshToken(authUserData.getToken().getRefreshToken()); + socialBo.setIdToken(authUserData.getToken().getIdToken()); + sysSocialService.updateByBo(socialBo); + + } + } + + List<SysSocialVo> list = sysSocialService.selectByAuthId(authUserData.getSource() + authUserData.getUuid()); + if (CollUtil.isEmpty(list)) { throw new ServiceException("浣犺繕娌℃湁缁戝畾绗笁鏂硅处鍙凤紝缁戝畾鍚庢墠鍙互鐧诲綍锛�"); } - // 楠岃瘉鎺堟潈琛ㄩ噷闈㈢殑绉熸埛id鏄惁鍖呭惈褰撳墠绉熸埛id - String tenantId = social.getTenantId(); - if (ObjectUtil.isNotNull(social) && StrUtil.isNotBlank(tenantId) - && !tenantId.contains(loginBody.getTenantId())) { - throw new ServiceException("瀵逛笉璧凤紝浣犳病鏈夋潈闄愮櫥褰曞綋鍓嶇鎴凤紒"); + SysSocialVo social; + if (TenantHelper.isEnable()) { + String finalTenantId = tenantId; + Optional<SysSocialVo> opt = StreamUtils.findAny(list, x -> x.getTenantId().equals(finalTenantId)); + if (opt.isEmpty()) { + throw new ServiceException("瀵逛笉璧凤紝浣犳病鏈夋潈闄愮櫥褰曞綋鍓嶇鎴凤紒"); + } + social = opt.get(); + } else { + social = list.get(0); } - - // 鏌ユ壘鐢ㄦ埛 - SysUserVo user = loadUser(tenantId, social.getUserId()); - - // 姝ゅ鍙牴鎹櫥褰曠敤鎴风殑鏁版嵁涓嶅悓 鑷鍒涘缓 loginUser 灞炴�т笉澶熺敤缁ф壙鎵╁睍灏辫浜� - LoginUser loginUser = loginService.buildLoginUser(user); + LoginUser loginUser = TenantHelper.dynamic(social.getTenantId(), () -> { + SysUserVo user = loadUser(social.getUserId()); + // 姝ゅ鍙牴鎹櫥褰曠敤鎴风殑鏁版嵁涓嶅悓 鑷鍒涘缓 loginUser 灞炴�т笉澶熺敤缁ф壙鎵╁睍灏辫浜� + return loginService.buildLoginUser(user); + }); loginUser.setClientKey(client.getClientKey()); loginUser.setDeviceType(client.getDeviceType()); SaLoginModel model = new SaLoginModel(); @@ -103,36 +173,27 @@ // 渚嬪: 鍚庡彴鐢ㄦ埛30鍒嗛挓杩囨湡 app鐢ㄦ埛1澶╄繃鏈� model.setTimeout(client.getTimeout()); model.setActiveTimeout(client.getActiveTimeout()); - model.setExtra(LoginHelper.CLIENT_KEY, clientId); + model.setExtra(LoginHelper.CLIENT_KEY, client.getClientId()); // 鐢熸垚token LoginHelper.login(loginUser, model); - - loginService.recordLogininfor(loginUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); - loginService.recordLoginInfo(user.getUserId()); LoginVo loginVo = new LoginVo(); loginVo.setAccessToken(StpUtil.getTokenValue()); loginVo.setExpireIn(StpUtil.getTokenTimeout()); - loginVo.setClientId(clientId); + loginVo.setClientId(client.getClientId()); return loginVo; } - private SysUserVo loadUser(String tenantId, Long userId) { - SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>() - .select(SysUser::getUserName, SysUser::getStatus) - .eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId) - .eq(SysUser::getUserId, userId)); + private SysUserVo loadUser(Long userId) { + SysUserVo user = userMapper.selectVoById(userId); if (ObjectUtil.isNull(user)) { log.info("鐧诲綍鐢ㄦ埛锛歿} 涓嶅瓨鍦�.", ""); throw new UserException("user.not.exists", ""); - } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { + } else if (SystemConstants.DISABLE.equals(user.getStatus())) { log.info("鐧诲綍鐢ㄦ埛锛歿} 宸茶鍋滅敤.", ""); throw new UserException("user.blocked", ""); } - if (TenantHelper.isEnable()) { - return userMapper.selectTenantUserByUserName(user.getUserName(), tenantId); - } - return userMapper.selectUserByUserName(user.getUserName()); + return user; } } -- Gitblit v1.9.3