stdproject/backend/src/main/java/com/stdproject/service/CustomUserDetailsService.java

147 lines
5.9 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.stdproject.service;
import com.stdproject.entity.LoginUser;
import com.stdproject.entity.Menu;
import com.stdproject.entity.Role;
import com.stdproject.entity.User;
import com.stdproject.mapper.MenuMapper;
import com.stdproject.mapper.RoleMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 自定义用户详情服务
* 实现Spring Security的UserDetailsService接口
*
* @author StdProject
*/
@Slf4j
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private IUserService appUserService;
@Autowired
private IMenuService appMenuService;
@Autowired
private RoleMapper roleMapper;
@Autowired
private MenuMapper menuMapper;
@Override
public UserDetails loadUserByUsername(String username) {
User appUser = appUserService.findByUsername(username);
if (appUser == null) {
throw new UsernameNotFoundException("用户不存在: " + username);
}
Collection<GrantedAuthority> authorities = buildUserAuthorities(appUser);
LoginUser loginUser = new LoginUser(appUser,authorities);
return loginUser;
}
/**
* 构建用户权限
*
* @param appUser 用户信息
* @return 权限集合
*/
private Collection<GrantedAuthority> buildUserAuthorities(User appUser) {
Set<GrantedAuthority> authorities = new HashSet<>();
try {
// 根据用户类型添加基本角色权限
if ("0".equals(appUser.getUsertype())) {
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
} else {
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
}
// 使用RoleMapper直接查询用户的角色信息
List<Role> roles = roleMapper.getRoleByUserId(appUser.getId());
if (!roles.isEmpty()) {
// 处理角色权限
for (Role role : roles) {
if ("1".equals(role.getIsvaild())) {
// 添加角色权限格式ROLE_角色编码
if (StringUtils.hasText(role.getRolecode())) {
authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getRolecode().toUpperCase()));
}
}
}
// 获取角色ID列表
List<String> roleIds = roles.stream()
.map(Role::getId)
.collect(Collectors.toList());
// 处理每个角色的菜单权限
for (String roleId : roleIds) {
// 使用MenuMapper直接查询角色关联的菜单ID
List<String> menuIds = menuMapper.selectMenuByRoleId(appUser.getAppId(), roleId);
if (!menuIds.isEmpty()) {
// 查询菜单信息并添加菜单权限
List<Menu> menus = appMenuService.listByIds(menuIds);
for (Menu menu : menus) {
if ("1".equals(menu.getIsdisplay()) && StringUtils.hasText(menu.getCode())) {
// 添加菜单权限,格式:菜单编码
authorities.add(new SimpleGrantedAuthority(menu.getCode()));
// 根据菜单类型添加操作权限
String menuCode = menu.getCode();
if (StringUtils.hasText(menuCode)) {
// 为每个菜单添加基本操作权限
authorities.add(new SimpleGrantedAuthority(menuCode + ":list"));
authorities.add(new SimpleGrantedAuthority(menuCode + ":detail"));
// 管理员拥有所有操作权限
if ("0".equals(appUser.getUsertype())) {
authorities.add(new SimpleGrantedAuthority(menuCode + ":add"));
authorities.add(new SimpleGrantedAuthority(menuCode + ":edit"));
authorities.add(new SimpleGrantedAuthority(menuCode + ":delete"));
authorities.add(new SimpleGrantedAuthority(menuCode + ":permission"));
}
}
}
}
}
}
}
log.debug("用户 {} 的权限列表: {}", appUser.getUsername(),
authorities.stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()));
} catch (Exception e) {
log.error("构建用户权限失败: {}", e.getMessage(), e);
// 发生异常时,至少保证基本角色权限
authorities.clear();
if ("0".equals(appUser.getUsertype())) {
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
} else {
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
}
}
return authorities;
}
}