You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 16:26:01