403 Forbidden on login via browser when Spring Boot app runs from JAR, but works in IDE and...

Discussão em 'Angular' iniciado por Sergey Bazhukov, Maio 11, 2025.

  1. I'm facing an issue with my Spring Boot application. When I run the app directly from my IDE, everything works fine — I can log in from my Angular frontend (via POST /login) without any problems.

    However, after I package the app into a JAR file using mvn clean install and run it with java -jar my-app.jar, I get the following behavior:

    Logging in via Postman or Insomnia still works (POST request to /login returns token as expected).

    Logging in via the Angular frontend (in the browser) fails with a 403 Forbidden error.

    Backend logs show: HttpRequestMethodNotSupportedException: Request method 'GET' is not supported

    What I've checked:

    • CORS configuration in SecurityConfiguration allows http://localhost:4200 and includes POST method.

    http.csrf(AbstractHttpConfigurer::disable)
    .cors(cors -> cors.configurationSource(request -> {
    var corsConfiguration = new CorsConfiguration();
    corsConfiguration.setAllowedOriginPatterns(List.of("http://localhost:4200"));
    corsConfiguration.setAllowedMethods(List.of("GET","PATCH", "POST", "PUT", "DELETE", "OPTIONS"));
    corsConfiguration.setAllowedHeaders(List.of("Authorization", "Content-Type"));

    corsConfiguration.setAllowCredentials(true);
    return corsConfiguration;
    }))
    .authorizeHttpRequests(request -> request
    .requestMatchers("/","/login","/join").permitAll()
    .requestMatchers("/users").hasRole("ADMIN")
    .requestMatchers("/uploads/**").permitAll()
    .anyRequest().authenticated())
    .sessionManagement(manager -> manager.sessionCreationPolicy(STATELESS))
    .authenticationProvider(authenticationProvider())
    .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
    return http.build();
    }

    • Angular is sending a POST request to /login.

    this.dataService.log(true);
    return this.http.post<AuthResponse>(`${environment.baseURL}/login`, loginRequest
    )
    .pipe(
    tap((response: AuthResponse) => {
    if (response.token) {
    localStorage.setItem('jwtToken', response.token);
    }
    }),
    catchError(error => {
    console.error('Login error:', error);
    return throwError(() => new Error(error.error?.message || 'Login failed. Please try again.'));
    })
    );
    }

    • Angular interceptor:

    export const headerInterceptor: HttpInterceptorFn = (req: HttpRequest<unknown>,
    next: HttpHandlerFn
    ): Observable<HttpEvent<unknown>> => {
    const Authorization = localStorage.getItem('jwtToken') ? `Bearer ${localStorage.getItem('jwtToken')}` : '';
    if(!req.url.includes('login') && !req.url.includes('join'))
    return next(req.clone({ setHeaders: { Authorization } }));
    else
    return next(req);
    };

    • environment.prod.ts:

    export const environment = {
    production: true,
    baseURL: "http://localhost:8080",
    eventsURL: "http://localhost:8080/events",
    homeURL: "http://localhost:8080/home",
    citiesURL: "http://localhost:8080/cities",
    commentsURL: "http://localhost:8080/comments",
    usersURL: "http://localhost:8080/users"
    };

    • and in angular.json:

    "fileReplacements": [
    {
    "replace": "src/environments/environment.ts",
    "with": "src/environments/environment.prod.ts"
    }
    ]

    • in application.yml:

    profiles:
    active: prod

    • start .jar with

    java -jar my-app.jar --spring.profiles.active=prod


    • Works perfectly in IDE.


    • Fails only after running from the JAR.

    No apparent difference in logs or stack traces that explain why only browser requests fail.

    Question: What could cause Spring Boot to behave differently (especially for browser-based login requests) when running from a JAR versus running from the IDE?

    Any suggestions or debugging tips would be greatly appreciated!

    Thanks in advance

    Continue reading...

Compartilhe esta Página