修复引入多租户后,前端 <img /> 读取图片报错的问题
parent
b99f364d92
commit
abf61bfdea
File diff suppressed because it is too large
Load Diff
|
@ -10,6 +10,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.adminserver.modules.infra.convert.file.InfFileConvert;
|
import cn.iocoder.yudao.adminserver.modules.infra.convert.file.InfFileConvert;
|
||||||
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
|
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
|
||||||
|
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiImplicitParam;
|
import io.swagger.annotations.ApiImplicitParam;
|
||||||
import io.swagger.annotations.ApiImplicitParams;
|
import io.swagger.annotations.ApiImplicitParams;
|
||||||
|
@ -64,6 +65,7 @@ public class InfFileController {
|
||||||
@ApiOperation("下载文件")
|
@ApiOperation("下载文件")
|
||||||
@ApiImplicitParam(name = "path", value = "文件附件", required = true, dataTypeClass = MultipartFile.class)
|
@ApiImplicitParam(name = "path", value = "文件附件", required = true, dataTypeClass = MultipartFile.class)
|
||||||
public void getFile(HttpServletResponse response, @PathVariable("path") String path) throws IOException {
|
public void getFile(HttpServletResponse response, @PathVariable("path") String path) throws IOException {
|
||||||
|
TenantContextHolder.setNullTenantId();
|
||||||
InfFileDO file = fileCoreService.getFile(path);
|
InfFileDO file = fileCoreService.getFile(path);
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
log.warn("[getFile][path({}) 文件不存在]", path);
|
log.warn("[getFile][path({}) 文件不存在]", path);
|
||||||
|
|
|
@ -2,11 +2,27 @@ package cn.iocoder.yudao.coreservice.modules.infra.dal.mysql.file;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
import cn.iocoder.yudao.coreservice.modules.infra.dal.dataobject.file.InfFileDO;
|
import cn.iocoder.yudao.coreservice.modules.infra.dal.dataobject.file.InfFileDO;
|
||||||
|
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface InfFileCoreMapper extends BaseMapperX<InfFileDO> {
|
public interface InfFileCoreMapper extends BaseMapperX<InfFileDO> {
|
||||||
|
|
||||||
default Integer selectCountById(String id) {
|
default Integer selectCountById(String id) {
|
||||||
return selectCount("id", id);
|
return selectCount("id", id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基于 Path 获取文件
|
||||||
|
* 实际上,是基于 ID 查询
|
||||||
|
* 由于前端使用 <img /> 的方式获取图片,所以需要忽略租户的查询
|
||||||
|
*
|
||||||
|
* @param path 路径
|
||||||
|
* @return 文件
|
||||||
|
*/
|
||||||
|
@InterceptorIgnore(tenantLine = "true")
|
||||||
|
default InfFileDO selectByPath(String path) {
|
||||||
|
return selectById(path);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ public class InfFileCoreServiceImpl implements InfFileCoreService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InfFileDO getFile(String path) {
|
public InfFileDO getFile(String path) {
|
||||||
return fileMapper.selectById(path);
|
return fileMapper.selectByPath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,11 @@ public class TenantContextHolder {
|
||||||
|
|
||||||
private static final ThreadLocal<Long> TENANT_ID = new TransmittableThreadLocal<>();
|
private static final ThreadLocal<Long> TENANT_ID = new TransmittableThreadLocal<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 租户编号 - 空
|
||||||
|
*/
|
||||||
|
private static final Long TENANT_ID_NULL = 0L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得租户编号。
|
* 获得租户编号。
|
||||||
*
|
*
|
||||||
|
@ -33,6 +38,15 @@ public class TenantContextHolder {
|
||||||
return tenantId;
|
return tenantId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在一些前端场景下,可能无法请求带上租户。例如说,<img /> 方式获取图片等
|
||||||
|
* 此时,暂时的解决方案,是在该接口的 Controller 方法上,调用该方法
|
||||||
|
* TODO 芋艿:思考有没更合适的方案,目标是去掉该方法
|
||||||
|
*/
|
||||||
|
public static void setNullTenantId() {
|
||||||
|
TENANT_ID.set(TENANT_ID_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
public static void setTenantId(Long tenantId) {
|
public static void setTenantId(Long tenantId) {
|
||||||
TENANT_ID.set(tenantId);
|
TENANT_ID.set(tenantId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ public class TenantSecurityWebFilter extends OncePerRequestFilter {
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
LoginUser user = SecurityFrameworkUtils.getLoginUser();
|
LoginUser user = SecurityFrameworkUtils.getLoginUser();
|
||||||
assert user != null; // shouldNotFilter 已经校验
|
assert user != null; // shouldNotFilter 已经校验
|
||||||
|
// 校验租户是否匹配。
|
||||||
if (!Objects.equals(user.getTenantId(), TenantContextHolder.getTenantId())) {
|
if (!Objects.equals(user.getTenantId(), TenantContextHolder.getTenantId())) {
|
||||||
log.error("[doFilterInternal][租户({}) User({}/{}) 越权访问租户({}) URL({}/{})]",
|
log.error("[doFilterInternal][租户({}) User({}/{}) 越权访问租户({}) URL({}/{})]",
|
||||||
user.getTenantId(), user.getId(), user.getUserType(),
|
user.getTenantId(), user.getId(), user.getUserType(),
|
||||||
|
|
Loading…
Reference in New Issue