feat: 可替换实现UserDetailsConverter,支持个性化业务定制
This commit is contained in:
parent
ffd026c421
commit
39fe3ace5d
@ -20,6 +20,7 @@ import dev.flyfish.framework.user.config.converter.EncryptedAuthenticationConver
|
|||||||
import dev.flyfish.framework.user.config.properties.SecurityProperties;
|
import dev.flyfish.framework.user.config.properties.SecurityProperties;
|
||||||
import dev.flyfish.framework.user.domain.UserQo;
|
import dev.flyfish.framework.user.domain.UserQo;
|
||||||
import dev.flyfish.framework.user.initializer.UserInitializer;
|
import dev.flyfish.framework.user.initializer.UserInitializer;
|
||||||
|
import dev.flyfish.framework.user.service.DefaultUserDetailsConverter;
|
||||||
import dev.flyfish.framework.user.service.DepartmentService;
|
import dev.flyfish.framework.user.service.DepartmentService;
|
||||||
import dev.flyfish.framework.user.service.UserDetailsConverter;
|
import dev.flyfish.framework.user.service.UserDetailsConverter;
|
||||||
import dev.flyfish.framework.user.service.UserService;
|
import dev.flyfish.framework.user.service.UserService;
|
||||||
@ -231,6 +232,6 @@ public class WebSecurityConfig {
|
|||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public UserDetailsConverter userDetailsConverter(DepartmentService departmentService) {
|
public UserDetailsConverter userDetailsConverter(DepartmentService departmentService) {
|
||||||
return new UserDetailsConverter(departmentService);
|
return new DefaultUserDetailsConverter(departmentService);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package dev.flyfish.framework.user.config.audit;
|
|||||||
|
|
||||||
import dev.flyfish.framework.auditor.ReactiveBeanPoster;
|
import dev.flyfish.framework.auditor.ReactiveBeanPoster;
|
||||||
import dev.flyfish.framework.domain.po.Role;
|
import dev.flyfish.framework.domain.po.Role;
|
||||||
import dev.flyfish.framework.user.service.UserDetailsConverter;
|
|
||||||
import dev.flyfish.framework.utils.ReactiveRedisOperations;
|
import dev.flyfish.framework.utils.ReactiveRedisOperations;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -18,7 +17,6 @@ import reactor.core.publisher.Mono;
|
|||||||
public class RoleBeanPoster implements ReactiveBeanPoster<Role> {
|
public class RoleBeanPoster implements ReactiveBeanPoster<Role> {
|
||||||
|
|
||||||
private final ReactiveRedisOperations reactiveRedisOperations;
|
private final ReactiveRedisOperations reactiveRedisOperations;
|
||||||
private final UserDetailsConverter userDetailsConverter;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 对入库的实体进行审查,并执行额外功能
|
* 对入库的实体进行审查,并执行额外功能
|
||||||
|
@ -2,11 +2,11 @@ package dev.flyfish.framework.user.config.audit;
|
|||||||
|
|
||||||
import dev.flyfish.framework.auditor.ReactiveBeanAuditor;
|
import dev.flyfish.framework.auditor.ReactiveBeanAuditor;
|
||||||
import dev.flyfish.framework.auditor.ReactiveBeanPoster;
|
import dev.flyfish.framework.auditor.ReactiveBeanPoster;
|
||||||
import dev.flyfish.framework.user.service.UserDetailsConverter;
|
|
||||||
import dev.flyfish.framework.user.utils.StrengthUtils;
|
|
||||||
import dev.flyfish.framework.user.config.constants.UserCacheKeys;
|
|
||||||
import dev.flyfish.framework.domain.po.User;
|
import dev.flyfish.framework.domain.po.User;
|
||||||
import dev.flyfish.framework.enums.UserType;
|
import dev.flyfish.framework.enums.UserType;
|
||||||
|
import dev.flyfish.framework.user.config.constants.UserCacheKeys;
|
||||||
|
import dev.flyfish.framework.user.service.UserDetailsConverter;
|
||||||
|
import dev.flyfish.framework.user.utils.StrengthUtils;
|
||||||
import dev.flyfish.framework.utils.Assert;
|
import dev.flyfish.framework.utils.Assert;
|
||||||
import dev.flyfish.framework.utils.ReactiveRedisOperations;
|
import dev.flyfish.framework.utils.ReactiveRedisOperations;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
@ -0,0 +1,101 @@
|
|||||||
|
package dev.flyfish.framework.user.service;
|
||||||
|
|
||||||
|
import dev.flyfish.framework.domain.base.IUser;
|
||||||
|
import dev.flyfish.framework.domain.po.Department;
|
||||||
|
import dev.flyfish.framework.domain.po.Role;
|
||||||
|
import dev.flyfish.framework.enums.UserType;
|
||||||
|
import dev.flyfish.framework.user.domain.AdminUserDetails;
|
||||||
|
import dev.flyfish.framework.utils.CopyUtils;
|
||||||
|
import dev.flyfish.framework.utils.DepartUtils;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class DefaultUserDetailsConverter implements UserDetailsConverter {
|
||||||
|
|
||||||
|
private final DepartmentService departmentService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将用户映射为用户详情,查询所有权限code
|
||||||
|
*
|
||||||
|
* @param user 用户信息
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public Mono<UserDetails> mapToUserDetails(IUser user) {
|
||||||
|
AdminUserDetails userDetail = new AdminUserDetails();
|
||||||
|
CopyUtils.copyProps(user, userDetail);
|
||||||
|
userDetail.setAuthorityCodes(Collections.singleton(Department.PUBLIC));
|
||||||
|
if (user.getType() == UserType.SUPER_ADMIN) {
|
||||||
|
userDetail.setAuthorityCodes(null);
|
||||||
|
} else if (CollectionUtils.isNotEmpty(user.getDepartments())) {
|
||||||
|
return judgeDeparts(user, userDetail);
|
||||||
|
}
|
||||||
|
return Mono.just(userDetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断部门包含关系,默认看不到本部门的数据却可以看到子部门的
|
||||||
|
*
|
||||||
|
* @param user 用户信息
|
||||||
|
* @param userDetails 用户详情
|
||||||
|
*/
|
||||||
|
private Mono<UserDetails> judgeDeparts(IUser user, AdminUserDetails userDetails) {
|
||||||
|
// 整合数据权限
|
||||||
|
Set<Role.Authority> authorities = user.getRoles().stream()
|
||||||
|
.flatMap(role -> null == role.getAuthorities() ? Stream.empty() : role.getAuthorities().stream())
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
// 默认使用用户当前选择的权限进行查询
|
||||||
|
String authority = user.getAuthority();
|
||||||
|
// 根据权限组装查询条件
|
||||||
|
Set<String> departs = StringUtils.isNotBlank(authority) ? Collections.singleton(authority) :
|
||||||
|
DepartUtils.mergeDeparts(user.getDepartments());
|
||||||
|
// 查询所有子部门id
|
||||||
|
return departmentService.getSubCodes(departs)
|
||||||
|
.map(codes -> {
|
||||||
|
// 取出权限,便于判定
|
||||||
|
boolean admin = authorities.contains(Role.Authority.ADMIN);
|
||||||
|
boolean view = authorities.contains(Role.Authority.VIEW);
|
||||||
|
boolean viewChildren = authorities.contains(Role.Authority.VIEW_CHILDREN);
|
||||||
|
// 全部
|
||||||
|
Set<String> all = new HashSet<>();
|
||||||
|
// 拥有查看本部门的权限
|
||||||
|
if (admin || view) {
|
||||||
|
all.addAll(departs);
|
||||||
|
}
|
||||||
|
// 拥有查看所有下级的权限
|
||||||
|
if (admin || viewChildren) {
|
||||||
|
all.addAll(codes);
|
||||||
|
}
|
||||||
|
// 最终设置权限
|
||||||
|
if (CollectionUtils.isNotEmpty(all)) {
|
||||||
|
userDetails.setAuthorityCodes(union(all, userDetails.getAuthorityCodes()));
|
||||||
|
}
|
||||||
|
userDetails.setVisibleDeparts(union(codes, departs));
|
||||||
|
return userDetails;
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 链接两个set
|
||||||
|
*
|
||||||
|
* @param a 第一个
|
||||||
|
* @param b 第二个
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
private Set<String> union(Set<String> a, Set<String> b) {
|
||||||
|
Set<String> result = new HashSet<>();
|
||||||
|
result.addAll(a);
|
||||||
|
result.addAll(b);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +1,14 @@
|
|||||||
package dev.flyfish.framework.user.service;
|
package dev.flyfish.framework.user.service;
|
||||||
|
|
||||||
import dev.flyfish.framework.user.config.constants.UserCacheKeys;
|
|
||||||
import dev.flyfish.framework.configuration.jwt.TokenProvider;
|
import dev.flyfish.framework.configuration.jwt.TokenProvider;
|
||||||
import dev.flyfish.framework.domain.base.IUser;
|
import dev.flyfish.framework.domain.base.IUser;
|
||||||
import dev.flyfish.framework.enums.UserStatus;
|
import dev.flyfish.framework.enums.UserStatus;
|
||||||
import dev.flyfish.framework.service.FlyfishUserDetailsService;
|
import dev.flyfish.framework.service.FlyfishUserDetailsService;
|
||||||
|
import dev.flyfish.framework.user.config.constants.UserCacheKeys;
|
||||||
import dev.flyfish.framework.utils.Assert;
|
import dev.flyfish.framework.utils.Assert;
|
||||||
import dev.flyfish.framework.utils.ReactiveRedisOperations;
|
import dev.flyfish.framework.utils.ReactiveRedisOperations;
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
import org.springframework.security.authentication.*;
|
import org.springframework.security.authentication.*;
|
||||||
@ -23,7 +24,6 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.web.server.ServerWebExchange;
|
import org.springframework.web.server.ServerWebExchange;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
@ -1,28 +1,15 @@
|
|||||||
package dev.flyfish.framework.user.service;
|
package dev.flyfish.framework.user.service;
|
||||||
|
|
||||||
import dev.flyfish.framework.user.domain.AdminUserDetails;
|
|
||||||
import dev.flyfish.framework.domain.base.IUser;
|
import dev.flyfish.framework.domain.base.IUser;
|
||||||
import dev.flyfish.framework.domain.po.Department;
|
|
||||||
import dev.flyfish.framework.domain.po.Role;
|
|
||||||
import dev.flyfish.framework.enums.UserType;
|
|
||||||
import dev.flyfish.framework.utils.CopyUtils;
|
|
||||||
import dev.flyfish.framework.utils.DepartUtils;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import java.util.*;
|
/**
|
||||||
import java.util.stream.Collectors;
|
* 用户详情转换器
|
||||||
import java.util.stream.Stream;
|
*
|
||||||
|
* @author wangyu
|
||||||
@Service
|
*/
|
||||||
@RequiredArgsConstructor
|
public interface UserDetailsConverter {
|
||||||
public class UserDetailsConverter {
|
|
||||||
|
|
||||||
private final DepartmentService departmentService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将用户映射为用户详情,查询所有权限code
|
* 将用户映射为用户详情,查询所有权限code
|
||||||
@ -30,72 +17,5 @@ public class UserDetailsConverter {
|
|||||||
* @param user 用户信息
|
* @param user 用户信息
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
public Mono<UserDetails> mapToUserDetails(IUser user) {
|
Mono<UserDetails> mapToUserDetails(IUser user);
|
||||||
AdminUserDetails userDetail = new AdminUserDetails();
|
|
||||||
CopyUtils.copyProps(user, userDetail);
|
|
||||||
userDetail.setAuthorityCodes(Collections.singleton(Department.PUBLIC));
|
|
||||||
if (user.getType() == UserType.SUPER_ADMIN) {
|
|
||||||
userDetail.setAuthorityCodes(null);
|
|
||||||
} else if (CollectionUtils.isNotEmpty(user.getDepartments())) {
|
|
||||||
return judgeDeparts(user, userDetail);
|
|
||||||
}
|
|
||||||
return Mono.just(userDetail);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断部门包含关系,默认看不到本部门的数据却可以看到子部门的
|
|
||||||
*
|
|
||||||
* @param user 用户信息
|
|
||||||
* @param userDetails 用户详情
|
|
||||||
*/
|
|
||||||
private Mono<UserDetails> judgeDeparts(IUser user, AdminUserDetails userDetails) {
|
|
||||||
// 整合数据权限
|
|
||||||
Set<Role.Authority> authorities = user.getRoles().stream()
|
|
||||||
.flatMap(role -> null == role.getAuthorities() ? Stream.empty() : role.getAuthorities().stream())
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
// 默认使用用户当前选择的权限进行查询
|
|
||||||
String authority = user.getAuthority();
|
|
||||||
// 根据权限组装查询条件
|
|
||||||
Set<String> departs = StringUtils.isNotBlank(authority) ? Collections.singleton(authority) :
|
|
||||||
DepartUtils.mergeDeparts(user.getDepartments());
|
|
||||||
// 查询所有子部门id
|
|
||||||
return departmentService.getSubCodes(departs)
|
|
||||||
.map(codes -> {
|
|
||||||
// 取出权限,便于判定
|
|
||||||
boolean admin = authorities.contains(Role.Authority.ADMIN);
|
|
||||||
boolean view = authorities.contains(Role.Authority.VIEW);
|
|
||||||
boolean viewChildren = authorities.contains(Role.Authority.VIEW_CHILDREN);
|
|
||||||
// 全部
|
|
||||||
Set<String> all = new HashSet<>();
|
|
||||||
// 拥有查看本部门的权限
|
|
||||||
if (admin || view) {
|
|
||||||
all.addAll(departs);
|
|
||||||
}
|
|
||||||
// 拥有查看所有下级的权限
|
|
||||||
if (admin || viewChildren) {
|
|
||||||
all.addAll(codes);
|
|
||||||
}
|
|
||||||
// 最终设置权限
|
|
||||||
if (CollectionUtils.isNotEmpty(all)) {
|
|
||||||
userDetails.setAuthorityCodes(union(all, userDetails.getAuthorityCodes()));
|
|
||||||
}
|
|
||||||
userDetails.setVisibleDeparts(union(codes, departs));
|
|
||||||
return userDetails;
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 链接两个set
|
|
||||||
*
|
|
||||||
* @param a 第一个
|
|
||||||
* @param b 第二个
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
private Set<String> union(Set<String> a, Set<String> b) {
|
|
||||||
Set<String> result = new HashSet<>();
|
|
||||||
result.addAll(a);
|
|
||||||
result.addAll(b);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user