import com.shareaccount.backend.util.JwtTokenHelper;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.UnsupportedJwtException;
import io.jsonwebtoken.security.SignatureException;
import io.micrometer.common.util.StringUtils;
import jakarta.annotation.Resource;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.AuthenticationEntryPoint;
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.Objects;
@Component
@Slf4j
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Resource
JwtTokenHelper jwtTokenHelper;
@Resource
UserDetailsService userDetailsService;
@Resource
AuthenticationEntryPoint authenticationEntryPoint;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
final String authHeader = request.getHeader("Authorization");
final String jwt;
final String userEmail;
log.info("[JWT验证] 进入JWTFilter");
// 以下條件為沒有攜帶Token的請求
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
log.info("[JWT验证] 鉴定为不含Token请求");
filterChain.doFilter(request, response);
return;
} jwt = authHeader.substring(7);
log.info("[JWT验证] 携带Token请求接受到一个" + jwt);
try {
jwtTokenHelper.validateToken(jwt);
}catch (SignatureException | MalformedJwtException | UnsupportedJwtException | IllegalArgumentException e) {
// 抛出异常,统一让 AuthenticationEntryPoint 处理响应参数
authenticationEntryPoint.commence(request, response, new AuthenticationServiceException("Token 不可用"));
return;
} catch (ExpiredJwtException e) {
authenticationEntryPoint.commence(request, response, new AuthenticationServiceException("Token 已失效"));
return;
}
String username = jwtTokenHelper.getUsernameByToken(jwt);
if(StringUtils.isNotBlank(username) && Objects.isNull(SecurityContextHolder.getContext().getAuthentication())) {
log.info("[JWT验证] 解析得到username: " + username);
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}
filterChain.doFilter(request, response);
}}