后端注释添加日期人员划分
This commit is contained in:
@@ -24,14 +24,27 @@ import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* Shiro自定义Realm实现
|
||||
* <p>
|
||||
* 继承AuthorizingRealm,实现两个核心职责:
|
||||
* 1. 认证(Authentication):通过doGetAuthenticationInfo校验用户JWT Token的合法性
|
||||
* 2. 授权(Authorization):通过doGetAuthorizationInfo加载用户的角色和权限信息
|
||||
* </p>
|
||||
* <p>
|
||||
* 当JwtFilter调用Subject.login()时,Shiro框架会自动调用本类中的认证和授权方法。
|
||||
* </p>
|
||||
*
|
||||
* @Description 描述:用户登录鉴权和获取用户授权
|
||||
* @Author A贾宇婷034244310
|
||||
* @Date 20260615
|
||||
* @Date 20260616
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ShiroRealm extends AuthorizingRealm {
|
||||
|
||||
/**
|
||||
* 使用@Lazy延迟注入,避免Shiro在Spring容器初始化阶段过早依赖Service Bean导致循环依赖
|
||||
*/
|
||||
@Autowired
|
||||
@Lazy
|
||||
private SysUserService sysUserService;
|
||||
@@ -41,6 +54,16 @@ public class ShiroRealm extends AuthorizingRealm {
|
||||
private SysUserRoleService sysUserRoleService;
|
||||
|
||||
|
||||
/**
|
||||
* 声明当前Realm支持的Token类型
|
||||
* <p>
|
||||
* Shiro框架通过此方法判断是否将Token交给当前Realm处理。
|
||||
* 仅当Token为JwtToken类型时,才会调用本Realm的认证/授权方法。
|
||||
* </p>
|
||||
*
|
||||
* @param token Shiro认证令牌
|
||||
* @return true-当前Realm支持该Token类型;false-不支持
|
||||
*/
|
||||
@Override
|
||||
public boolean supports(AuthenticationToken token) {
|
||||
return token instanceof JwtToken;
|
||||
@@ -48,22 +71,29 @@ public class ShiroRealm extends AuthorizingRealm {
|
||||
|
||||
|
||||
/**
|
||||
* 详细授权认证
|
||||
* @param principals
|
||||
* @return
|
||||
* 授权认证:加载当前用户的角色和权限信息
|
||||
* <p>
|
||||
* 当请求中使用了@RequiresRoles、@RequiresPermissions等Shiro注解时,
|
||||
* Shiro框架会自动调用此方法获取用户的授权信息,用于后续的权限判断。
|
||||
* </p>
|
||||
*
|
||||
* @param principals 用户主体集合,包含认证成功后存储的用户信息(SysUserLoginDTO)
|
||||
* @return 包含用户角色和权限的授权信息对象
|
||||
*/
|
||||
@Override
|
||||
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
|
||||
|
||||
String userId = null;
|
||||
if (principals != null) {
|
||||
// 从主体集合中获取认证时存储的用户登录信息
|
||||
SysUserLoginDTO user = (SysUserLoginDTO) principals.getPrimaryPrincipal();
|
||||
userId = user.getId();
|
||||
}
|
||||
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
|
||||
|
||||
// 查找用户角色
|
||||
// 根据用户ID查询该用户拥有的所有角色列表
|
||||
List<String> roles = sysUserRoleService.listRoles(userId);
|
||||
// 将角色列表设置到授权信息中,供Shiro进行角色权限校验
|
||||
info.setRoles(new HashSet<>(roles));
|
||||
|
||||
log.info("++++++++++校验详细权限完成");
|
||||
@@ -71,47 +101,65 @@ public class ShiroRealm extends AuthorizingRealm {
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验用户的账号密码是否正确
|
||||
* @param auth
|
||||
* @return
|
||||
* @throws AuthenticationException
|
||||
* 身份认证:校验用户提交的JWT Token是否合法
|
||||
* <p>
|
||||
* 当JwtFilter调用Subject.login(jwtToken)时,Shiro框架会回调此方法。
|
||||
* 方法内部提取Token中的用户信息并校验Token有效性,
|
||||
* 返回的SimpleAuthenticationInfo中principal为用户对象,credentials为原始Token字符串。
|
||||
* </p>
|
||||
*
|
||||
* @param auth 认证令牌,包含用户提交的JWT Token(通过getCredentials()获取)
|
||||
* @return 认证信息对象,包含用户主体(principal)和凭证(credentials)
|
||||
* @throws AuthenticationException 当Token为空或校验失败时抛出
|
||||
*/
|
||||
@Override
|
||||
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
|
||||
// 从认证令牌中提取JWT Token字符串(JwtToken的getCredentials()返回的是Token字符串)
|
||||
String token = (String) auth.getCredentials();
|
||||
if (token == null) {
|
||||
throw new AuthenticationException("token为空!");
|
||||
}
|
||||
|
||||
// 校验token有效性
|
||||
// 校验Token有效性:解析用户名、查询用户信息、验证Token签名和过期时间
|
||||
SysUserLoginDTO user = this.checkToken(token);
|
||||
// 构造认证信息:user作为principal(后续可通过Subject.getPrincipal()获取),
|
||||
// token作为credentials,getName()返回当前Realm名称
|
||||
return new SimpleAuthenticationInfo(user, token, getName());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 校验Token的有效性
|
||||
* @param token
|
||||
* @return
|
||||
* @throws AuthenticationException
|
||||
* 校验JWT Token的有效性
|
||||
* <p>
|
||||
* Token校验流程分为三步:
|
||||
* 1. 从Token中解析用户名(JWT Payload部分)
|
||||
* 2. 根据用户名从数据库中查询用户信息
|
||||
* 3. 验证Token的签名和过期时间
|
||||
* 任一步骤失败都会抛出AuthenticationException异常。
|
||||
* </p>
|
||||
*
|
||||
* @param token JWT Token字符串
|
||||
* @return 校验通过后返回的用户登录信息DTO
|
||||
* @throws AuthenticationException 当Token无效、用户不存在或Token已过期时抛出
|
||||
*/
|
||||
public SysUserLoginDTO checkToken(String token) throws AuthenticationException {
|
||||
|
||||
// 查询用户信息
|
||||
log.debug("++++++++++校验用户token: "+ token);
|
||||
|
||||
// 从token中获取用户名
|
||||
// 第一步:从JWT Token的Payload中解析出用户名
|
||||
String username = JwtUtils.getUsername(token);
|
||||
log.debug("++++++++++用户名: "+ username);
|
||||
|
||||
// 解析失败说明Token格式不正确或已损坏
|
||||
if (username == null) {
|
||||
throw new AuthenticationException("无效的token");
|
||||
}
|
||||
|
||||
// 查找登录用户对象
|
||||
// 第二步:根据用户名从数据库中查找对应的用户登录信息
|
||||
SysUserLoginDTO user = sysUserService.token(token);
|
||||
|
||||
// 校验token是否失效
|
||||
// 第三步:校验Token的签名完整性和是否已过期
|
||||
if (!JwtUtils.verify(token, username)) {
|
||||
throw new AuthenticationException("登陆失效,请重试登陆!");
|
||||
}
|
||||
@@ -122,8 +170,13 @@ public class ShiroRealm extends AuthorizingRealm {
|
||||
|
||||
|
||||
/**
|
||||
* 清除当前用户的权限认证缓存
|
||||
* @param principals
|
||||
* 清除指定用户的认证/授权缓存
|
||||
* <p>
|
||||
* 当用户信息发生变更(如角色调整、权限修改)时,可调用此方法
|
||||
* 清除该用户在Shiro中的缓存,使下次请求时重新执行认证和授权逻辑。
|
||||
* </p>
|
||||
*
|
||||
* @param principals 待清除缓存的用户主体标识集合
|
||||
*/
|
||||
@Override
|
||||
public void clearCache(PrincipalCollection principals) {
|
||||
|
||||
@@ -14,42 +14,70 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
||||
/**
|
||||
* JWT认证过滤器
|
||||
* <p>
|
||||
* 作为Shiro过滤链中的核心认证组件,拦截所有需要鉴权的HTTP请求。
|
||||
* 工作流程:从请求头中提取JWT Token -> 封装为JwtToken对象 -> 提交给ShiroRealm进行认证。
|
||||
* 继承BasicHttpAuthenticationFilter以融入Shiro的过滤器链机制。
|
||||
* </p>
|
||||
*
|
||||
* @Description 描述:鉴权登录拦截器
|
||||
* @Author A贾宇婷034244310
|
||||
* @Date 20260615
|
||||
* @Date 20260616
|
||||
*/
|
||||
@Slf4j
|
||||
public class JwtFilter extends BasicHttpAuthenticationFilter {
|
||||
|
||||
/**
|
||||
* 执行登录认证
|
||||
* @param request
|
||||
* @param response
|
||||
* @param mappedValue
|
||||
* @return
|
||||
* 判断当前请求是否允许访问(Shiro过滤器链的入口方法)
|
||||
* <p>
|
||||
* Shiro在处理每个请求时会调用此方法来决定是否放行。
|
||||
* 内部调用executeLogin完成JWT认证,认证成功则放行,失败则返回统一错误响应。
|
||||
* </p>
|
||||
*
|
||||
* @param request 当前HTTP请求对象
|
||||
* @param response 当前HTTP响应对象
|
||||
* @param mappedValue 过滤器链中配置的权限标识(如perms、roles等),此处未使用
|
||||
* @return true-认证通过,允许访问;false-认证失败,拒绝访问
|
||||
*/
|
||||
@Override
|
||||
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
|
||||
try {
|
||||
// 尝试执行JWT登录认证流程
|
||||
executeLogin(request, response);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
// 写出统一错误信息
|
||||
// 认证失败时,向客户端写出统一的错误响应信息(如401未授权)
|
||||
InjectUtils.restError((HttpServletResponse) response);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 执行JWT登录认证
|
||||
* <p>
|
||||
* 从HTTP请求头中提取JWT Token,封装为Shiro可识别的JwtToken对象,
|
||||
* 然后提交给Shiro的Subject进行登录。Shiro会将JwtToken传递给ShiroRealm的
|
||||
* doGetAuthenticationInfo方法完成实际的身份校验。
|
||||
* </p>
|
||||
*
|
||||
* @param request 当前HTTP请求对象,用于获取Token请求头
|
||||
* @param response 当前HTTP响应对象
|
||||
* @return true-登录成功;若登录失败则抛出异常由上层捕获
|
||||
* @throws Exception 当Token无效或认证失败时抛出异常
|
||||
*/
|
||||
@Override
|
||||
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
|
||||
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
|
||||
// 从请求头中获取JWT Token(Token字段名定义在Constant.TOKEN常量中)
|
||||
String token = httpServletRequest.getHeader(Constant.TOKEN);
|
||||
|
||||
// 将原始Token字符串封装为Shiro的认证令牌对象
|
||||
JwtToken jwtToken = new JwtToken(token);
|
||||
// 提交给realm进行登入,如果错误他会抛出异常并被捕获
|
||||
// 提交给ShiroRealm进行身份认证,如果Token无效,Realm会抛出AuthenticationException
|
||||
getSubject(request, response).login(jwtToken);
|
||||
// 如果没有抛出异常则代表登入成功,返回true
|
||||
// 如果没有抛出异常则代表认证成功,返回true放行
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@ import lombok.Data;
|
||||
import org.apache.shiro.authc.AuthenticationToken;
|
||||
|
||||
/**
|
||||
* @Description 描述:
|
||||
* @Description 描述:* @Author A贾宇婷034244310
|
||||
* @Author A贾宇婷034244310
|
||||
* @Date 20260615
|
||||
* @Date 20260616
|
||||
*/
|
||||
@Data
|
||||
public class JwtToken implements AuthenticationToken {
|
||||
|
||||
@@ -13,7 +13,7 @@ import java.util.Date;
|
||||
/**
|
||||
* @Description 描述:JWT工具类
|
||||
* @Author A贾宇婷034244310
|
||||
* @Date 20260615
|
||||
* @Date 20260616
|
||||
*/
|
||||
public class JwtUtils {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user