Переглянути джерело

:zap: 登录、新增用户增加租户权限判断

smallchill 6 роки тому
батько
коміт
c35f940cd9

+ 11 - 0
src/main/java/org/springblade/common/cache/SysCache.java

@@ -51,6 +51,7 @@ public class SysCache {
 	private static final String ROLE_ALIAS_ID = "roleAlias:id:";
 	private static final String ROLE_ALIASES_ID = "roleAliases:id:";
 	private static final String TENANT_ID = "tenant:id:";
+	private static final String TENANT_TENANT_ID = "tenant:tenantId:";
 
 	private static IMenuService menuService;
 	private static IDeptService deptService;
@@ -199,4 +200,14 @@ public class SysCache {
 		return CacheUtil.get(SYS_CACHE, TENANT_ID, id, () -> tenantService.getById(id));
 	}
 
+	/**
+	 * 获取租户
+	 *
+	 * @param tenantId 租户id
+	 * @return Tenant
+	 */
+	public static Tenant getTenant(String tenantId) {
+		return CacheUtil.get(SYS_CACHE, TENANT_TENANT_ID, tenantId, () -> tenantService.getByTenantId(tenantId));
+	}
+
 }

+ 14 - 4
src/main/java/org/springblade/modules/auth/granter/PasswordTokenGranter.java

@@ -17,10 +17,14 @@
 package org.springblade.modules.auth.granter;
 
 import lombok.AllArgsConstructor;
+import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.tool.utils.DigestUtil;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.modules.auth.enums.BladeUserEnum;
+import org.springblade.modules.auth.utils.TokenUtil;
+import org.springblade.modules.system.entity.Tenant;
 import org.springblade.modules.system.entity.UserInfo;
+import org.springblade.modules.system.service.ITenantService;
 import org.springblade.modules.system.service.IUserService;
 import org.springframework.stereotype.Component;
 
