// 定义包路径,用于存放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 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); // 清除缓存 } }