漏洞修复

This commit is contained in:
山东云则
2024-12-27 14:34:19 +08:00
parent 281a9bc245
commit c2bbd26071
13 changed files with 267 additions and 11 deletions
@@ -9,6 +9,8 @@ import com.alibaba.fastjson.JSON;
import com.yunze.common.utils.ip.IpUtils;
import com.yunze.common.utils.spring.SpringUtils;
import com.yunze.common.utils.yunze.AesEncryptUtil;
import com.yunze.system.mapper.mysql.SysDeptMapper;
import com.yunze.system.service.ISysDeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
@@ -56,7 +58,8 @@ public class SysUserController extends BaseController
@Autowired
private ISysPostService postService;
@Autowired
private ISysDeptService deptService;
@Autowired
private TokenService tokenService;
@@ -174,6 +177,8 @@ public class SysUserController extends BaseController
@PostMapping
public AjaxResult add(@Validated @RequestBody SysUser user)
{
deptService.checkDeptDataScope(user.getDeptId());
roleService.checkRoleDataScope(user.getRoleIds());
if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user.getUserName())))
{
return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
@@ -202,6 +207,13 @@ public class SysUserController extends BaseController
public AjaxResult edit(@Validated @RequestBody SysUser user)
{
userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId());
deptService.checkDeptDataScope(user.getDeptId());
roleService.checkRoleDataScope(user.getRoleIds());
if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user.getUserName())))
{
return error("修改用户'" + user.getUserName() + "'失败,登录账号已存在");
}
if (StringUtils.isNotEmpty(user.getPhonenumber())
&& UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
{
@@ -236,6 +248,7 @@ public class SysUserController extends BaseController
public AjaxResult resetPwd(@RequestBody SysUser user)
{
userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId());
user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
user.setUpdateBy(SecurityUtils.getUsername());
return toAjax(userService.resetPwd(user));
@@ -250,6 +263,7 @@ public class SysUserController extends BaseController
public AjaxResult changeStatus(@RequestBody SysUser user)
{
userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId());
user.setUpdateBy(SecurityUtils.getUsername());
return toAjax(userService.updateUserStatus(user));
}
@@ -15,7 +15,14 @@ import com.yunze.common.core.domain.entity.SysUser;
public class LoginUser implements UserDetails
{
private static final long serialVersionUID = 1L;
/**
* 部门ID
*/
private Long deptId;
/**
* 用户ID
*/
private Long userId;
/**
* 用户唯一标识
*/
@@ -71,16 +78,31 @@ public class LoginUser implements UserDetails
this.token = token;
}
public LoginUser()
{
}
public LoginUser(SysUser user, Set<String> permissions)
public LoginUser(Long userId, Long deptId, SysUser user, Set<String> permissions)
{
this.userId = userId;
this.deptId = deptId;
this.user = user;
this.permissions = permissions;
}
public Long getDeptId()
{
return deptId;
}
public void setDeptId(Long deptId)
{
this.deptId = deptId;
}
public Long getUserId()
{
return userId;
}
public void setUserId(Long userId)
{
this.userId = userId;
}
@JsonIgnore
@Override
public String getPassword()
@@ -3,7 +3,7 @@ package com.yunze.common.exception;
/**
* 演示模式异常
*
* @author yunze
* @author ruoyi
*/
public class DemoModeException extends RuntimeException
{
@@ -0,0 +1,58 @@
package com.yunze.common.exception;
/**
* 全局异常
*
* @author ruoyi
*/
public class GlobalException extends RuntimeException
{
private static final long serialVersionUID = 1L;
/**
* 错误提示
*/
private String message;
/**
* 错误明细,内部调试错误
*
* 和 {@link CommonResult#getDetailMessage()} 一致的设计
*/
private String detailMessage;
/**
* 空构造方法,避免反序列化问题
*/
public GlobalException()
{
}
public GlobalException(String message)
{
this.message = message;
}
public String getDetailMessage()
{
return detailMessage;
}
public GlobalException setDetailMessage(String detailMessage)
{
this.detailMessage = detailMessage;
return this;
}
@Override
public String getMessage()
{
return message;
}
public GlobalException setMessage(String message)
{
this.message = message;
return this;
}
}
@@ -0,0 +1,74 @@
package com.yunze.common.exception;
/**
* 业务异常
*
* @author ruoyi
*/
public final class ServiceException extends RuntimeException
{
private static final long serialVersionUID = 1L;
/**
* 错误码
*/
private Integer code;
/**
* 错误提示
*/
private String message;
/**
* 错误明细,内部调试错误
*
* 和 {@link CommonResult#getDetailMessage()} 一致的设计
*/
private String detailMessage;
/**
* 空构造方法,避免反序列化问题
*/
public ServiceException()
{
}
public ServiceException(String message)
{
this.message = message;
}
public ServiceException(String message, Integer code)
{
this.message = message;
this.code = code;
}
public String getDetailMessage()
{
return detailMessage;
}
@Override
public String getMessage()
{
return message;
}
public Integer getCode()
{
return code;
}
public ServiceException setMessage(String message)
{
this.message = message;
return this;
}
public ServiceException setDetailMessage(String detailMessage)
{
this.detailMessage = detailMessage;
return this;
}
}
@@ -3,7 +3,7 @@ package com.yunze.common.exception;
/**
* 工具类异常
*
* @author yunze
* @author ruoyi
*/
public class UtilException extends RuntimeException
{
@@ -1,5 +1,6 @@
package com.yunze.common.utils;
import com.yunze.common.exception.ServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@@ -14,6 +15,20 @@ import com.yunze.common.exception.CustomException;
*/
public class SecurityUtils
{
/**
* 用户ID
**/
public static Long getUserId()
{
try
{
return getLoginUser().getUserId();
}
catch (Exception e)
{
throw new ServiceException("获取用户ID异常", HttpStatus.UNAUTHORIZED);
}
}
/**
* 获取用户账户
**/
@@ -119,4 +119,5 @@ public interface ISysDeptService
*/
public Map<String, Object> selMap(Map<String, Object> map);
void checkDeptDataScope(Long deptId);
}
@@ -128,4 +128,6 @@ public interface ISysRoleService
* @return 结果
*/
public int deleteRoleByIds(Long[] roleIds);
void checkRoleDataScope(Long[] roleIds);
}
@@ -179,4 +179,6 @@ public interface ISysUserService
public boolean userPhone(Map map);
SysUser selectUserByPhonenumber(String phone);
void checkUserDataScope(Long userId);
}
@@ -3,6 +3,10 @@ package com.yunze.system.service.impl;
import java.util.*;
import java.util.stream.Collectors;
import com.yunze.common.core.domain.entity.SysUser;
import com.yunze.common.exception.ServiceException;
import com.yunze.common.utils.SecurityUtils;
import com.yunze.common.utils.spring.SpringUtils;
import com.yunze.common.utils.yunze.PageUtil;
import org.springframework.stereotype.Service;
import com.yunze.common.annotation.DataScope;
@@ -328,7 +332,24 @@ public class SysDeptServiceImpl implements ISysDeptService
return omp;
}
/**
* 校验部门是否有数据权限
*
* @param deptId 部门id
*/
@Override
public void checkDeptDataScope(Long deptId)
{
if (!SysUser.isAdmin(SecurityUtils.getUserId()) && StringUtils.isNotNull(deptId))
{
SysDept dept = new SysDept();
dept.setDeptId(deptId);
List<SysDept> depts = SpringUtils.getAopProxy(this).selectDeptList(dept);
if (StringUtils.isEmpty(depts))
{
throw new ServiceException("没有权限访问部门数据!");
}
}
}
}
@@ -5,6 +5,10 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.yunze.common.core.domain.entity.SysUser;
import com.yunze.common.exception.ServiceException;
import com.yunze.common.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -325,4 +329,27 @@ public class SysRoleServiceImpl implements ISysRoleService
roleDeptMapper.deleteRoleDept(roleIds);
return roleMapper.deleteRoleByIds(roleIds);
}
/**
* 校验角色是否有数据权限
*
* @param roleIds 角色id
*/
@Override
public void checkRoleDataScope(Long... roleIds)
{
if (!SysUser.isAdmin(SecurityUtils.getUserId()))
{
for (Long roleId : roleIds)
{
SysRole role = new SysRole();
role.setRoleId(roleId);
List<SysRole> roles = SpringUtils.getAopProxy(this).selectRoleList(role);
if (StringUtils.isEmpty(roles))
{
throw new ServiceException("没有权限访问角色数据!");
}
}
}
}
}
@@ -442,5 +442,25 @@ public class SysUserServiceImpl implements ISysUserService {
return userMapper.userByPhonenumber(phone);
}
/**
* 校验用户是否有数据权限
*
* @param userId 用户id
*/
@Override
public void checkUserDataScope(Long userId)
{
if (!SysUser.isAdmin(SecurityUtils))
{
SysUser user = new SysUser();
user.setUserId(userId);
List<SysUser> users = SpringUtils.getAopProxy(this).selectUserList(user);
if (StringUtils.isEmpty(users))
{
throw new ServiceException("没有权限访问用户数据!");
}
}
}
}