/* * Copyright (c) 2013 Data Harmonisation Panel * * All rights reserved. This program and the accompanying materials are made * available under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * Data Harmonisation Panel <http://www.dhpanel.eu> */ package eu.esdihumboldt.hale.server.security.util; import java.net.URI; import javax.servlet.http.HttpServletRequest; import org.springframework.security.openid.OpenIDAuthenticationFilter; import com.google.common.base.Splitter; import com.google.common.collect.Iterables; import de.fhg.igd.slf4jplus.ALogger; import de.fhg.igd.slf4jplus.ALoggerFactory; /** * Open ID Authentication filter that supports proxying with X-Forwarded-For * header. * * @author Simon Templer */ public class ProxyOpenIDAuthenticationFilter extends OpenIDAuthenticationFilter { /** * Redeclared constant from APIUtil (which is not used here not to introduce * the dependency) */ public static final String SYSTEM_PROPERTY_SERVER_URL = "hale.api.base-url"; private static final ALogger log = ALoggerFactory .getLogger(ProxyOpenIDAuthenticationFilter.class); @Override protected String buildReturnToUrl(HttpServletRequest request) { String forwardedFor = request.getHeader("X-Forwarded-For"); String returnTo = super.buildReturnToUrl(request); if (forwardedFor != null) { log.warn("Proxy detected - X-Forwarded-For: " + forwardedFor); String proxyReturnTo = buildReturnToForProxy(returnTo, forwardedFor); if (proxyReturnTo != null) { returnTo = proxyReturnTo; } else { log.error("Could not determine proxy returnTo URL"); } } return returnTo; } /** * Build a returnTo URL if behind a proxy. * * @param returnTo the original returnTo URL * @param forwardedFor the X-Forwarded-For header * @return the proxy returnTo URL or <code>null</code> if it could not be * determined */ public static String buildReturnToForProxy(String returnTo, String forwardedFor) { Iterable<String> parts = Splitter.on(',').trimResults().split(forwardedFor); String outwardProxy = null; try { outwardProxy = Iterables.get(parts, 1); // original returnTo URI org = URI.create(returnTo); // build proxy URL, assuming http as scheme URI uri = new URI("http", outwardProxy, org.getPath(), org.getQuery(), org.getFragment()); return uri.toString(); } catch (Exception e) { log.warn("Error building proxy return URL from X-Forwarded-For"); // try HALE base URL system property as fall-back String baseUrl = System.getProperty(SYSTEM_PROPERTY_SERVER_URL); if (baseUrl != null) { try { // original returnTo URI org = URI.create(returnTo); // build proxy URL URI uri = new URI(baseUrl + org.getRawPath()); return uri.toString(); } catch (Exception e1) { log.warn("Error building proxy return URL from " + SYSTEM_PROPERTY_SERVER_URL + " system property", e1); } } } return null; } }