|
|
// 定义包路径,用于存放Shiro领域相关的类
|
|
|
package com.yf.exam.ability.shiro;
|
|
|
|
|
|
import com.yf.exam.ability.shiro.jwt.JwtToken; // JWT令牌类
|
|
|
import com.yf.exam.ability.shiro.jwt.JwtUtils; // JWT工具类
|
|
|
import com.yf.exam.modules.sys.user.dto.response.SysUserLoginDTO; // 用户登录DTO
|
|
|
import com.yf.exam.modules.sys.user.service.SysUserRoleService; // 用户角色服务
|
|
|
import com.yf.exam.modules.sys.user.service.SysUserService; // 用户服务
|
|
|
import lombok.extern.slf4j.Slf4j; // 日志注解
|
|
|
import org.apache.shiro.authc.AuthenticationException; // 认证异常
|
|
|
import org.apache.shiro.authc.AuthenticationInfo; // 认证信息
|
|
|
import org.apache.shiro.authc.AuthenticationToken; // 认证令牌
|
|
|
import org.apache.shiro.authc.SimpleAuthenticationInfo; // 简单认证信息
|
|
|
import org.apache.shiro.authz.AuthorizationInfo; // 授权信息
|
|
|
import org.apache.shiro.authz.SimpleAuthorizationInfo; // 简单授权信息
|
|
|
import org.apache.shiro.realm.AuthorizingRealm; // 授权领域
|
|
|
import org.apache.shiro.subject.PrincipalCollection; // 主体集合
|
|
|
import org.springframework.beans.factory.annotation.Autowired; // Spring自动注入注解
|
|
|
import org.springframework.context.annotation.Lazy; // 延迟注入注解
|
|
|
import org.springframework.stereotype.Component; // Spring组件注解
|
|
|
|
|
|
import java.util.HashSet; // 哈希集合
|
|
|
import java.util.List; // 列表
|
|
|
|
|
|
/**
|
|
|
* 用户登录鉴权和获取用户授权的Shiro领域类
|
|
|
* 负责用户的认证和授权,是Shiro框架中的核心组件之一。
|
|
|
* @author bool
|
|
|
*/
|
|
|
@Component // 标记为Spring组件
|
|
|
@Slf4j // 启用Slf4j日志
|
|
|
public class ShiroRealm extends AuthorizingRealm {
|
|
|
|
|
|
@Autowired
|
|
|
@Lazy // 延迟注入,避免循环依赖
|
|
|
private SysUserService sysUserService; // 用户服务
|
|
|
|
|
|
@Autowired
|
|
|
@Lazy // 延迟注入,避免循环依赖
|
|
|
private SysUserRoleService sysUserRoleService; // 用户角色服务
|
|
|
|
|
|
/**
|
|
|
* 判断是否支持JWT令牌
|
|
|
* 确定当前领域是否支持处理JWT令牌类型的认证。
|
|
|
* @param token 认证令牌
|
|
|
* @return 是否支持JWT令牌
|
|
|
*/
|
|
|
@Override
|
|
|
public boolean supports(AuthenticationToken token) {
|
|
|
// 判断是否支持JWT令牌
|
|
|
return token instanceof JwtToken; // 返回是否为JwtToken
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 详细授权认证
|
|
|
* 获取用户的授权信息,包括角色和权限。
|
|
|
* @param principals 主体集合
|
|
|
* @return 授权信息
|
|
|
*/
|
|
|
@Override
|
|
|
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
|
|
|
String userId = null; // 用户ID
|
|
|
if (principals != null) {
|
|
|
SysUserLoginDTO user = (SysUserLoginDTO) principals.getPrimaryPrincipal(); // 获取用户信息
|
|
|
userId = user.getId(); // 获取用户ID
|
|
|
}
|
|
|
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); // 创建授权信息
|
|
|
|
|
|
// 查找用户角色
|
|
|
List<String> roles = sysUserRoleService.listRoles(userId); // 获取用户角色列表
|
|
|
info.setRoles(new HashSet<>(roles)); // 设置角色
|
|
|
|
|
|
log.info("++++++++++校验详细权限完成"); // 日志记录
|
|
|
return info; // 返回授权信息
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 校验用户的账号密码是否正确
|
|
|
* 根据传入的认证令牌,验证用户的账号密码。
|
|
|
* @param auth 认证令牌
|
|
|
* @return 认证信息
|
|
|
* @throws AuthenticationException 认证异常
|
|
|
*/
|
|
|
@Override
|
|
|
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
|
|
|
String token = (String) auth.getCredentials(); // 获取token
|
|
|
if (token == null) {
|
|
|
throw new AuthenticationException("token为空!"); // 抛出异常
|
|
|
}
|
|
|
|
|
|
// 校验token有效性
|
|
|
SysUserLoginDTO user = this.checkToken(token); // 验证token并获取用户信息
|
|
|
return new SimpleAuthenticationInfo(user, token, getName()); // 返回认证信息
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 校验Token的有效性
|
|
|
* 验证JWT令牌的有效性,并获取对应的用户信息。
|
|
|
* @param token JWT令牌
|
|
|
* @return 用户登录DTO
|
|
|
* @throws AuthenticationException 认证异常
|
|
|
*/
|
|
|
public SysUserLoginDTO checkToken(String token) throws AuthenticationException {
|
|
|
// 查询用户信息
|
|
|
log.debug("++++++++++校验用户token: "+ token); // 日志记录
|
|
|
|
|
|
// 从token中获取用户名
|
|
|
String username = JwtUtils.getUsername(token); // 获取用户名
|
|
|
log.debug("++++++++++用户名: "+ username); // 日志记录
|
|
|
|
|
|
if (username == null) {
|
|
|
throw new AuthenticationException("无效的token"); // 抛出异常
|
|
|
}
|
|
|
|
|
|
// 查找登录用户对象
|
|
|
SysUserLoginDTO user = sysUserService.token(token); // 获取用户信息
|
|
|
|
|
|
// 校验token是否失效
|
|
|
if (!JwtUtils.verify(token, username)) {
|
|
|
throw new AuthenticationException("登陆失效,请重试登陆!"); // 抛出异常
|
|
|
}
|
|
|
|
|
|
return user; // 返回用户信息
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 清除当前用户的权限认证缓存
|
|
|
* 用于在用户信息变更后,清除缓存,确保权限信息的更新。
|
|
|
* @param principals 主体集合
|
|
|
*/
|
|
|
@Override
|
|
|
public void clearCache(PrincipalCollection principals) {
|
|
|
super.clearCache(principals); // 清除缓存
|
|
|
}
|
|
|
} |