-
1. Re: infinite redirect loop using apache proxy to weblogic and scheme="https"
bmhardy Apr 2, 2012 7:01 PM (in response to bmhardy)I figured out how to get this work. If you have a configuration with an Apache proxy and a weblogic application server using SEAM and you would like to make
use of the the SEAM scheme settings to force pages to use https or http follow these steps.
1. Make Apache forward to weblogic - You can read about this elsewhere and get this going separately but here are some notes.
A. Get the weblogic apache module and turn it on in the Apache httpd.conf file with this line.
LoadModule weblogic_module modules/mod_wl_22.so
B. Make apache forward to requests to weblogic for http. Edit the Apache httpd.conf file and add lines similar to these
RedirectMatch ^/$ /portal
RedirectMatch ^/ourwebsite/pub/main$ /portal
<Location /portal>
SetHandler weblogic-handler
WebLogicHost hostmachine.yourdomain.com
WebLogicPort 7001
</Location>
C. Turn on SSL in apache forward requests to weblogic for https. Edit the Apache httpd.conf file and add/modify lines similar to these
LoadModule ssl_module modules/mod_ssl.so
# Secure (SSL/TLS) connections
Include conf/httpd-ssl.conf
#
# Note: The following must must be present to support
# starting without SSL on platforms with no /dev/random equivalent
# but a statically compiled-in mod_ssl.
#
<IfModule ssl_module>
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
</IfModule>
After you have Apache successfully forwarding requests to weblogic you can follow these steps to make SEAM scheme settings work with a proxy.
1. In the Apache httpd.conf file turn the mod headers module on with the following line.
LoadModule headers_module modules/mod_headers.so
2. In the Apache httpd.conf file indicate that the request was forwarded with http by adding the following line.
RequestHeader set X-Forwarded-Proto "http"
3. In the Apache httpd-ssl.conf file indicate that the request was forwarded with https by adding the following line after <VirtualHost _default_:443>
RequestHeader set X-Forwarded-Proto "https"
4. In pages.xml set the port numbers that the proxy expects to use. Even if you are using the standard port numbers of 80 for http and 443 for https set these values since these since Pages.encodeScheme will append numbers from the URL. (Your other option here is to extend Pages and overload the encodeScheme method.)
<pages xmlns="http://jboss.com/products/seam/pages"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.1.xsd"
no-conversation-view-id="/xhtml/map/overviewMap.xhtml"
login-view-id="/xhtml/loginRedirector.xhtml"
http-port="80" https-port="443">
5. Indicate the deftault site scheme with the SEAM scheme tag in pages.xml. This belongs in your page element with attribute view-id="*".
<page view-id="*" scheme="http">
6. Indicate which pages you would like to be forced to use a different scheme regardless of how the user arrived at the page.
<page view-id="/xhtml/forgotPassword.xhtml" scheme="https">
7. Create a SEAM Filter used to examine if a request was forwarded by apache and force SSL. This uses a RequestWrapper to convert http to https and httpPort to httpsPort when necessary as modules in SEAM ask for the requestURL. This java file is called forwardedHttpsDecoderFilter.
package com.yourapplication.yourpackage;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
import org.jboss.seam.annotations.web.Filter;
import org.jboss.seam.log.Log;
import org.jboss.seam.navigation.Pages;
import org.jboss.seam.web.AbstractFilter;
@Name("forwardedHttpsDecoderFilter")
@Scope(ScopeType.APPLICATION)
@Install
@BypassInterceptors
@Filter
public class ForwardedHttpsDecoderFilter extends AbstractFilter
{
private static Integer httpPort;
private static Integer httpsPort;
// Indicates whether the request was forwarded from a proxy.
public static final String HEADER_HTTP_X_FORWARDED_PROTO = "X-Forwarded-Proto";
private static final int DEFAULT_HTTP_PORT = 80;
private static final int DEFAULT_HTTPS_PORT = 443;
@Logger
Log log;
public static class SslRequest extends HttpServletRequestWrapper
{
public SslRequest(HttpServletRequest request)
{
super(request);
}
public HttpServletRequest getRequest()
{
return (HttpServletRequest) super.getRequest();
}
public StringBuffer getRequestURL()
{
StringBuffer requestURL = super.getRequestURL();
boolean needHttpsScheme = requestURL.indexOf("http://") == 0;
if (needHttpsScheme) requestURL.replace(0, 7, "https://");
String httpPortString = String.format(":%d", httpPort);
boolean needSslPort = requestURL.indexOf(httpPortString) > -1;
if (needSslPort)
{
String newPortValue = String.format(":%d", httpsPort);
requestURL = new StringBuffer(requestURL.toString().replace(httpPortString, newPortValue));
}
return requestURL;
}
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException
{
if (request instanceof HttpServletRequest)
{
String forwardedScheme = ((HttpServletRequest) request).getHeader(HEADER_HTTP_X_FORWARDED_PROTO);
if (forwardedScheme != null && forwardedScheme.equals("https"))
request = new SslRequest((HttpServletRequest) request);
}
filterChain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException
{
System.out.println("INITIALIZING FILTER ...");
try
{
// Access the Pages component to see what ports have been set.
Pages pages = (Pages) Component.getInstance("org.jboss.seam.navigation.pages");
httpPort = pages.getHttpPort() != null ? pages.getHttpPort() : DEFAULT_HTTP_PORT;
httpsPort = pages.getHttpsPort() != null ? pages.getHttpsPort() : DEFAULT_HTTPS_PORT;
} catch (Throwable ex) {
log.error("Could not get port numbers", ex);
}
}
}
This code allows requests to go through to the seam framework, then get redirected by SEAM based on scheme setting in pages.xml and then the filter causes https to be used when it is expected.
I hope this helps others with this issue.
Brian
-
2. Re: infinite redirect loop using apache proxy to weblogic and scheme="https"
david.atkins Jul 19, 2015 6:15 AM (in response to bmhardy)I know this post is 3 years old, but just wanted to let you know that your filter really helped me out setting up a legacy seam application that's using haproxy for SSL termination.
In my case the whole application uses SSL. The user-facing URL is on port 8443
My setup:
pages.xml:
<page view-id="*" scheme="https" />
components.xml
<navigation:pages https-port="8443" />
haproxy backend
backend servers-https
mode http
option forwardfor
server localhost 127.0.0.1:8080 weight 1 maxconn 100
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
option ssl-hello-chk