diff --git a/kicc-common/kicc-common-data/src/main/java/com/cloud/kicc/common/data/handler/KiccTenantLineHandler.java b/kicc-common/kicc-common-data/src/main/java/com/cloud/kicc/common/data/handler/KiccTenantLineHandler.java
index e2d52a0e..27705db3 100644
--- a/kicc-common/kicc-common-data/src/main/java/com/cloud/kicc/common/data/handler/KiccTenantLineHandler.java
+++ b/kicc-common/kicc-common-data/src/main/java/com/cloud/kicc/common/data/handler/KiccTenantLineHandler.java
@@ -1,12 +1,10 @@
package com.cloud.kicc.common.data.handler;
import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.cloud.kicc.common.data.entity.KiccUser;
import com.cloud.kicc.common.data.override.TenantLikeExpression;
import com.cloud.kicc.common.data.properties.TenantProperties;
-import com.cloud.kicc.common.data.util.TenantContextHolder;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.schema.Column;
import org.springframework.security.core.Authentication;
@@ -59,7 +57,21 @@ public class KiccTenantLineHandler implements TenantLineHandler {
@Override
public Expression getTenantId() {
// 返回当前用户所属的多租户ID进行条件拼接
- return StrUtil.isNotBlank(TenantContextHolder.getTenant()) ? new TenantLikeExpression(TenantContextHolder.getTenant()): null;
+ return ObjectUtil.isNotEmpty(getUser()) ? new TenantLikeExpression(getUser().getTenantId()): null;
+ }
+
+ /**
+ * 获取用户
+ */
+ protected KiccUser getUser() {
+ Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ if (Optional.ofNullable(authentication).isPresent()) {
+ Object principal = authentication.getPrincipal();
+ if (principal instanceof KiccUser) {
+ return (KiccUser) principal;
+ }
+ }
+ return null;
}
}
diff --git a/kicc-common/kicc-common-data/src/main/java/com/cloud/kicc/common/data/util/TenantContextHolder.java b/kicc-common/kicc-common-data/src/main/java/com/cloud/kicc/common/data/util/TenantContextHolder.java
deleted file mode 100644
index 72ad129b..00000000
--- a/kicc-common/kicc-common-data/src/main/java/com/cloud/kicc/common/data/util/TenantContextHolder.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package com.cloud.kicc.common.data.util;
-
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
-import com.cloud.kicc.common.data.entity.KiccUser;
-import com.cloud.kicc.common.data.override.TenantLikeExpression;
-import lombok.experimental.UtilityClass;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-
-import java.util.Optional;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- *
- * 动态设置多租户
- *
- *
- * @Author: entfrm开发团队-王翔
- * @Date: 2022/5/13
- */
-@UtilityClass
-public class TenantContextHolder {
-
- private final ThreadLocal contextHolder = new ThreadLocal();
-
- public void setTenant(String tenantIds) {
- contextHolder.set(tenantIds);
- }
-
- public String getTenant() {
- String tenantIds = ObjectUtil.isNotEmpty(getUser()) ? getUser().getTenantId() : clearTenant();
- return StrUtil.isNotBlank(contextHolder.get()) ? contextHolder.get() : tenantIds;
- }
-
- /**
- * 校验用户多租户是否为空,为空说明当前用户未登录,需要清除当前线程多租户数据
- * 不收的销毁,会出现 ThreadLocal 内存泄漏的问题
- */
- public String clearTenant() {
- contextHolder.remove();
- return null;
- }
-
- /**
- * 获取用户
- * 如果当前不存在用户,正常情况多租户拼接查询会报错
- */
- private KiccUser getUser() {
- Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
- if (Optional.ofNullable(authentication).isPresent()) {
- Object principal = authentication.getPrincipal();
- if (principal instanceof KiccUser) {
- return (KiccUser) principal;
- }
- }
- return null;
- }
-
-}
diff --git a/kicc-common/kicc-common-security/src/main/java/com/cloud/kicc/common/security/exp/KiccLocalResourceServerTokenServices.java b/kicc-common/kicc-common-security/src/main/java/com/cloud/kicc/common/security/exp/KiccLocalResourceServerTokenServices.java
index b44c54a0..2647436e 100644
--- a/kicc-common/kicc-common-security/src/main/java/com/cloud/kicc/common/security/exp/KiccLocalResourceServerTokenServices.java
+++ b/kicc-common/kicc-common-security/src/main/java/com/cloud/kicc/common/security/exp/KiccLocalResourceServerTokenServices.java
@@ -45,33 +45,14 @@ public class KiccLocalResourceServerTokenServices implements ResourceServerToken
}
OAuth2Request oAuth2Request = oAuth2Authentication.getOAuth2Request();
+ // 检测是否是属于认证的KiccUser实体用户
if (!(oAuth2Authentication.getPrincipal() instanceof KiccUser)) {
return oAuth2Authentication;
}
- String clientId = oAuth2Request.getClientId();
-
- // 根据客户端授权类型加载身份验证,考虑多种登录方式,比如手机登录,用户密码登录
- Map userDetailsServiceMap = SpringUtil.getBeansOfType(KiccUserDetailsService.class);
- Optional optional = userDetailsServiceMap.values().stream()
- .filter(service -> service.support(clientId, oAuth2Request.getGrantType()))
- .max(Comparator.comparingInt(Ordered::getOrder));
-
- if (!optional.isPresent()) {
- throw new InternalAuthenticationServiceException("UserDetailsService error , not register");
- }
-
- // 根据 username 查询 spring cache 最新的值 并返回
KiccUser kiccUser = (KiccUser) oAuth2Authentication.getPrincipal();
-
- UserDetails userDetails;
- try {
- userDetails = optional.get().loadUserByUser(kiccUser);
- } catch (UsernameNotFoundException notFoundException) {
- throw new UnauthorizedException(String.format("%s username not found", kiccUser.getUsername()), notFoundException);
- }
- // 加载用户名密码身份验证令牌
- Authentication userAuthentication = new UsernamePasswordAuthenticationToken(userDetails, "N/A", userDetails.getAuthorities());
+ // 每次请求前都预先加载用户名密码身份验证令牌
+ Authentication userAuthentication = new UsernamePasswordAuthenticationToken(kiccUser, "N/A", kiccUser.getAuthorities());
OAuth2Authentication authentication = new OAuth2Authentication(oAuth2Request, userAuthentication);
authentication.setAuthenticated(true);
return authentication;
diff --git a/kicc-platform/kicc-platform-biz/kicc-system-biz/src/main/java/com/cloud/kicc/system/controller/UserController.java b/kicc-platform/kicc-platform-biz/kicc-system-biz/src/main/java/com/cloud/kicc/system/controller/UserController.java
index 163b4333..86be2127 100644
--- a/kicc-platform/kicc-platform-biz/kicc-system-biz/src/main/java/com/cloud/kicc/system/controller/UserController.java
+++ b/kicc-platform/kicc-platform-biz/kicc-system-biz/src/main/java/com/cloud/kicc/system/controller/UserController.java
@@ -9,7 +9,6 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cloud.kicc.common.core.api.R;
import com.cloud.kicc.common.core.constant.AppConstants;
import com.cloud.kicc.common.data.entity.KiccUser;
-import com.cloud.kicc.common.data.util.TenantContextHolder;
import com.cloud.kicc.common.log.annotation.SysLog;
import com.cloud.kicc.common.security.annotation.Inner;
import com.cloud.kicc.common.security.util.SecurityUtils;
@@ -24,6 +23,7 @@ import com.cloud.kicc.system.service.UserService;
import com.pig4cloud.plugin.excel.annotation.ResponseExcel;
import com.pig4cloud.plugin.excel.annotation.Sheet;
import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@@ -206,12 +206,12 @@ public class UserController {
return userService.list();
}
-
+ @SneakyThrows
@SysLog("用户多租户更改")
@GetMapping("/changeTenant/{tenantIds:[\\w,]+}")
@PreAuthorize("@pms.hasPermission('user_edit')")
public R changeTenant(@PathVariable String[] tenantIds) {
- TenantContextHolder.setTenant(StrUtil.join(",", tenantIds));
+ userService.setCurrentUserTenant(tenantIds);
return R.ok();
}
@@ -219,7 +219,8 @@ public class UserController {
@GetMapping("/resetTenant")
@PreAuthorize("@pms.hasPermission('user_edit')")
public R resetTenant() {
- TenantContextHolder.setTenant(SecurityUtils.getUser().getTenantId());
+ User user = userService.getOne(Wrappers.query().lambda().eq(User::getId, SecurityUtils.getUser().getId()));
+ userService.setCurrentUserTenant(user.getTenantId());
return R.ok();
}
diff --git a/kicc-platform/kicc-platform-biz/kicc-system-biz/src/main/java/com/cloud/kicc/system/service/UserService.java b/kicc-platform/kicc-platform-biz/kicc-system-biz/src/main/java/com/cloud/kicc/system/service/UserService.java
index 7384c524..b10980ca 100644
--- a/kicc-platform/kicc-platform-biz/kicc-system-biz/src/main/java/com/cloud/kicc/system/service/UserService.java
+++ b/kicc-platform/kicc-platform-biz/kicc-system-biz/src/main/java/com/cloud/kicc/system/service/UserService.java
@@ -37,4 +37,11 @@ public interface UserService extends IService {
*/
User getUserAuthority(User user);
+ /**
+ * 设置当前用户多租户信息
+ * @param tenantIds 多租户ids
+ * @return void
+ */
+ void setCurrentUserTenant(String... tenantIds);
+
}
diff --git a/kicc-platform/kicc-platform-biz/kicc-system-biz/src/main/java/com/cloud/kicc/system/service/impl/UserServiceImpl.java b/kicc-platform/kicc-platform-biz/kicc-system-biz/src/main/java/com/cloud/kicc/system/service/impl/UserServiceImpl.java
index 65d7e4b1..18c15673 100644
--- a/kicc-platform/kicc-platform-biz/kicc-system-biz/src/main/java/com/cloud/kicc/system/service/impl/UserServiceImpl.java
+++ b/kicc-platform/kicc-platform-biz/kicc-system-biz/src/main/java/com/cloud/kicc/system/service/impl/UserServiceImpl.java
@@ -8,6 +8,8 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloud.kicc.common.core.constant.SecurityConstants;
import com.cloud.kicc.common.core.exception.CheckedException;
import com.cloud.kicc.common.core.exception.CommonException;
+import com.cloud.kicc.common.data.entity.KiccUser;
+import com.cloud.kicc.common.security.util.SecurityUtils;
import com.cloud.kicc.system.api.entity.Dept;
import com.cloud.kicc.system.api.entity.Role;
import com.cloud.kicc.system.api.entity.User;
@@ -16,8 +18,15 @@ import com.cloud.kicc.system.mapper.UserMapper;
import com.cloud.kicc.system.service.*;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.oauth2.common.OAuth2AccessToken;
+import org.springframework.security.oauth2.provider.OAuth2Authentication;
+import org.springframework.security.oauth2.provider.OAuth2Request;
+import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -44,6 +53,7 @@ public class UserServiceImpl extends ServiceImpl implements Us
private final RoleService roleService;
private final MenuService menuService;
private final TenantService tenantService;
+ private final TokenStore tokenStore;
private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();
@Override
@@ -101,6 +111,38 @@ public class UserServiceImpl extends ServiceImpl implements Us
return user;
}
+
+ @Override
+ public void setCurrentUserTenant(String... tenantIds) {
+ Authentication currentAuthentication = SecurityContextHolder.getContext().getAuthentication();
+ if (currentAuthentication == null) {
+ new CommonException("当前用户未登录,请登录后重试!");
+ }
+ OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) currentAuthentication;
+ OAuth2AccessToken accessToken = tokenStore.getAccessToken(oAuth2Authentication);
+ OAuth2Request oAuth2Request = oAuth2Authentication.getOAuth2Request();
+ KiccUser currentKiccUser = SecurityUtils.getUser();
+ // 更新当前授权成功用户的信息
+ KiccUser kiccUser = new KiccUser(
+ currentKiccUser.getId(),
+ currentKiccUser.getDeptId(),
+ currentKiccUser.getUsername(),
+ currentKiccUser.getPassword(),
+ currentKiccUser.getPhone(),
+ StrUtil.join(",", tenantIds),
+ currentKiccUser.isEnabled(),
+ currentKiccUser.isAccountNonExpired(),
+ currentKiccUser.isCredentialsNonExpired(),
+ currentKiccUser.isAccountNonLocked(),
+ currentKiccUser.getAuthorities()
+ );
+ // 加载用户名密码身份验证令牌
+ Authentication userAuthentication = new UsernamePasswordAuthenticationToken(kiccUser, "N/A", kiccUser.getAuthorities());
+ OAuth2Authentication authentication = new OAuth2Authentication(oAuth2Request, userAuthentication);
+ authentication.setAuthenticated(true);
+ tokenStore.storeAccessToken(accessToken, authentication);
+ }
+
/**
* 新增用户角色信息
* @param user 用户对象