forked from github/cool-admin-java
fix: RBAC模型P2安全修复
P2-8: 删除实体时级联清理中间表 P2-9: BaseEntity添加delFlag逻辑删除字段 P2-10: adminLogout清理roleIds和perms缓存 P2-11: 启用EnableMethodSecurity,BaseController增加checkPermission钩子 P2-12: 移除eps/getModuleTree/createCode的TokenIgnore
This commit is contained in:
@@ -115,6 +115,7 @@ public abstract class BaseController<S extends BaseService<T>, T extends BaseEnt
|
||||
@Operation(summary = "新增", description = "新增信息,对应后端的实体类")
|
||||
@PostMapping("/add")
|
||||
protected R add(@RequestAttribute() JSONObject requestParams) {
|
||||
checkPermission("add");
|
||||
String body = requestParams.getStr("body");
|
||||
if (JSONUtil.isTypeJSONArray(body)) {
|
||||
JSONArray array = JSONUtil.parseArray(body);
|
||||
@@ -135,6 +136,7 @@ public abstract class BaseController<S extends BaseService<T>, T extends BaseEnt
|
||||
@PostMapping("/delete")
|
||||
protected R delete(HttpServletRequest request, @RequestBody Map<String, Object> params,
|
||||
@RequestAttribute() JSONObject requestParams) {
|
||||
checkPermission("delete");
|
||||
service.delete(requestParams, Convert.toLongArray(getIds(params)));
|
||||
return R.ok();
|
||||
}
|
||||
@@ -147,6 +149,7 @@ public abstract class BaseController<S extends BaseService<T>, T extends BaseEnt
|
||||
@Operation(summary = "修改", description = "根据ID修改")
|
||||
@PostMapping("/update")
|
||||
protected R update(@RequestBody T t, @RequestAttribute() JSONObject requestParams) {
|
||||
checkPermission("update");
|
||||
Long id = t.getId();
|
||||
JSONObject info = JSONUtil.parseObj(JSONUtil.toJsonStr(service.getById(id)));
|
||||
requestParams.forEach(info::set);
|
||||
@@ -286,4 +289,7 @@ public abstract class BaseController<S extends BaseService<T>, T extends BaseEnt
|
||||
page.setRecords(transformList(page.getRecords(), asType));
|
||||
return page;
|
||||
}
|
||||
|
||||
protected void checkPermission(String action) {
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,10 @@ public abstract class BaseEntity<T extends Model<T>> extends Model<T> implements
|
||||
@ColumnDefine(comment = "更新时间")
|
||||
protected Date updateTime;
|
||||
|
||||
@Column(isLogicDelete = true)
|
||||
@ColumnDefine(comment = "删除标记 0:未删除 1:已删除", defaultValue = "0")
|
||||
protected Integer delFlag;
|
||||
|
||||
@Ignore
|
||||
@Column(ignore = true)
|
||||
@JsonIgnore
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.AuthenticationProvider;
|
||||
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||
@@ -32,6 +33,7 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandl
|
||||
import org.springframework.web.util.pattern.PathPattern;
|
||||
|
||||
@EnableWebSecurity
|
||||
@EnableMethodSecurity
|
||||
@Configuration
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
|
||||
@@ -85,7 +85,8 @@ public class CoolSecurityUtil {
|
||||
*/
|
||||
public static void adminLogout(Long adminUserId, String username) {
|
||||
coolCache.del("admin:department:" + adminUserId, "admin:passwordVersion:" + adminUserId,
|
||||
"admin:userInfo:" + adminUserId, "admin:userDetails:" + username);
|
||||
"admin:userInfo:" + adminUserId, "admin:userDetails:" + username,
|
||||
"admin:roleIds:" + adminUserId, "admin:perms:" + adminUserId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,14 +24,12 @@ public class AdminBaseCodingController {
|
||||
|
||||
private final BaseCodingService baseCodingService;
|
||||
|
||||
@TokenIgnore
|
||||
@Operation(summary = "获取模块目录结构", description = "获取模块目录结构")
|
||||
@GetMapping("/getModuleTree")
|
||||
public R getModuleTree() {
|
||||
return R.ok(baseCodingService.getModuleTree());
|
||||
}
|
||||
|
||||
@TokenIgnore
|
||||
@Operation(summary = "创建代码", description = "创建代码")
|
||||
@PostMapping("/createCode")
|
||||
public R createCode(@RequestAttribute JSONObject requestParams) {
|
||||
|
||||
@@ -44,7 +44,6 @@ public class AdminBaseCommController {
|
||||
|
||||
final private FileUploadStrategyFactory fileUploadStrategyFactory;
|
||||
|
||||
@TokenIgnore
|
||||
@Operation(summary = "实体信息与路径", description = "系统所有的实体信息与路径,供前端自动生成代码与服务")
|
||||
@GetMapping("/eps")
|
||||
public R eps() {
|
||||
|
||||
+9
@@ -4,10 +4,12 @@ import cn.hutool.json.JSONObject;
|
||||
import com.cool.core.annotation.CoolRestController;
|
||||
import com.cool.core.base.BaseController;
|
||||
import com.cool.core.request.R;
|
||||
import com.cool.core.util.CoolSecurityUtil;
|
||||
import com.cool.modules.base.entity.sys.BaseSysDepartmentEntity;
|
||||
import com.cool.modules.base.service.sys.BaseSysDepartmentService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
@@ -22,6 +24,13 @@ import java.util.List;
|
||||
public class AdminBaseSysDepartmentController
|
||||
extends BaseController<BaseSysDepartmentService, BaseSysDepartmentEntity> {
|
||||
|
||||
@Override
|
||||
protected void checkPermission(String action) {
|
||||
if (("add".equals(action) || "delete".equals(action) || "update".equals(action)) && !CoolSecurityUtil.isSuperAdmin()) {
|
||||
throw new AccessDeniedException("仅超级管理员可操作部门");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init(HttpServletRequest request, JSONObject requestParams) {
|
||||
}
|
||||
|
||||
+10
@@ -12,6 +12,7 @@ import com.cool.modules.base.service.sys.BaseSysRoleService;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
|
||||
/**
|
||||
* 系统角色
|
||||
@@ -20,6 +21,15 @@ import jakarta.servlet.http.HttpServletRequest;
|
||||
@CoolRestController(api = { "add", "delete", "update", "page", "list", "info" })
|
||||
public class AdminBaseSysRoleController extends BaseController<BaseSysRoleService, BaseSysRoleEntity> {
|
||||
|
||||
@Override
|
||||
protected void checkPermission(String action) {
|
||||
if ("add".equals(action) || "delete".equals(action) || "update".equals(action)) {
|
||||
if (!CoolSecurityUtil.isSuperAdmin()) {
|
||||
throw new AccessDeniedException("仅超级管理员可操作角色");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init(HttpServletRequest request, JSONObject requestParams) {
|
||||
JSONObject tokenInfo = requestParams.getJSONObject("tokenInfo");
|
||||
|
||||
+9
@@ -8,9 +8,11 @@ import com.cool.modules.base.entity.sys.BaseSysUserEntity;
|
||||
import com.cool.modules.base.service.sys.BaseSysUserService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestAttribute;
|
||||
|
||||
import com.cool.core.util.CoolSecurityUtil;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
@@ -20,6 +22,13 @@ import jakarta.servlet.http.HttpServletRequest;
|
||||
@CoolRestController(api = { "add", "delete", "update", "page", "info" })
|
||||
public class AdminBaseSysUserController extends BaseController<BaseSysUserService, BaseSysUserEntity> {
|
||||
|
||||
@Override
|
||||
protected void checkPermission(String action) {
|
||||
if ("delete".equals(action) && !CoolSecurityUtil.isSuperAdmin()) {
|
||||
throw new AccessDeniedException("仅超级管理员可删除用户");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init(HttpServletRequest request, JSONObject requestParams) {
|
||||
}
|
||||
|
||||
@@ -5,8 +5,10 @@ import com.cool.core.base.BaseServiceImpl;
|
||||
import com.cool.core.exception.CoolPreconditions;
|
||||
import com.cool.core.util.CoolSecurityUtil;
|
||||
import com.cool.modules.base.entity.sys.BaseSysDepartmentEntity;
|
||||
import com.cool.modules.base.entity.sys.BaseSysRoleDepartmentEntity;
|
||||
import com.cool.modules.base.entity.sys.BaseSysUserEntity;
|
||||
import com.cool.modules.base.mapper.sys.BaseSysDepartmentMapper;
|
||||
import com.cool.modules.base.mapper.sys.BaseSysRoleDepartmentMapper;
|
||||
import com.cool.modules.base.mapper.sys.BaseSysUserMapper;
|
||||
import com.cool.modules.base.service.sys.BaseSysDepartmentService;
|
||||
import com.cool.modules.base.service.sys.BaseSysPermsService;
|
||||
@@ -16,6 +18,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* 系统部门
|
||||
@@ -30,6 +33,8 @@ public class BaseSysDepartmentServiceImpl extends
|
||||
|
||||
final private BaseSysPermsService baseSysPermsService;
|
||||
|
||||
final private BaseSysRoleDepartmentMapper baseSysRoleDepartmentMapper;
|
||||
|
||||
@Override
|
||||
public void order(List<BaseSysDepartmentEntity> list) {
|
||||
list.forEach(baseSysDepartmentEntity -> {
|
||||
@@ -64,6 +69,7 @@ public class BaseSysDepartmentServiceImpl extends
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean delete(JSONObject requestParams, Long... ids) {
|
||||
List<Long> allDeptIds = new ArrayList<>(List.of(ids));
|
||||
for (Long id : ids) {
|
||||
@@ -72,6 +78,8 @@ public class BaseSysDepartmentServiceImpl extends
|
||||
long userCount = baseSysUserMapper.selectCountByQuery(
|
||||
QueryWrapper.create().in(BaseSysUserEntity::getDepartmentId, allDeptIds));
|
||||
CoolPreconditions.check(userCount > 0, "该部门或其子部门下存在用户,无法删除");
|
||||
baseSysRoleDepartmentMapper.deleteByQuery(
|
||||
QueryWrapper.create().in(BaseSysRoleDepartmentEntity::getDepartmentId, allDeptIds));
|
||||
return super.delete(ids);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,9 @@ import com.cool.core.util.CompilerUtils;
|
||||
import com.cool.core.util.CoolSecurityUtil;
|
||||
import com.cool.core.util.PathUtils;
|
||||
import com.cool.modules.base.entity.sys.BaseSysMenuEntity;
|
||||
import com.cool.modules.base.entity.sys.BaseSysRoleMenuEntity;
|
||||
import com.cool.modules.base.mapper.sys.BaseSysMenuMapper;
|
||||
import com.cool.modules.base.mapper.sys.BaseSysRoleMenuMapper;
|
||||
import com.cool.modules.base.service.sys.BaseSysMenuService;
|
||||
import com.cool.modules.base.service.sys.BaseSysPermsService;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
@@ -37,6 +39,8 @@ public class BaseSysMenuServiceImpl extends BaseServiceImpl<BaseSysMenuMapper, B
|
||||
|
||||
final private CoolEps coolEps;
|
||||
|
||||
final private BaseSysRoleMenuMapper baseSysRoleMenuMapper;
|
||||
|
||||
@Override
|
||||
public Object list(JSONObject requestParams, QueryWrapper queryWrapper) {
|
||||
List<BaseSysMenuEntity> list = baseSysPermsService.getMenus(CoolSecurityUtil.getAdminUsername());
|
||||
@@ -71,6 +75,10 @@ public class BaseSysMenuServiceImpl extends BaseServiceImpl<BaseSysMenuMapper, B
|
||||
|
||||
@Override
|
||||
public boolean delete(Long... ids) {
|
||||
for (Long id : ids) {
|
||||
baseSysRoleMenuMapper.deleteByQuery(
|
||||
QueryWrapper.create().eq(BaseSysRoleMenuEntity::getMenuId, id));
|
||||
}
|
||||
super.delete(ids);
|
||||
for (Long id : ids) {
|
||||
this.delChildMenu(id);
|
||||
|
||||
@@ -9,9 +9,11 @@ import com.cool.core.util.CoolSecurityUtil;
|
||||
import com.cool.modules.base.entity.sys.BaseSysRoleDepartmentEntity;
|
||||
import com.cool.modules.base.entity.sys.BaseSysRoleEntity;
|
||||
import com.cool.modules.base.entity.sys.BaseSysRoleMenuEntity;
|
||||
import com.cool.modules.base.entity.sys.BaseSysUserRoleEntity;
|
||||
import com.cool.modules.base.mapper.sys.BaseSysRoleDepartmentMapper;
|
||||
import com.cool.modules.base.mapper.sys.BaseSysRoleMapper;
|
||||
import com.cool.modules.base.mapper.sys.BaseSysRoleMenuMapper;
|
||||
import com.cool.modules.base.mapper.sys.BaseSysUserRoleMapper;
|
||||
import com.cool.modules.base.service.sys.BaseSysPermsService;
|
||||
import com.cool.modules.base.service.sys.BaseSysRoleService;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
@@ -37,6 +39,8 @@ public class BaseSysRoleServiceImpl extends BaseServiceImpl<BaseSysRoleMapper, B
|
||||
|
||||
final private BaseSysPermsService baseSysPermsService;
|
||||
|
||||
final private BaseSysUserRoleMapper baseSysUserRoleMapper;
|
||||
|
||||
@Override
|
||||
public Object add(JSONObject requestParams, BaseSysRoleEntity entity) {
|
||||
BaseSysRoleEntity checkLabel = getOne(QueryWrapper.create().eq(BaseSysRoleEntity::getLabel, entity.getLabel()));
|
||||
@@ -77,6 +81,12 @@ public class BaseSysRoleServiceImpl extends BaseServiceImpl<BaseSysRoleMapper, B
|
||||
if (type == ModifyEnum.DELETE) {
|
||||
Long[] ids = requestParams.get("ids", Long[].class);
|
||||
for (Long id : ids) {
|
||||
baseSysRoleMenuMapper.deleteByQuery(
|
||||
QueryWrapper.create().eq(BaseSysRoleMenuEntity::getRoleId, id));
|
||||
baseSysRoleDepartmentMapper.deleteByQuery(
|
||||
QueryWrapper.create().eq(BaseSysRoleDepartmentEntity::getRoleId, id));
|
||||
baseSysUserRoleMapper.deleteByQuery(
|
||||
QueryWrapper.create().eq(BaseSysUserRoleEntity::getRoleId, id));
|
||||
baseSysPermsService.refreshPermsByRoleId(id);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -182,7 +182,16 @@ public class BaseSysUserServiceImpl extends BaseServiceImpl<BaseSysUserMapper, B
|
||||
@Override
|
||||
public void modifyAfter(JSONObject requestParams, BaseSysUserEntity baseSysUserEntity,
|
||||
ModifyEnum type) {
|
||||
if (type != ModifyEnum.DELETE && requestParams.get("roleIdList", Long[].class) != null) {
|
||||
if (type == ModifyEnum.DELETE) {
|
||||
Long[] ids = requestParams.get("ids", Long[].class);
|
||||
if (ids != null) {
|
||||
for (Long id : ids) {
|
||||
baseSysUserRoleMapper.deleteByQuery(
|
||||
QueryWrapper.create().eq(BaseSysUserRoleEntity::getUserId, id));
|
||||
CoolSecurityUtil.adminLogout(id, null);
|
||||
}
|
||||
}
|
||||
} else if (requestParams.get("roleIdList", Long[].class) != null) {
|
||||
Long[] roleIdList = requestParams.get("roleIdList", Long[].class);
|
||||
validateRoleAssignment(roleIdList);
|
||||
baseSysPermsService.updateUserRole(baseSysUserEntity.getId(), roleIdList);
|
||||
|
||||
Reference in New Issue
Block a user