Files
aue/私人文件查看权限更新.md
2026-06-03 13:16:30 +08:00

151 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
私人文件权限控制修改文档
📋 修改概述
修改目标实现私人文件isPublic=0的严格访问控制确保只有文件所有者本人可以查看和访问。
修改时间2026-05-06 修改文件FileServiceImpl.java
影响范围:文件查询、文件详情查看、文件内容下载/预览功能
🔍 问题分析
原有问题
在修改前,系统的文件权限控制存在以下安全漏洞:
私人文件未隔离:即使是 isPublic=0 的私人文件,同部门的其他用户也能看到和访问
权限检查缺失checkFilePermission 方法没有区分文件的公开/私人属性
查询过滤不足pageFiles 方法在列表查询时未排除他人的私人文件
安全隐患
❌ 用户A上传的私人文件同部门的用户B也能看到
❌ 部门管理员可以查看所有本部门用户的私人文件
❌ 隐私数据可能被未授权人员访问
✅ 修改内容
修改点 1增强权限检查逻辑
位置:第 475-506 行 方法checkFilePermission(File file, User user)
修改前代码
private void checkFilePermission(top.tqx.demo_1.entity.File file, top.tqx.demo_1.entity.User user) {
Integer userType = user.getUserType();
Long currentUserId = user.getId();
Long currentDeptId = user.getDeptId();
if (userType.equals(CommonConstant.RoleType.SUPER_ADMIN)) {
return;
}
if (userType.equals(CommonConstant.RoleType.DEPT_ADMIN)) {
if (!file.getDeptId().equals(currentDeptId)) {
throw new RuntimeException("无权限查看此文件");
}
return;
}
if (userType.equals(CommonConstant.RoleType.NORMAL_USER)) {
if (!file.getDeptId().equals(currentDeptId)) {
throw new RuntimeException("无权限查看此文件");
}
if (!file.getUploadUserId().equals(currentUserId)) {
throw new RuntimeException("无权限查看此文件");
}
if (file.getAuditStatus() != null && file.getAuditStatus() == 0) {
throw new RuntimeException("文件待审核,暂时无法查看");
}
}
修改后代码
private void checkFilePermission(top.tqx.demo_1.entity.File file, top.tqx.demo_1.entity.User user) {
Integer userType = user.getUserType();
Long currentUserId = user.getId();
Long currentDeptId = user.getDeptId();
// 超级管理员拥有所有权限
if (userType.equals(CommonConstant.RoleType.SUPER_ADMIN)) {
return;
}
// 【新增】私人文件权限检查:只有上传者本人可访问
if (file.getIsPublic() != null && file.getIsPublic() == 0) {
if (!file.getUploadUserId().equals(currentUserId)) {
throw new RuntimeException("无权限查看此私人文件");
}
return;
}
// 公开文件的部门权限检查
if (userType.equals(CommonConstant.RoleType.DEPT_ADMIN)) {
if (!file.getDeptId().equals(currentDeptId)) {
throw new RuntimeException("无权限查看此文件");
}
return;
}
if (userType.equals(CommonConstant.RoleType.NORMAL_USER)) {
if (!file.getDeptId().equals(currentDeptId)) {
throw new RuntimeException("无权限查看此文件");
}
if (file.getAuditStatus() != null && file.getAuditStatus() == 0) {
throw new RuntimeException("文件待审核,暂时无法查看");
}
}
关键改进
✅ 优先检查私人文件:在任何其他权限判断之前,先判断是否为私人文件 ✅ 严格所有者验证:私人文件必须满足 uploadUserId == currentUserId ✅ 提前返回机制:私人文件检查通过后直接返回,避免后续逻辑干扰
修改点 2增强列表查询过滤
位置:第 48-87 行 方法pageFiles(Integer pageNum, Integer pageSize, String fileName, User user)
修改前代码
```
if (userType.equals(CommonConstant.RoleType.SUPER_ADMIN)) {
wrapper.eq(File::getStatus, CommonConstant.STATUS_ENABLE);
} else if (userType.equals(CommonConstant.RoleType.DEPT_ADMIN)) {
wrapper.eq(File::getStatus, CommonConstant.STATUS_ENABLE);
wrapper.and(w -> w.eq(File::getDeptId, currentDeptId)
.or().eq(File::getUploadUserId, currentUserId));
} else if (userType.equals(CommonConstant.RoleType.NORMAL_USER)) {
wrapper.eq(File::getStatus, CommonConstant.STATUS_ENABLE);
wrapper.ne(File::getAuditStatus, 0);
wrapper.and(w -> w.eq(File::getDeptId, currentDeptId)
.or().eq(File::getUploadUserId, currentUserId));
}
```
修改后代码
```
if (userType.equals(CommonConstant.RoleType.SUPER_ADMIN)) {
wrapper.eq(File::getStatus, CommonConstant.STATUS_ENABLE);
} else if (userType.equals(CommonConstant.RoleType.DEPT_ADMIN)) {
wrapper.eq(File::getStatus, CommonConstant.STATUS_ENABLE);
wrapper.and(w -> w.eq(File::getDeptId, currentDeptId)
.or().eq(File::getUploadUserId, currentUserId));
// 【新增】排除他人私人文件
wrapper.and(w -> w.ne(File::getIsPublic, 0)
.or().eq(File::getUploadUserId, currentUserId));
} else if (userType.equals(CommonConstant.RoleType.NORMAL_USER)) {
wrapper.eq(File::getStatus, CommonConstant.STATUS_ENABLE);
wrapper.ne(File::getAuditStatus, 0);
wrapper.and(w -> w.eq(File::getDeptId, currentDeptId)
.or().eq(File::getUploadUserId, currentUserId));
// 【新增】排除他人私人文件
wrapper.and(w -> w.ne(File::getIsPublic, 0)
.or().eq(File::getUploadUserId, currentUserId));
}
```
SQL 逻辑说明
新增的过滤条件生成的 SQL 逻辑为:
```
-- 对于部门管理员和普通用户
WHERE ...
AND (
is_public != 0 -- 非私人文件
OR upload_user_id = currentUserId -- 或者是自己上传的文件
)
```
关键改进
✅ 数据库层过滤:在查询阶段就排除他人私人文件,提升性能和安全性 ✅ 双重保护:既在查询层过滤,又在访问层检查,形成纵深防御 ✅ 保留自身访问:用户可以查看自己的私人文件(包括已上传的私人文件)