@@ -35,7 +39,8 @@ public class PasswordTokenGranter implements ITokenGranter {
 
 	public static final String GRANT_TYPE = "password";
 
-	private IUserService service;
+	private IUserService userService;
+	private ITenantService tenantService;
 
 	@Override
 	public UserInfo grant(TokenParameter tokenParameter) {
@@ -44,15 +49,20 @@ public class PasswordTokenGranter implements ITokenGranter {
 		String password = tokenParameter.getArgs().getStr("password");
 		UserInfo userInfo = null;
 		if (Func.isNoneBlank(username, password)) {
+			// 获取租户信息
+			Tenant tenant = tenantService.getByTenantId(tenantId);
+			if (!TokenUtil.judgeTenant(tenant)) {
+				throw new ServiceException(TokenUtil.USER_HAS_NO_TENANT_PERMISSION);
+			}
 			// 获取用户类型
 			String userType = tokenParameter.getArgs().getStr("userType");
 			// 根据不同用户类型调用对应的接口返回数据,用户可自行拓展
 			if (userType.equals(BladeUserEnum.WEB.getName())) {
-				userInfo = service.userInfo(tenantId, username, DigestUtil.encrypt(password));
+				userInfo = userService.userInfo(tenantId, username, DigestUtil.encrypt(password));
 			} else if (userType.equals(BladeUserEnum.APP.getName())) {
-				userInfo = service.userInfo(tenantId, username, DigestUtil.encrypt(password));
+				userInfo = userService.userInfo(tenantId, username, DigestUtil.encrypt(password));
 			} else {
-				userInfo = service.userInfo(tenantId, username, DigestUtil.encrypt(password));
+				userInfo = userService.userInfo(tenantId, username, DigestUtil.encrypt(password));
 			}
 		}
 		return userInfo;

+ 14 - 2
src/main/java/org/springblade/modules/auth/granter/RefreshTokenGranter.java

@@ -19,9 +19,13 @@ package org.springblade.modules.auth.granter;
 import io.jsonwebtoken.Claims;
 import lombok.AllArgsConstructor;
 import org.springblade.core.launch.constant.TokenConstant;
+import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.secure.utils.SecureUtil;
 import org.springblade.core.tool.utils.Func;
+import org.springblade.modules.auth.utils.TokenUtil;
+import org.springblade.modules.system.entity.Tenant;
 import org.springblade.modules.system.entity.UserInfo;
+import org.springblade.modules.system.service.ITenantService;
 import org.springblade.modules.system.service.IUserService;
 import org.springframework.stereotype.Component;
 
@@ -38,10 +42,12 @@ public class RefreshTokenGranter implements ITokenGranter {
 
 	public static final String GRANT_TYPE = "refresh_token";
 
-	private IUserService service;
+	private IUserService userService;
+	private ITenantService tenantService;
 
 	@Override
 	public UserInfo grant(TokenParameter tokenParameter) {
+		String tenantId = tokenParameter.getArgs().getStr("tenantId");
 		String grantType = tokenParameter.getArgs().getStr("grantType");
 		String refreshToken = tokenParameter.getArgs().getStr("refreshToken");
 		UserInfo userInfo = null;
@@ -49,7 +55,13 @@ public class RefreshTokenGranter implements ITokenGranter {
 			Claims claims = SecureUtil.parseJWT(refreshToken);
 			String tokenType = Func.toStr(Objects.requireNonNull(claims).get(TokenConstant.TOKEN_TYPE));
 			if (tokenType.equals(TokenConstant.REFRESH_TOKEN)) {
-				userInfo = service.userInfo(Func.toLong(claims.get(TokenConstant.USER_ID)));
+				// 获取租户信息
+				Tenant tenant = tenantService.getByTenantId(tenantId);
+				if (!TokenUtil.judgeTenant(tenant)) {
+					throw new ServiceException(TokenUtil.USER_HAS_NO_TENANT_PERMISSION);
+				}
+				// 获取用户信息
+				userInfo = userService.userInfo(Func.toLong(claims.get(TokenConstant.USER_ID)));
 			}
 		}
 		return userInfo;

+ 24 - 0
src/main/java/org/springblade/modules/auth/utils/TokenUtil.java

@@ -17,14 +17,18 @@
 package org.springblade.modules.auth.utils;
 
 import org.springblade.core.launch.constant.TokenConstant;
+import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.secure.TokenInfo;
 import org.springblade.core.secure.utils.SecureUtil;
 import org.springblade.core.tool.support.Kv;
+import org.springblade.core.tool.utils.DateUtil;
 import org.springblade.core.tool.utils.Func;
+import org.springblade.modules.system.entity.Tenant;
 import org.springblade.modules.system.entity.User;
 import org.springblade.modules.system.entity.UserInfo;
 
 import javax.servlet.http.HttpServletResponse;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -40,6 +44,9 @@ public class TokenUtil {
 	public final static String USER_TYPE_HEADER_KEY = "User-Type";
 	public final static String DEFAULT_USER_TYPE = "web";
 	public final static String USER_NOT_FOUND = "用户名或密码错误";
+	public final static String USER_HAS_NO_ROLE = "未获得用户的角色信息";
+	public final static String USER_HAS_NO_TENANT = "未获得用户的租户信息";
+	public final static String USER_HAS_NO_TENANT_PERMISSION = "租户授权已过期,请联系管理员";
 	public final static String HEADER_KEY = "Authorization";
 	public final static String HEADER_PREFIX = "Basic ";
 	public final static String DEFAULT_AVATAR = "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png";
@@ -99,4 +106,21 @@ public class TokenUtil {
 		return SecureUtil.createJWT(param, "audience", "issuser", TokenConstant.REFRESH_TOKEN);
 	}
 
+	/**
+	 * 判断租户权限
+	 *
+	 * @param tenant 租户信息
+	 * @return boolean
+	 */
+	public static boolean judgeTenant(Tenant tenant) {
+		if (tenant == null) {
+			throw new ServiceException(TokenUtil.USER_HAS_NO_TENANT);
+		}
+		Date expireTime = tenant.getExpireTime();
+		if (expireTime != null && expireTime.before(DateUtil.now())) {
+			throw new ServiceException(TokenUtil.USER_HAS_NO_TENANT_PERMISSION);
+		}
+		return true;
+	}
+
 }

+ 6 - 0
src/main/java/org/springblade/modules/system/controller/TenantController.java

@@ -34,6 +34,7 @@ import org.springblade.core.tool.constant.RoleConstant;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.modules.system.entity.Tenant;
 import org.springblade.modules.system.service.ITenantService;
+import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.web.bind.annotation.*;
 import springfox.documentation.annotations.ApiIgnore;
 
@@ -42,6 +43,8 @@ import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
+import static org.springblade.core.cache.constant.CacheConstant.SYS_CACHE;
+
 /**
  * 控制器
  *
@@ -117,6 +120,7 @@ public class TenantController extends BladeController {
 	@ApiOperationSupport(order = 5)
 	@ApiOperation(value = "新增或修改", notes = "传入tenant")
 	@PreAuth(RoleConstant.HAS_ROLE_ADMINISTRATOR)
+	@CacheEvict(cacheNames = {SYS_CACHE}, allEntries = true)
 	public R submit(@Valid @RequestBody Tenant tenant) {
 		return R.status(tenantService.saveTenant(tenant));
 	}
@@ -129,6 +133,7 @@ public class TenantController extends BladeController {
 	@ApiOperationSupport(order = 6)
 	@ApiOperation(value = "逻辑删除", notes = "传入ids")
 	@PreAuth(RoleConstant.HAS_ROLE_ADMINISTRATOR)
+	@CacheEvict(cacheNames = {SYS_CACHE}, allEntries = true)
 	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
 		return R.status(tenantService.deleteLogic(Func.toLongList(ids)));
 	}
@@ -140,6 +145,7 @@ public class TenantController extends BladeController {
 	@ApiOperationSupport(order = 7)
 	@ApiOperation(value = "授权配置", notes = "传入ids,accountNumber,expireTime")
 	@PreAuth(RoleConstant.HAS_ROLE_ADMINISTRATOR)
+	@CacheEvict(cacheNames = {SYS_CACHE}, allEntries = true)
 	public R setting(@ApiParam(value = "主键集合", required = true) @RequestParam String ids, @ApiParam(value = "账号额度") Integer accountNumber, @ApiParam(value = "过期时间") Date expireTime) {
 		boolean temp = tenantService.update(
 			Wrappers.<Tenant>update().lambda()

+ 8 - 0
src/main/java/org/springblade/modules/system/service/ITenantService.java

@@ -36,6 +36,14 @@ public interface ITenantService extends BaseService<Tenant> {
 	 */
 	IPage<Tenant> selectTenantPage(IPage<Tenant> page, Tenant tenant);
 
+	/**
+	 * 根据租户编号获取实体
+	 *
+	 * @param tenantId
+	 * @return
+	 */
+	Tenant getByTenantId(String tenantId);
+
 	/**
 	 * 新增
 	 *

+ 5 - 0
src/main/java/org/springblade/modules/system/service/impl/TenantServiceImpl.java

@@ -54,6 +54,11 @@ public class TenantServiceImpl extends BaseServiceImpl<TenantMapper, Tenant> imp
 		return page.setRecords(baseMapper.selectTenantPage(page, tenant));
 	}
 
+	@Override
+	public Tenant getByTenantId(String tenantId) {
+		return getOne(Wrappers.<Tenant>query().lambda().eq(Tenant::getTenantId, tenantId));
+	}
+
 	@Override
 	@Transactional(rollbackFor = Exception.class)
 	public boolean saveTenant(Tenant tenant) {

+ 10 - 2
src/main/java/org/springblade/modules/system/service/impl/UserServiceImpl.java

@@ -30,6 +30,7 @@ import org.springblade.core.tool.constant.BladeConstant;
 import org.springblade.core.tool.utils.DateUtil;
 import org.springblade.core.tool.utils.DigestUtil;
 import org.springblade.core.tool.utils.Func;
+import org.springblade.modules.system.entity.Tenant;
 import org.springblade.modules.system.entity.User;
 import org.springblade.modules.system.entity.UserDept;
 import org.springblade.modules.system.entity.UserInfo;
@@ -56,11 +57,18 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
 	@Override
 	@Transactional(rollbackFor = Exception.class)
 	public boolean submit(User user) {
+		String tenantId = user.getTenantId();
+		Tenant tenant = SysCache.getTenant(tenantId);
+		Integer accountNumber = tenant.getAccountNumber();
+		Integer tenantCount = baseMapper.selectCount(Wrappers.<User>query().lambda().eq(User::getTenantId, Func.toStr(tenantId, BladeConstant.ADMIN_TENANT_ID)));
+		if (accountNumber != null && accountNumber > 0 && accountNumber < tenantCount) {
+			throw new ServiceException("当前租户已到最大账号额度");
+		}
 		if (Func.isNotEmpty(user.getPassword())) {
 			user.setPassword(DigestUtil.encrypt(user.getPassword()));
 		}
-		Integer cnt = baseMapper.selectCount(Wrappers.<User>query().lambda().eq(User::getTenantId, Func.toStr(user.getTenantId(), BladeConstant.ADMIN_TENANT_ID)).eq(User::getAccount, user.getAccount()));
-		if (cnt > 0 && Func.isEmpty(user.getId())) {
+		Integer userCount = baseMapper.selectCount(Wrappers.<User>query().lambda().eq(User::getTenantId, Func.toStr(tenantId, BladeConstant.ADMIN_TENANT_ID)).eq(User::getAccount, user.getAccount()));
+		if (userCount > 0 && Func.isEmpty(user.getId())) {
 			throw new ApiException("当前用户已存在!");
 		}
 		return save(user) && submitUserDept(user);