【问题标题】:JSF "faces-redirect=true" redirects from https:// to http:// URL due to Apache ProxyPass由于 Apache ProxyPass,JSF“faces-redirect=true”从 https:// 重定向到 http:// URL
【发布时间】:2014-05-25 22:37:53
【问题描述】:
由于我有一个 Apache Webserver,它对 Glassfish 服务器执行 ProxyPass,后者不知道客户正在谈论“https”。
因此,当使用诸如
之类的东西时
return "shop.xhtml?faces-redirect=true";
生成的 HTTP Location: 标头包含一个“http://” URL。
我读过JSF redirects from HTTPS to HTTP,但发现这个解决方案不是很优雅。有没有办法告诉 Glassfish 这个或所有传入的请求都是 https,这样我就不必摆弄生成的导航规则?
【问题讨论】:
标签:
jsf
redirect
glassfish
java-ee-7
【解决方案1】:
您可以尝试添加一些可以在 java 端解释的请求标头,例如“X-redirect-to-https”。然后创建将包装 HttpServletResponse 的过滤器,并在该包装器中覆盖 sendRedirect 方法,以在存在“X-redirect-to-https”标头时将重定向 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;
}
}