mirror of
http://192.168.1.205:9980/cf_devdept2/cf_imes_server.git
synced 2026-08-12 21:02:08 +08:00
1、菜单权限问题修复;
2、增加修改菜单权限刷新本地缓存;
This commit is contained in:
Vendored
+11
-3
@@ -17,13 +17,21 @@ import java.util.concurrent.Executors;
|
||||
public class CacheUtils {
|
||||
|
||||
public static <K, V> LoadingCache<K, V> buildAsyncReloadingCache(Duration duration, CacheLoader<K, V> loader) {
|
||||
Executor executor = Executors.newCachedThreadPool( // TODO 晨丰:可能要思考下,未来要不要做成可配置
|
||||
TtlExecutors.getDefaultDisableInheritableThreadFactory()); // TTL 保证 ThreadLocal 可以透传
|
||||
return CacheBuilder.newBuilder()
|
||||
// 只阻塞当前数据加载线程,其他线程返回旧值
|
||||
.refreshAfterWrite(duration)
|
||||
// 通过 asyncReloading 实现全异步加载,包括 refreshAfterWrite 被阻塞的加载线程
|
||||
.build(CacheLoader.asyncReloading(loader, executor));
|
||||
.build(CacheLoader.asyncReloading(loader, Executors.newCachedThreadPool())); // TODO 芋艿:可能要思考下,未来要不要做成可配置
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建同步刷新的 LoadingCache 对象
|
||||
*
|
||||
* @param duration 过期时间
|
||||
* @param loader CacheLoader 对象
|
||||
* @return LoadingCache 对象
|
||||
*/
|
||||
public static <K, V> LoadingCache<K, V> buildCache(Duration duration, CacheLoader<K, V> loader) {
|
||||
return CacheBuilder.newBuilder().refreshAfterWrite(duration).build(loader);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-12
@@ -1,8 +1,6 @@
|
||||
package com.cf.imes.framework.organ.core.security;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.cf.imes.framework.common.enums.RpcConstants;
|
||||
import com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants;
|
||||
import com.cf.imes.framework.common.pojo.CommonResult;
|
||||
import com.cf.imes.framework.common.util.servlet.ServletUtils;
|
||||
@@ -56,18 +54,10 @@ public class OrganSecurityWebFilter extends ApiRequestFilter {
|
||||
this.organFrameworkService = organFrameworkService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldNotFilter(HttpServletRequest request) {
|
||||
return super.shouldNotFilter(request) &&
|
||||
!StrUtil.startWithAny(request.getRequestURI(), RpcConstants.RPC_API_PREFIX); // 因为 RPC API 也会透传组织编号
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
|
||||
throws ServletException, IOException {
|
||||
Long organId = WebFrameworkUtils.getOrganId(request);
|
||||
//Long organId = OrganContextHolder.getOrganId();
|
||||
boolean isRpcRequest = WebFrameworkUtils.isRpcRequest(request);
|
||||
// 1. 登陆的用户,校验是否有权限访问该组织,避免越权问题。
|
||||
LoginUser user = SecurityFrameworkUtils.getLoginUser();
|
||||
if (user != null) {
|
||||
@@ -76,8 +66,7 @@ public class OrganSecurityWebFilter extends ApiRequestFilter {
|
||||
organId = user.getOrganId();
|
||||
OrganContextHolder.setOrganId(organId);
|
||||
// 如果传递了组织编号,则进行比对组织编号,避免越权问题
|
||||
} else if (!Objects.equals(user.getOrganId(), OrganContextHolder.getOrganId())
|
||||
&& !isRpcRequest) { // Cloud 特殊逻辑:如果是 RPC 请求,就不校验了。主要考虑,一些场景下,会调用 OrganUtils 去切换组织
|
||||
} else if (!Objects.equals(user.getOrganId(), OrganContextHolder.getOrganId())) { // Cloud 特殊逻辑:如果是 RPC 请求,就不校验了。主要考虑,一些场景下,会调用 OrganUtils 去切换组织
|
||||
log.error("[doFilterInternal][组织({}) User({}/{}) 越权访问组织({}) URL({}/{})]",
|
||||
user.getOrganId(), user.getId(), user.getUserType(),
|
||||
OrganContextHolder.getOrganId(), request.getRequestURI(), request.getMethod());
|
||||
|
||||
+21
@@ -7,6 +7,7 @@ import com.cf.imes.framework.common.enums.DocumentEnum;
|
||||
import com.cf.imes.framework.mq.redis.core.RedisMQTemplate;
|
||||
import com.cf.imes.framework.mq.redis.core.job.RedisPendingMessageResendJob;
|
||||
import com.cf.imes.framework.mq.redis.core.pubsub.AbstractRedisChannelMessageListener;
|
||||
import com.cf.imes.framework.mq.redis.core.pubsub.AbstractRedisSimpleMessageListener;
|
||||
import com.cf.imes.framework.mq.redis.core.stream.AbstractRedisStreamMessageListener;
|
||||
import com.cf.imes.framework.redis.config.ChenfengRedisAutoConfiguration;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -61,6 +62,26 @@ public class ChenfengRedisMQConsumerAutoConfiguration {
|
||||
return container;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 Redis Pub/Sub 广播消费的容器
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnBean(AbstractRedisSimpleMessageListener.class)
|
||||
public RedisMessageListenerContainer redisDelListenerContainer(
|
||||
RedisTemplate redisTemplate, List<AbstractRedisSimpleMessageListener> listeners) {
|
||||
// 创建 RedisMessageListenerContainer 对象
|
||||
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
|
||||
// 设置 RedisConnection 工厂。
|
||||
container.setConnectionFactory(redisTemplate.getRequiredConnectionFactory());
|
||||
// 添加监听器
|
||||
listeners.forEach(listener -> {
|
||||
container.addMessageListener(listener, listener.getTopic());
|
||||
log.info("[redisMessageListenerContainer][注册 ChannelTopic({}) 对应的监听器({})]",
|
||||
listener.getTopic(), listener.getClass().getName());
|
||||
});
|
||||
return container;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 Redis Stream 重新消费的任务
|
||||
*/
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.cf.imes.framework.mq.redis.core.pubsub;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.data.redis.connection.MessageListener;
|
||||
import org.springframework.data.redis.listener.ChannelTopic;
|
||||
|
||||
/**
|
||||
* Redis监听器
|
||||
*
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
public abstract class AbstractRedisSimpleMessageListener implements MessageListener {
|
||||
|
||||
/**
|
||||
* 通道主题
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private ChannelTopic topic;
|
||||
}
|
||||
+7
@@ -23,6 +23,13 @@ public interface SecurityFrameworkService {
|
||||
*/
|
||||
boolean hasAnyPermissions(String... permissions);
|
||||
|
||||
/**
|
||||
* 清空本地缓存
|
||||
*
|
||||
* @param
|
||||
*/
|
||||
void invalidateAll();
|
||||
|
||||
/**
|
||||
* 判断是否有角色
|
||||
*
|
||||
|
||||
+7
-2
@@ -28,7 +28,7 @@ public class SecurityFrameworkServiceImpl implements SecurityFrameworkService {
|
||||
/**
|
||||
* 针对 {@link #hasAnyRoles(String...)} 的缓存
|
||||
*/
|
||||
private final LoadingCache<KeyValue<Long, List<String>>, Boolean> hasAnyRolesCache = CacheUtils.buildAsyncReloadingCache(
|
||||
private final LoadingCache<KeyValue<Long, List<String>>, Boolean> hasAnyRolesCache = CacheUtils.buildCache(
|
||||
Duration.ofMinutes(1L), // 过期时间 1 分钟
|
||||
new CacheLoader<KeyValue<Long, List<String>>, Boolean>() {
|
||||
|
||||
@@ -42,7 +42,7 @@ public class SecurityFrameworkServiceImpl implements SecurityFrameworkService {
|
||||
/**
|
||||
* 针对 {@link #hasAnyPermissions(String...)} 的缓存
|
||||
*/
|
||||
private final LoadingCache<KeyValue<Long, List<String>>, Boolean> hasAnyPermissionsCache = CacheUtils.buildAsyncReloadingCache(
|
||||
private final LoadingCache<KeyValue<Long, List<String>>, Boolean> hasAnyPermissionsCache = CacheUtils.buildCache(
|
||||
Duration.ofMinutes(1L), // 过期时间 1 分钟
|
||||
new CacheLoader<KeyValue<Long, List<String>>, Boolean>() {
|
||||
|
||||
@@ -65,6 +65,11 @@ public class SecurityFrameworkServiceImpl implements SecurityFrameworkService {
|
||||
return hasAnyPermissionsCache.get(new KeyValue<>(SecurityFrameworkUtils.getLoginUserId(), Arrays.asList(permissions)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateAll() {
|
||||
hasAnyPermissionsCache.invalidateAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRole(String role) {
|
||||
return hasAnyRoles(role);
|
||||
|
||||
Reference in New Issue
Block a user