新增组织产品有效性的检查能力

This commit is contained in:
gaoqr
2025-09-24 09:36:24 +08:00
parent 6e365e77aa
commit c070584159
22 changed files with 174 additions and 15 deletions
@@ -32,6 +32,11 @@ public class OrganProperties {
*/
private Set<String> ignoreUrls = Collections.emptySet();
/**
* 需要忽略产品检查的请求
*/
private Set<String> ignoreProductUrls = Collections.emptySet();
/**
* 需要忽略多组织的表
*
@@ -2,6 +2,7 @@ package com.cf.imes.framework.organ.core.security;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.cf.imes.framework.common.enums.UserTypeEnum;
import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants;
import com.cf.imes.framework.common.pojo.CommonResult;
@@ -23,6 +24,7 @@ import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;
@@ -31,7 +33,7 @@ import java.util.Objects;
* 1. 如果是登陆的用户,校验是否有权限访问该组织,避免越权问题。
* 2. 如果请求未带组织的编号,检查是否是忽略的 URL,否则也不允许访问。
* 3. 校验组织是合法,例如说被禁用、到期
*
* <p>
* 校验用户访问的组织,是否是其所在的组织,
*
* @author 晨丰科技
@@ -70,7 +72,7 @@ public class OrganSecurityWebFilter extends ApiRequestFilter {
if (organId == null) {
organId = user.getOrganId();
OrganContextHolder.setOrganId(organId);
// 如果传递了组织编号,则进行比对组织编号,避免越权问题
// 如果传递了组织编号,则进行比对组织编号,避免越权问题
} else if (!Objects.equals(user.getOrganId(), OrganContextHolder.getOrganId())) { // Cloud 特殊逻辑:如果是 RPC 请求,就不校验了。主要考虑,一些场景下,会调用 OrganUtils 去切换组织
log.error("[doFilterInternal][组织({}) User({}/{}) 越权访问组织({}) URL({}/{})]",
user.getOrganId(), user.getId(), user.getUserType(),
@@ -98,6 +100,10 @@ public class OrganSecurityWebFilter extends ApiRequestFilter {
// 校验部门
organFrameworkService.validDept(deptId);
}
// 校验组织产品有效性
validOrgnProduct(user, request);
} catch (Throwable ex) {
CommonResult<?> result = globalExceptionHandler.allExceptionHandler(request, ex);
// 组织失效返回401踢出系统
@@ -115,6 +121,19 @@ public class OrganSecurityWebFilter extends ApiRequestFilter {
chain.doFilter(request, response);
}
/**
* 校验组织产品有效性
*
* @param user
* @param request
*/
private void validOrgnProduct(LoginUser user, HttpServletRequest request) {
// 非管理端校验产品的有效性
if (!Objects.equals(user.getUserType(), UserTypeEnum.ADMIN.getValue()) && !isProductIgnoreUrl(request)) {
organFrameworkService.validOrgProduct(user.getOrganId(), user.getProductId());
}
}
private boolean isIgnoreUrl(HttpServletRequest request) {
// 快速匹配,保证性能
if (CollUtil.contains(organProperties.getIgnoreUrls(), request.getRequestURI())) {
@@ -129,6 +148,20 @@ public class OrganSecurityWebFilter extends ApiRequestFilter {
return false;
}
private boolean isProductIgnoreUrl(HttpServletRequest request) {
// 快速匹配,保证性能
if (CollUtil.contains(organProperties.getIgnoreProductUrls(), request.getRequestURI())) {
return true;
}
// 逐个 Ant 路径匹配
for (String url : organProperties.getIgnoreProductUrls()) {
if (pathMatcher.match(url, request.getRequestURI())) {
return true;
}
}
return false;
}
/**
* 是否组织失效设置未登录回调
*
@@ -29,4 +29,12 @@ public interface OrganFrameworkService {
* @param id
*/
void validDept(Long id);
/**
* 校验组织产品是否有效
*
* @param organId
* @param productId
*/
void validOrgProduct(Long organId, Long productId);
}
@@ -1,5 +1,6 @@
package com.cf.imes.framework.organ.core.service;
import cn.hutool.core.lang.Pair;
import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.framework.common.util.cache.CacheUtils;
import com.cf.imes.module.system.api.dept.DeptApi;
@@ -66,6 +67,20 @@ public class OrganFrameworkServiceImpl implements OrganFrameworkService {
});
/**
* 针对 {@link #validOrgProduct(Long, Long)} 的缓存
*/
private final LoadingCache<Pair<Long, Long>, CommonResult<Boolean>> validOrgProduct = CacheUtils.buildCache(
Duration.ofMinutes(1L), // 过期时间 1 分钟
new CacheLoader<>() {
@Override
public CommonResult<Boolean> load(Pair<Long, Long> pair) {
return organApi.validOrganProduct(pair.getKey(), pair.getValue());
}
});
@Override
@SneakyThrows
public List<Long> getOrganIds() {
@@ -83,4 +98,10 @@ public class OrganFrameworkServiceImpl implements OrganFrameworkService {
public void validDept(Long id) {
validOrganDept.get(id).checkError();
}
@Override
@SneakyThrows
public void validOrgProduct(Long organId, Long productId) {
validOrgProduct.get(new Pair<>(organId, productId)).checkError();
}
}