注册 Sa-Token 的注解拦截器
SaInterceptor是satoken提供的
@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {
// 注册 Sa-Token 拦截器,打开注解式鉴权功能
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册 Sa-Token 拦截器,打开注解式鉴权功能
registry.addInterceptor(new SaInterceptor()).addPathPatterns("/**");
}
}
实现 StpInterface 接口
StpInterface是satoken提供的接口
public interface StpInterface {
List<String> getPermissionList(Object var1, String var2);
List<String> getRoleList(Object var1, String var2);
}
自己重写接口的两个方法
@Component
public class StpInterfaceImpl implements StpInterface {
@Resource
private AuthFeignService authFeignService;
@Override
public List<String> getPermissionList(Object loginId, String loginType) {
SaSession saSession = StpUtil.getSessionByLoginId(loginId, false);
UserVO userVO;
// 先查缓存,缓存不存在再通过feign查询
if (saSession == null || (userVO = saSession.getModel(SystemConstants.USER, UserVO.class)) == null) {
// 返回此 loginId 拥有的权限列表
CommonResult<UserVO> feignResult = authFeignService.getUserInfoById((Integer.valueOf(loginId.toString())));
if (feignResult.getCode() != HttpStatus.SUCCESS || (userVO = feignResult.getData()) == null) {
return null;
}
}
return userVO.getPermissions().stream().map(Permission::getPermissionLabel).collect(Collectors.toList());
}
@Override
public List<String> getRoleList(Object loginId, String loginType) {
SaSession saSession = StpUtil.getSessionByLoginId(loginId, false);
UserVO userVO;
// 先查缓存,缓存不存在再通过feign查询
if (saSession == null || (userVO = saSession.getModel(SystemConstants.USER, UserVO.class)) == null) {
// 返回此 loginId 拥有的角色列表
CommonResult<UserVO> feignResult = authFeignService.getUserInfoById(Integer.valueOf(loginId.toString()));
if (feignResult.getCode() != HttpStatus.SUCCESS || (userVO = feignResult.getData()) == null) {
return null;
}
}
return userVO.getRoles().stream().map(Role::getRoleCode).collect(Collectors.toList());
}
}
具体实现
AuthFeignService.getUserInfoById UserInfoProvider
@RequestMapping("/getUserInfoById")
public CommonResult<UserVO> getUserInfoById(@RequestParam Integer userId) {
UserVO userVO = userAuthService.findUserById(userId);
return CommonResult.ok("用户信息查询成功", userVO);
}
UserConvert.user2VO
roleSet和permissionSet
public static UserVO user2VO(User user) {
if (user == null) {
return null;
} else {
UserVO userVO = new UserVO();
userVO.setId(user.getId());
userVO.setUsername(user.getUsername());
userVO.setNickname(user.getNickname());
userVO.setEmail(user.getEmail());
userVO.setAvatar(user.getAvatar());
userVO.setCreateDate(user.getCreateDate());
userVO.setLastLoginDate(user.getLastLoginDate());
userVO.setLastLoginIp(user.getLastLoginIp());
userVO.setLastLoginLocation(user.getLastLoginLocation());
userVO.setState(user.getState());
userVO.setInit(user.getInit());
Set<Role> roleSet = new HashSet<>();
List<Role> userRoles = user.getRoles();
if (!CollectionUtil.isEmpty(userRoles)) {
roleSet.addAll(userRoles);
}
List<Group> groups = user.getGroups();
// 用户组角色转移到用户角色中并删除重复角色
if (!CollectionUtil.isEmpty(groups)) {
for (Group group : groups) {
roleSet.addAll(group.getGroupRoles());
group.setGroupRoles(null);
}
}
List<Role> roles = new ArrayList<>(roleSet);
userVO.setGroups(groups);
userVO.setThirdPlatforms(user.getThirdPlatforms());
// 用户组权限转移到用户权限中并删除重复权限
Set<Permission> permissionSet = new HashSet<>();
if (!CollectionUtil.isEmpty(roles)) {
for (Role role : roleSet) {
permissionSet.addAll(role.getPermissions());
role.setPermissions(null);
}
}
userVO.setRoles(roles);
userVO.setPermissions(new ArrayList<>(permissionSet));
return userVO;
}
}
UserMapper.findUserById
@Select("select id, username, password, nickname, email, ifnull(last_login_date, 0) last_login_date," +
"inet_ntoa(last_login_ip) last_login_ip, last_login_location, avatar, state, init from user " +
"where username = #{username} and deleted = 0")
@Results(id = "userInfoMap", value = {
@Result(column = "id", property = "id", javaType = Integer.class),
@Result(column = "username", property = "username", javaType = String.class),
@Result(column = "password", property = "password", javaType = String.class),
@Result(column = "nickname", property = "nickname", javaType = String.class),
@Result(column = "email", property = "email", javaType = String.class),
@Result(column = "last_login_date", property = "lastLoginDate", javaType = String.class),
@Result(column = "last_login_ip", property = "lastLoginIp", javaType = String.class),
@Result(column = "last_login_location", property = "lastLoginLocation", javaType = String.class),
@Result(column = "avatar", property = "avatar", javaType = String.class),
@Result(column = "state", property = "state", javaType = Short.class),
@Result(column = "init", property = "init", javaType = Short.class),
@Result(column = "id", property = "roles", javaType = List.class,
many = @Many(select = "com.afs.springcloud.auth.mapper.RoleMapper.findRolesByUserId")),
@Result(column = "id", property = "groups", javaType = List.class,
many = @Many(select = "com.afs.springcloud.auth.mapper.GroupMapper.findGroupsByUserId")),
@Result(column = "id", property = "thirdPlatforms", javaType = List.class,
many = @Many(select = "com.afs.springcloud.auth.mapper.ThirdPartyUserMapper.findPlatformsByUserId")),
})
User findUserByName(String username);
@Select("select id, username, nickname, email, ifnull(last_login_date, 0) last_login_date, " +
"inet_ntoa(last_login_ip) last_login_ip, last_login_location, avatar, state, init " +
"from user where id = #{id} and deleted = 0")
@ResultMap(value = "userInfoMap")
User findUserById(int id);
在controller方法上使用注解约束权限
@SaCheckPermission(value = "system:user:add", orRole = "admin")
其中
value = "system:user:add"
用于标识不同的操作;
orRole = "admin"
表示如果当前用户没有 "system:user:add" 权限,则会检查当前用户是否拥有 "admin" 角色。
在方法执行前进行权限检查。如果当前用户拥有 "system:user:add" 权限,则可以继续执行方法;如果当前用户没有该权限,则会进一步检查是否拥有 "admin" 角色。只有当用户满足其中之一(拥有权限或者拥有角色)时,方法才会被执行。