反向代理下HAL Browser重定向失效问题求助
Let's break down why your redirect isn't working and how to fix it. The core problem here is that when running behind a reverse proxy, your Spring Data REST app doesn't have visibility into the external URL (the one users are actually accessing) by default. The HalBrowser.java component is generating redirects using the internal server's hostname/port (like localhost:8080) instead of the proxy's public address, which breaks the redirect flow.
Here are the step-by-step solutions to resolve this:
1. Configure Spring Boot to Respect Forwarded Headers
First, tell your Spring Boot app to use the headers sent by the reverse proxy to build correct external URLs. Add this to your application.properties (or equivalent YAML):
# For Spring Boot 2.2+ server.forward-headers-strategy=framework # For older Spring Boot versions (pre-2.2) # server.use-forward-headers=true
This setting makes Spring MVC honor headers like X-Forwarded-Proto, X-Forwarded-Host, and X-Forwarded-Port that the reverse proxy sends. These headers contain the actual protocol, hostname, and port users are using to access your app.
2. Ensure Your Reverse Proxy Sends the Correct Forwarded Headers
Your proxy server needs to pass these headers to your app. Here's how to configure common proxies:
Nginx Example
Add these lines to your location block that proxies to your Spring app:
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Port $server_port; proxy_set_header X-Forwarded-For $remote_addr;
Apache Example
Make sure mod_headers and mod_proxy are enabled, then add:
RequestHeader set X-Forwarded-Proto "https" RequestHeader set X-Forwarded-Host "your-public-domain.com" RequestHeader set X-Forwarded-Port "443"
Adjust the values to match your actual public protocol, domain, and port.
3. Customize the HAL Browser Redirect Logic (If Needed)
If the above settings don't fix the issue, you can override the default HalBrowser behavior to explicitly build the correct redirect URL. Create a custom controller that handles the /app endpoint and returns a properly constructed redirect:
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.servlet.view.RedirectView; import javax.servlet.http.HttpServletRequest; @Controller public class CustomHalBrowserRedirect { @GetMapping("/app") public RedirectView redirectToHalBrowser(HttpServletRequest request) { // Build the base URL using proxy-aware request details String baseUrl = String.format("%s://%s:%s/app", request.getScheme(), request.getServerName(), request.getServerPort()); String redirectUrl = baseUrl + "/browser/index.html#" + baseUrl; return new RedirectView(redirectUrl); } }
This code uses HttpServletRequest (which now has proxy-aware values thanks to step 1) to build the exact redirect URL users need.
4. Verify the Redirect URL
To debug, you can log the request details in your app to confirm it's receiving the correct forwarded headers. Add a quick logger in your controller or filter:
logger.info("Request URL: {}", request.getRequestURL()); logger.info("X-Forwarded-Host: {}", request.getHeader("X-Forwarded-Host")); logger.info("X-Forwarded-Proto: {}", request.getHeader("X-Forwarded-Proto"));
If these logs show your public domain instead of localhost, you know the headers are being picked up correctly.
内容的提问来源于stack exchange,提问作者codesmith

