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/SysLoginService.java | 87 +++++++++++++++++++++++++++++++++---------- 1 files changed, 66 insertions(+), 21 deletions(-) diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java b/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java index a269d38..5966195 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java @@ -4,17 +4,23 @@ import cn.dev33.satoken.stp.StpUtil; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.lang.Opt; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import com.baomidou.lock.annotation.Lock4j; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import me.zhyd.oauth.model.AuthUser; +import org.dromara.common.core.constant.CacheConstants; import org.dromara.common.core.constant.Constants; -import org.dromara.common.core.constant.GlobalConstants; +import org.dromara.common.core.constant.SystemConstants; import org.dromara.common.core.constant.TenantConstants; +import org.dromara.common.core.domain.dto.PostDTO; import org.dromara.common.core.domain.dto.RoleDTO; import org.dromara.common.core.domain.model.LoginUser; import org.dromara.common.core.enums.LoginType; -import org.dromara.common.core.enums.TenantStatus; +import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.exception.user.UserException; import org.dromara.common.core.utils.*; import org.dromara.common.log.event.LogininforEvent; @@ -26,7 +32,6 @@ import org.dromara.system.domain.SysUser; import org.dromara.system.domain.bo.SysSocialBo; import org.dromara.system.domain.vo.*; -import org.dromara.system.mapper.SysDeptMapper; import org.dromara.system.mapper.SysUserMapper; import org.dromara.system.service.*; import org.springframework.beans.factory.annotation.Value; @@ -47,6 +52,12 @@ @Service public class SysLoginService { + @Value("${justauth.type.keycloak.server-url}") + private String keycloakServerUrl; + + @Value("${justauth.type.keycloak.realm}") + private String keycloakRealm; + @Value("${user.password.maxRetryCount}") private Integer maxRetryCount; @@ -57,7 +68,8 @@ private final ISysPermissionService permissionService; private final ISysSocialService sysSocialService; private final ISysRoleService roleService; - private final SysDeptMapper deptMapper; + private final ISysDeptService deptService; + private final ISysPostService postService; private final SysUserMapper userMapper; @@ -65,20 +77,28 @@ * 缁戝畾绗笁鏂圭敤鎴� * * @param authUserData 鎺堟潈鍝嶅簲瀹炰綋 - * @return 缁熶竴鍝嶅簲瀹炰綋 */ + @Lock4j public void socialRegister(AuthUser authUserData) { String authId = authUserData.getSource() + authUserData.getUuid(); // 绗笁鏂圭敤鎴蜂俊鎭� SysSocialBo bo = BeanUtil.toBean(authUserData, SysSocialBo.class); BeanUtil.copyProperties(authUserData.getToken(), bo); - bo.setUserId(LoginHelper.getUserId()); + Long userId = LoginHelper.getUserId(); + bo.setUserId(userId); bo.setAuthId(authId); bo.setOpenId(authUserData.getUuid()); bo.setUserName(authUserData.getUsername()); bo.setNickName(authUserData.getNickname()); + List<SysSocialVo> checkList = sysSocialService.selectByAuthId(authId); + if (CollUtil.isNotEmpty(checkList)) { + throw new ServiceException("姝や笁鏂硅处鍙峰凡缁忚缁戝畾!"); + } // 鏌ヨ鏄惁宸茬粡缁戝畾鐢ㄦ埛 - List<SysSocialVo> list = sysSocialService.selectByAuthId(authId); + SysSocialBo params = new SysSocialBo(); + params.setUserId(userId); + params.setSource(bo.getSource()); + List<SysSocialVo> list = sysSocialService.queryList(params); if (CollUtil.isEmpty(list)) { // 娌℃湁缁戝畾鐢ㄦ埛, 鏂板鐢ㄦ埛淇℃伅 sysSocialService.insertByBo(bo); @@ -86,6 +106,8 @@ // 鏇存柊鐢ㄦ埛淇℃伅 bo.setId(list.get(0).getId()); sysSocialService.updateByBo(bo); + // 濡傛灉瑕佺粦瀹氱殑骞冲彴璐﹀彿宸茬粡琚粦瀹氳繃浜� 鏄惁鎶涘紓甯歌嚜琛屽喅鏂� + // throw new ServiceException("姝ゅ钩鍙拌处鍙峰凡缁忚缁戝畾!"); } } @@ -104,6 +126,26 @@ TenantHelper.clearDynamic(); } recordLogininfor(loginUser.getTenantId(), loginUser.getUsername(), Constants.LOGOUT, MessageUtils.message("user.logout.success")); + // 鏂板Keycloak鐧诲嚭閫昏緫 + + Long userId = loginUser.getUserId(); + + SysSocialVo social = sysSocialService.selectByUserId(userId); + if (social == null) { + return; + } + + String logoutUrl = keycloakServerUrl + "/realms/" + keycloakRealm + "/protocol/openid-connect/logout"; + HttpRequest request = HttpRequest.get(logoutUrl) + .form("refresh_token", social.getRefreshToken()) + .form("id_token_hint", social.getIdToken()); + + + HttpResponse response = request.execute(); + if (response.isOk()) { + System.out.println("1234"); + } + } catch (NotLoginException ignored) { } finally { try { @@ -131,26 +173,29 @@ SpringUtils.context().publishEvent(logininforEvent); } - /** * 鏋勫缓鐧诲綍鐢ㄦ埛 */ public LoginUser buildLoginUser(SysUserVo user) { LoginUser loginUser = new LoginUser(); + Long userId = user.getUserId(); loginUser.setTenantId(user.getTenantId()); - loginUser.setUserId(user.getUserId()); + loginUser.setUserId(userId); loginUser.setDeptId(user.getDeptId()); loginUser.setUsername(user.getUserName()); loginUser.setNickname(user.getNickName()); loginUser.setUserType(user.getUserType()); - loginUser.setMenuPermission(permissionService.getMenuPermission(user.getUserId())); - loginUser.setRolePermission(permissionService.getRolePermission(user.getUserId())); - SysDeptVo dept = deptMapper.selectVoById(user.getDeptId()); - loginUser.setDeptName(ObjectUtil.isNull(dept) ? "" : dept.getDeptName()); - List<SysRoleVo> roles = DataPermissionHelper.ignore(() -> { - return roleService.selectRolesByUserId(user.getUserId()); - }); + loginUser.setMenuPermission(permissionService.getMenuPermission(userId)); + loginUser.setRolePermission(permissionService.getRolePermission(userId)); + if (ObjectUtil.isNotNull(user.getDeptId())) { + Opt<SysDeptVo> deptOpt = Opt.of(user.getDeptId()).map(deptService::selectDeptById); + loginUser.setDeptName(deptOpt.map(SysDeptVo::getDeptName).orElse(StringUtils.EMPTY)); + loginUser.setDeptCategory(deptOpt.map(SysDeptVo::getDeptCategory).orElse(StringUtils.EMPTY)); + } + List<SysRoleVo> roles = roleService.selectRolesByUserId(userId); + List<SysPostVo> posts = postService.selectPostsByUserId(userId); loginUser.setRoles(BeanUtil.copyToList(roles, RoleDTO.class)); + loginUser.setPosts(BeanUtil.copyToList(posts, PostDTO.class)); return loginUser; } @@ -172,7 +217,7 @@ * 鐧诲綍鏍¢獙 */ public void checkLogin(LoginType loginType, String tenantId, String username, Supplier<Boolean> supplier) { - String errorKey = GlobalConstants.PWD_ERR_CNT_KEY + username; + String errorKey = CacheConstants.PWD_ERR_CNT_KEY + username; String loginFail = Constants.LOGIN_FAIL; // 鑾峰彇鐢ㄦ埛鐧诲綍閿欒娆℃暟锛岄粯璁や负0 (鍙嚜瀹氫箟闄愬埗绛栫暐 渚嬪: key + username + ip) @@ -211,17 +256,17 @@ if (!TenantHelper.isEnable()) { return; } - if (TenantConstants.DEFAULT_TENANT_ID.equals(tenantId)) { - return; - } if (StringUtils.isBlank(tenantId)) { throw new TenantException("tenant.number.not.blank"); + } + if (TenantConstants.DEFAULT_TENANT_ID.equals(tenantId)) { + return; } SysTenantVo tenant = tenantService.queryByTenantId(tenantId); if (ObjectUtil.isNull(tenant)) { log.info("鐧诲綍绉熸埛锛歿} 涓嶅瓨鍦�.", tenantId); throw new TenantException("tenant.not.exists"); - } else if (TenantStatus.DISABLE.getCode().equals(tenant.getStatus())) { + } else if (SystemConstants.DISABLE.equals(tenant.getStatus())) { log.info("鐧诲綍绉熸埛锛歿} 宸茶鍋滅敤.", tenantId); throw new TenantException("tenant.blocked"); } else if (ObjectUtil.isNotNull(tenant.getExpireTime()) -- Gitblit v1.9.3