Angular请求Spring Boot遇CORS及JWT认证异常排查求助
问题:Angular携带JWT请求Spring Boot接口遇CORS及Token获取失败问题
场景概述
我使用Angular向Spring Boot后端发送GET请求,通过HttpInterceptor在请求头中携带Bearer Token实现身份认证,但遇到CORS错误,且后端JwtFilter中始终无法获取到Authorization请求头。临时放开接口权限后虽解决了CORS问题,但接口无需认证即可访问,不符合需求。
Angular拦截器代码
@Injectable() export class AuthInterceptor implements HttpInterceptor { constructor() {} intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { const token = getCookieValue('token'); if (token) { const authRequest = request.clone({ setHeaders: { Authorization: `Bearer ${token}` } }); return next.handle(authRequest); } return next.handle(request); } }
浏览器返回CORS错误
Access to XMLHttpRequest at
'http://localhost:8080/api/user-profile/get-data' from origin
'http://localhost:4200' has been blocked by CORS policy: Response to
preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
Spring Boot安全配置代码
public class SecurityConfiguration implements WebMvcConfigurer { private final JwtFilter jwtFilter; private final DataSource dataSource; @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("http://localhost:4200") .allowedMethods("*"); } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.csrf(AbstractHttpConfigurer::disable); http.sessionManagement(sess -> sess.sessionAuthenticationStrategy(sessionAuthenticationStrategy())); http.authorizeHttpRequests(auth -> auth .requestMatchers("/", "/api/auth/oauth").authenticated() // 也试过配置"/api/user-profile/**" .requestMatchers("/", "/api/auth/**").permitAll() .anyRequest().authenticated() ); http.httpBasic(withDefaults()); http.oauth2Login(withDefaults()); http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class); return http.build(); } }
尝试过的临时解决方法(不符合需求)
发送不带Token的请求:
this.http.get(environment.apiBaseUrl + 'user-profile/get-data').subscribe(result => { console.log(result); })
同时修改Spring Boot权限配置,将/api/user-profile/**加入无需认证列表:
.requestMatchers("/", "/api/auth/**", "/api/user-profile/**").permitAll()
此操作消除了CORS错误,但接口失去认证限制,不符合需求。
JwtFilter代码(无法获取Authorization头)
@AllArgsConstructor @Component public class JwtFilter extends OncePerRequestFilter { private final CustomUserService customUserService; private Jwt jwt; @Override protected void doFilterInternal(HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull FilterChain filterChain) throws ServletException, IOException { final String authorizationHeader = request.getHeader("Authorization"); String token = null; String username = null; if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) { token = authorizationHeader.substring(7); // 校验Token有效性 try { jwt.isTokenValid(token, customUserService.loadUserByUsername(jwt.extractUsername(token))); } catch (Exception e) { Response responseObj = Response.builder() .code("UNAUTHORIZED") .status(HttpStatus.UNAUTHORIZED) .timestamp(LocalDateTime.now()) .messages(Collections.singletonList("Invalid token")) .build(); ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule()); String json = mapper.writeValueAsString(responseObj); response.setContentType("application/json"); response.setCharacterEncoding("UTF-8"); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.getWriter().write(json); return; } username = jwt.extractUsername(token); } if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { UserDetails userDetails = customUserService.loadUserByUsername(username); if (jwt.isTokenValid(token, userDetails)) { UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken); } } filterChain.doFilter(request, response); } }
核心问题
- 携带Token请求时触发CORS错误
- JwtFilter中
authorizationHeader始终为null - 需要实现仅已认证用户可访问
/api/user-profile/get-data接口的需求
内容的提问来源于stack exchange,提问作者xRay
相关产品推荐
相关产品推荐

