✨ 新增应收账单按角色和客户归属的行级数据权限
This commit is contained in:
+78
@@ -0,0 +1,78 @@
|
||||
package com.bms.framework.aspectj;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.annotation.AfterReturning;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
import com.bms.common.core.domain.entity.SysRole;
|
||||
import com.bms.common.core.domain.entity.SysUser;
|
||||
import com.bms.framework.web.service.TokenService;
|
||||
import com.bms.system.domain.SysUserRole;
|
||||
|
||||
/** 授权关系修改提交后,让旧登录态失效;不参与业务 SQL 数据范围计算。 */
|
||||
@Aspect
|
||||
@Component
|
||||
@Order(1)
|
||||
public class AuthorizationSessionAspect {
|
||||
private final TokenService tokenService;
|
||||
|
||||
public AuthorizationSessionAspect(TokenService tokenService) {
|
||||
this.tokenService = tokenService;
|
||||
}
|
||||
|
||||
@AfterReturning(pointcut = "execution(* com.bms.system.service.impl.SysUserServiceImpl.updateUser(..))"
|
||||
+ " || execution(* com.bms.system.service.impl.SysUserServiceImpl.updateUserStatus(..))"
|
||||
+ " || execution(* com.bms.system.service.impl.SysUserServiceImpl.insertUserAuth(..))"
|
||||
+ " || execution(* com.bms.system.service.impl.SysUserServiceImpl.deleteUserBy*(..))", returning = "result")
|
||||
public void userChanged(JoinPoint point, Object result) {
|
||||
if (result instanceof Number && ((Number) result).intValue() <= 0) return;
|
||||
Object target = point.getArgs()[0];
|
||||
Set<Long> users = new HashSet<>();
|
||||
if (target instanceof SysUser) users.add(((SysUser) target).getUserId());
|
||||
else if (target instanceof Long[]) users.addAll(Arrays.asList((Long[]) target));
|
||||
else if (target instanceof Long) users.add((Long) target);
|
||||
invalidate(users, Set.of());
|
||||
}
|
||||
|
||||
@AfterReturning(pointcut = "execution(* com.bms.system.service.impl.SysRoleServiceImpl.updateRole(..))"
|
||||
+ " || execution(* com.bms.system.service.impl.SysRoleServiceImpl.updateRoleStatus(..))"
|
||||
+ " || execution(* com.bms.system.service.impl.SysRoleServiceImpl.deleteRoleBy*(..))"
|
||||
+ " || execution(* com.bms.system.service.impl.SysRoleServiceImpl.deleteAuthUser*(..))"
|
||||
+ " || execution(* com.bms.system.service.impl.SysRoleServiceImpl.insertAuthUsers(..))", returning = "result")
|
||||
public void roleChanged(JoinPoint point, Object result) {
|
||||
if (result instanceof Number && ((Number) result).intValue() <= 0) return;
|
||||
Object target = point.getArgs()[0];
|
||||
Set<Long> users = new HashSet<>();
|
||||
Set<Long> roles = new HashSet<>();
|
||||
if (target instanceof SysUserRole) users.add(((SysUserRole) target).getUserId());
|
||||
else if (point.getArgs().length > 1 && point.getArgs()[1] instanceof Long[])
|
||||
users.addAll(Arrays.asList((Long[]) point.getArgs()[1]));
|
||||
else if (target instanceof SysRole) roles.add(((SysRole) target).getRoleId());
|
||||
else if (target instanceof Long[]) roles.addAll(Arrays.asList((Long[]) target));
|
||||
else if (target instanceof Long) roles.add((Long) target);
|
||||
invalidate(users, roles);
|
||||
}
|
||||
|
||||
private void invalidate(Set<Long> users, Set<Long> roles) {
|
||||
users.remove(null);
|
||||
Set<Long> roleIds = new HashSet<>(roles);
|
||||
roleIds.remove(null);
|
||||
Set<Long> userIds = Set.copyOf(users);
|
||||
if (userIds.isEmpty() && roleIds.isEmpty()) return;
|
||||
Runnable action = () -> tokenService.evictAuthorizationSessions(userIds, roleIds);
|
||||
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
||||
@Override
|
||||
public void afterCommit() { action.run(); }
|
||||
});
|
||||
} else {
|
||||
action.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-9
@@ -1,8 +1,6 @@
|
||||
package com.bms.framework.security.context;
|
||||
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import com.bms.common.core.text.Convert;
|
||||
import com.bms.common.utils.PermissionContext;
|
||||
|
||||
/**
|
||||
* 权限信息
|
||||
@@ -11,17 +9,13 @@ import com.bms.common.core.text.Convert;
|
||||
*/
|
||||
public class PermissionContextHolder
|
||||
{
|
||||
private static final String PERMISSION_CONTEXT_ATTRIBUTES = "PERMISSION_CONTEXT";
|
||||
|
||||
public static void setContext(String permission)
|
||||
{
|
||||
RequestContextHolder.currentRequestAttributes().setAttribute(PERMISSION_CONTEXT_ATTRIBUTES, permission,
|
||||
RequestAttributes.SCOPE_REQUEST);
|
||||
PermissionContext.set(permission);
|
||||
}
|
||||
|
||||
public static String getContext()
|
||||
{
|
||||
return Convert.toStr(RequestContextHolder.currentRequestAttributes().getAttribute(PERMISSION_CONTEXT_ATTRIBUTES,
|
||||
RequestAttributes.SCOPE_REQUEST));
|
||||
return PermissionContext.get();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.bms.framework.web.service;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -231,6 +232,22 @@ public class TokenService
|
||||
return CacheConstants.LOGIN_TOKEN_KEY + uuid;
|
||||
}
|
||||
|
||||
/** 授权或部门变更后失效受影响会话,避免缓存中的旧角色继续扩大业务范围。 */
|
||||
public void evictAuthorizationSessions(Set<Long> userIds, Set<Long> roleIds)
|
||||
{
|
||||
Collection<String> keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
|
||||
if (keys == null) return;
|
||||
for (String key : keys)
|
||||
{
|
||||
LoginUser user = redisCache.getCacheObject(key);
|
||||
if (user == null || user.getUser() == null) continue;
|
||||
boolean affected = userIds.contains(user.getUserId())
|
||||
|| (user.getUser().getRoles() != null && user.getUser().getRoles().stream()
|
||||
.anyMatch(role -> role != null && roleIds.contains(role.getRoleId())));
|
||||
if (affected) redisCache.deleteObject(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 角色权限变更后,刷新所有持有该角色的在线用户权限
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user