Springboot Backend receives jwt from Angular Fetch request, but not HttpClient {...

Discussão em 'Angular' iniciado por Josef Creations, Março 27, 2025.

  1. I am developing a Springboot/Angular application. I am running into an annoying issue where my backend is able to receive and parse credentials (in this case, a jwt) from fetch requests but is not receiving the same credentials when I try to use the HttpClient api.

    Here are some brief examples of the two different requests:

    this.httpClient.get('http://localhost:8080/api/route', {
    withCredentials: true,
    headers: { 'Content-Type': 'application/json' }
    });

    fetch('http://localhost:8080/api/route', {
    method: 'GET',
    headers: { 'Accept': 'application/json' },
    credentials: 'include'
    });


    Now, in my app.config.ts I do have this line:

    provideHttpClient(withFetch()),


    However, the angular docs say to set withFetch there in SSR apps. I have tried to remove that, or add withOptions([withCredentials: true]) - but the results are the same.

    I have tried a number of things, and since nothing I am doing in angular seems blatantly wrong (it very well could be, please tell me if you see something that is wrong), I started taking a look at my Springboot cors/security configurations:

    Security Configuration:

    @Configuration
    public class SecurityConfig {

    private final FirebaseAuthFilter firebaseAuthFilter;

    public SecurityConfig(FirebaseAuthFilter firebaseAuthFilter) {
    this.firebaseAuthFilter = firebaseAuthFilter;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http, CorsConfigurationSource corsConfigurationSource) throws Exception {
    http.cors(cors -> cors.configurationSource(corsConfigurationSource))
    .csrf(AbstractHttpConfigurer::disable)
    .authorizeHttpRequests(auth -> auth
    .requestMatchers(PUBLIC_ENDPOINTS).permitAll()
    .anyRequest().authenticated()
    )
    .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
    .addFilterBefore(firebaseAuthFilter, UsernamePasswordAuthenticationFilter.class);

    return http.build();
    }
    }


    Firebase Filter (I have messed with this a significant amount, but this configuration successfully passes the jwt to the rest of the backend when FETCH requests are sent, so I do not think this is the issue):

    @Component
    public class FirebaseAuthFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
    throws ServletException, IOException {
    String token = request.getHeader("Authorization");

    if (token != null && token.startsWith("Bearer ")) {
    try {
    FirebaseToken decodedToken = FirebaseAuth.getInstance().verifyIdToken(token.substring(7));
    UserDetails userDetails = new User(decodedToken.getUid(), "", Collections.emptyList());

    SecurityContextHolder.getContext().setAuthentication(
    new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()));
    } catch (Exception e) {
    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    return;
    }
    }
    chain.doFilter(request, response);
    }
    }


    and my Cors Configuration:

    @Configuration
    public class CorsConfig {

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();

    configuration.setAllowCredentials(true);
    configuration.setAllowedOriginPatterns(List.of("http://localhost:4200"));
    configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
    configuration.setAllowedHeaders(List.of("Authorization", "Content-Type", "X-Requested-With"));
    configuration.setExposedHeaders(List.of("Set-Cookie"));

    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);

    return source;
    }
    }


    My JWT is set as httpOnly, with SameSite as lax (I have tried both None and Strict, to no avail), and I can see it as such in the browser, so I know that the cookie is being set properly.

    If I have provided too little information, please do ask for what you think you need to answer the question. I am somewhat experienced, but this is my first time going solo with writing the foundations for an app like this. Thank you.

    Continue reading...

Compartilhe esta Página