package com.rongyichuang.auth.filter;
|
|
import com.rongyichuang.auth.util.JwtUtil;
|
import com.rongyichuang.user.entity.User;
|
import com.rongyichuang.user.repository.UserRepository;
|
import jakarta.servlet.FilterChain;
|
import jakarta.servlet.ServletException;
|
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletResponse;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
|
import org.springframework.stereotype.Component;
|
import org.springframework.web.filter.OncePerRequestFilter;
|
|
import java.io.IOException;
|
import java.util.ArrayList;
|
import java.util.Optional;
|
|
/**
|
* JWT认证过滤器
|
*/
|
@Component
|
public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
|
private static final Logger logger = LoggerFactory.getLogger(JwtAuthenticationFilter.class);
|
|
@Autowired
|
private JwtUtil jwtUtil;
|
|
@Autowired
|
private UserRepository userRepository;
|
|
@Override
|
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
|
FilterChain filterChain) throws ServletException, IOException {
|
System.out.println("=== JWT过滤器被调用 === URI: " + request.getRequestURI());
|
logger.debug("JWT过滤器开始处理请求: {}", request.getRequestURI());
|
|
String authHeader = request.getHeader("Authorization");
|
String token = null;
|
Long userId = null;
|
|
logger.debug("Authorization头: {}", authHeader);
|
|
// 从请求头中提取JWT token
|
if (authHeader != null && authHeader.startsWith("Bearer ")) {
|
token = authHeader.substring(7);
|
logger.debug("提取到JWT token: {}", token.substring(0, Math.min(20, token.length())) + "...");
|
try {
|
userId = jwtUtil.getUserIdFromToken(token);
|
logger.debug("从token中解析到用户ID: {}", userId);
|
} catch (Exception e) {
|
logger.error("JWT token解析失败: {}", e.getMessage(), e);
|
}
|
} else {
|
logger.debug("没有找到Authorization头或格式不正确");
|
}
|
|
// 如果token有效且当前是匿名或无认证,则进行认证
|
Authentication existingAuth = SecurityContextHolder.getContext().getAuthentication();
|
boolean isAnonymous = (existingAuth == null) || ("anonymousUser".equals(String.valueOf(existingAuth.getPrincipal())));
|
if (userId != null && isAnonymous) {
|
logger.debug("开始验证token有效性");
|
|
// 验证token是否有效
|
if (jwtUtil.validateToken(token)) {
|
logger.debug("Token验证成功,查找用户信息");
|
|
// 查找用户信息
|
Optional<User> userOpt = userRepository.findById(userId);
|
if (userOpt.isPresent()) {
|
User user = userOpt.get();
|
logger.debug("找到用户: userId={}, phone={}", user.getId(), user.getPhone());
|
|
// 创建认证对象
|
UsernamePasswordAuthenticationToken authToken =
|
new UsernamePasswordAuthenticationToken(
|
user.getId().toString(),
|
null,
|
new ArrayList<>() // 暂时不设置权限,后续可以根据角色设置
|
);
|
|
authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
SecurityContextHolder.getContext().setAuthentication(authToken);
|
|
logger.info("用户认证成功: userId={}, phone={}", user.getId(), user.getPhone());
|
} else {
|
logger.warn("用户不存在: userId={}", userId);
|
}
|
} else {
|
logger.warn("Token验证失败");
|
}
|
} else if (userId == null) {
|
logger.debug("没有解析到用户ID");
|
} else {
|
logger.debug("已存在非匿名认证信息,跳过JWT认证");
|
}
|
|
filterChain.doFilter(request, response);
|
}
|
}
|