diff --git a/nginx_file b/nginx_file index 766d28f2..f1048044 100644 --- a/nginx_file +++ b/nginx_file @@ -5,6 +5,10 @@ server { proxy_pass http://localhost:8587; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Port $server_port; # CORS Headers if ($request_method = OPTIONS) { diff --git a/src/main/java/com/open/spring/security/JwtApiController.java b/src/main/java/com/open/spring/security/JwtApiController.java index 56d0e249..238438de 100644 --- a/src/main/java/com/open/spring/security/JwtApiController.java +++ b/src/main/java/com/open/spring/security/JwtApiController.java @@ -84,17 +84,15 @@ public ResponseEntity createAuthenticationToken(@RequestBody Person authentic return new ResponseEntity<>("Token generation failed", HttpStatus.INTERNAL_SERVER_ERROR); } - boolean secureFlag = cookieSecure && request.isSecure(); - String sameSite = secureFlag ? cookieSameSite : "Lax"; // Build cookie with development-friendly settings // For localhost: allow HTTP and SameSite=Lax // For production: require HTTPS and SameSite=None; Secure ResponseCookie tokenCookie = ResponseCookie.from("jwt_java_spring", token) .httpOnly(true) - .secure(secureFlag) + .secure(cookieSecure) .path("/api") .maxAge(cookieMaxAge) // Configured via jwt.cookie.max-age in application.properties - .sameSite(sameSite) + .sameSite(cookieSameSite) .build(); return ResponseEntity.ok().header(HttpHeaders.SET_COOKIE, tokenCookie.toString()).body(resolvedUid + " was authenticated successfully"); @@ -141,24 +139,21 @@ public String performLogout(Authentication authentication, HttpServletRequest re // Perform logout using SecurityContextLogoutHandler logoutHandler.logout(request, response, authentication); - boolean secureFlag = cookieSecure && request.isSecure(); - String sameSite = secureFlag ? cookieSameSite : "Lax"; - // Expire the JWT token immediately by setting a past expiration date ResponseCookie jwtCookie = ResponseCookie.from("jwt_java_spring", "") .httpOnly(true) - .secure(secureFlag) + .secure(cookieSecure) .path("/api") .maxAge(0) // Set maxAge to 0 to expire the cookie immediately - .sameSite(sameSite) + .sameSite(cookieSameSite) .build(); ResponseCookie sessionCookie = ResponseCookie.from(sessionCookieName, "") .httpOnly(true) - .secure(secureFlag) + .secure(cookieSecure) .path("/") .maxAge(0) - .sameSite(sameSite) + .sameSite(cookieSameSite) .build(); // Set the cookies in the response to effectively "remove" them diff --git a/src/main/java/com/open/spring/security/MvcSecurityConfig.java b/src/main/java/com/open/spring/security/MvcSecurityConfig.java index d7bc0f7a..a2c16ae6 100644 --- a/src/main/java/com/open/spring/security/MvcSecurityConfig.java +++ b/src/main/java/com/open/spring/security/MvcSecurityConfig.java @@ -121,14 +121,12 @@ public SecurityFilterChain mvcSecurityFilterChain(HttpSecurity http) throws Exce return; } - boolean secureFlag = cookieSecure && request.isSecure(); - String sameSite = secureFlag ? cookieSameSite : "Lax"; ResponseCookie jwtCookie = ResponseCookie.from("jwt_java_spring", token) .httpOnly(true) - .secure(secureFlag) + .secure(cookieSecure) .path("/api") .maxAge(-1) - .sameSite(sameSite) + .sameSite(cookieSameSite) .build(); response.addHeader(HttpHeaders.SET_COOKIE, jwtCookie.toString()); @@ -138,21 +136,19 @@ public SecurityFilterChain mvcSecurityFilterChain(HttpSecurity http) throws Exce .invalidateHttpSession(true) .clearAuthentication(true) .logoutSuccessHandler((request, response, authentication) -> { - boolean secureFlag = cookieSecure && request.isSecure(); - String sameSite = secureFlag ? cookieSameSite : "Lax"; ResponseCookie sessionCookie = ResponseCookie.from(sessionCookieName, "") .httpOnly(true) - .secure(secureFlag) + .secure(cookieSecure) .path("/") .maxAge(0) - .sameSite(sameSite) + .sameSite(cookieSameSite) .build(); ResponseCookie jwtCookie = ResponseCookie.from("jwt_java_spring", "") .httpOnly(true) - .secure(secureFlag) + .secure(cookieSecure) .path("/api") .maxAge(0) - .sameSite(sameSite) + .sameSite(cookieSameSite) .build(); response.addHeader(HttpHeaders.SET_COOKIE, sessionCookie.toString()); response.addHeader(HttpHeaders.SET_COOKIE, jwtCookie.toString()); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index c20183c9..4d2139b8 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -8,6 +8,10 @@ server.port=8585 socket.port=8589 socket.host=0.0.0.0 +# Trust X-Forwarded-* headers from reverse proxy (Nginx) +# Fixes Mixed Content errors: ensures request.isSecure()=true behind HTTPS proxy +server.forward-headers-strategy=framework + # Disable default error page server.error.whitelabel.enabled=false