JSF "faces-redirect=true"从 https ://to http://URL due to Apache ProxyPass 重定向

标签 jsf redirect glassfish java-ee-7

由于我有一个 Apache Web 服务器,它对 Glassfish 服务器进行 ProxyPass,因此后者不知道客户正在谈论“https”。

因此,当使用诸如

之类的东西时
return "shop.xhtml?faces-redirect=true";

生成的 HTTP Location: header 包含“http://”URL。

我已阅读 JSF redirects from HTTPS to HTTP但发现这个解决方案不是很优雅。有没有办法告诉 Glassfish 这个或所有传入请求都是 https,这样我就不必摆弄生成的导航规则?

最佳答案

您可以尝试添加一些可以在java端解释的请求 header ,例如“X-redirect-to-https”。然后创建将包装 HttpServletResponse 的过滤器,并在该包装器中重写 sendRedirect 方法,以在存在“X-redirect-to-https” header 时将重定向 URL 中的 http 替换为 https。

代码(有点乱,但说明了解决方案)改编自: http://javahunter.wordpress.com/2011/06/01/why-does-https-become-http-on-a-sendredirect/

@WebFilter("/*")
public class HttpsSendRedirectFilter implements Filter {

   @Override
   public void init(FilterConfig filterConfig) throws ServletException {
   }

   @Override
   public void destroy() {
   }

   @Override
   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
         ServletException {
      chain.doFilter(request, new HttpsRedirectResponseWrapper((HttpServletRequest) request,
            (HttpServletResponse) response));
   }
}

public class HttpsRedirectResponseWrapper extends HttpServletResponseWrapper {

   private HttpServletRequest req;
   private String prefix = null;

   public HttpsRedirectResponseWrapper(HttpServletRequest req, HttpServletResponse res) {
      super(res);
      this.req = req;
      prefix = getPrefix(req);
   }

   @Override
   public void sendRedirect(String location) throws IOException {
      String finalurl = null;

      if (isUrlAbsolute(location)) {
         finalurl = location;
      } else {
         finalurl = fixForScheme(prefix + location);
      }
      super.sendRedirect(finalurl);
   }

   public boolean isUrlAbsolute(String url) {
      String lowercaseurl = url.toLowerCase();
      if (lowercaseurl.startsWith("http") == true) {
         return true;
      } else {
         return false;
      }
   }

   public String fixForScheme(String url) {
      if (this.req.getHeader("X-redirect-to-https") != null) {
         return url.replaceFirst("http", "https");
      } else {
         return url;
      }
   }

   public String getPrefix(HttpServletRequest request) {
      StringBuffer str = request.getRequestURL();
      String url = str.toString();
      String uri = request.getRequestURI();
      int offset = url.indexOf(uri);
      String prefix_t = url.substring(0, offset);
      return prefix_t;
   }
}

关于JSF "faces-redirect=true"从 https ://to http://URL due to Apache ProxyPass 重定向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23018248/

相关文章:

java - 重新加载 jsf 表单错误上的某个 jQuery 代码

javascript - 将 PWA 支持添加到 JSF Web 应用程序

python - 创建后的 Plone Archetypes 重定向

redirect - Nginx - 从 http ://to https://without www 正确重定向

eclipse - 创建 HK2 模块

JSF:数据更改后重新加载页面

jsf - 部分渲染仅适用于@form?

javascript - 从 iframe 内的脚本重定向整个页面的任何方法

java - Glassfish 在移动安装目录后挂起

ssl - AWS EIP To Load balancer 混淆了 XP 上的证书存储