/* * Copyright 2014 Federal Chancellery Austria MOA-ID has been developed in a cooperation between * BRZ, the Federal Chancellery Austria - ICT staff unit, and Graz University of Technology. * * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by the European * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in * compliance with the Licence. You may obtain a copy of the Licence at: http://www.osor.eu/eupl/ * * Unless required by applicable law or agreed to in writing, software distributed under the Licence * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the Licence for the specific language governing permissions and limitations under * the Licence. * * This product combines work with different licenses. See the "NOTICE" text file for details on the * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative * works that you distribute must include a readable copy of the "NOTICE" text file. */ package at.gv.egiz.eaaf.core.impl.http; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableKeyException; import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.net.ssl.SSLContext; import javax.servlet.http.HttpServletRequest; import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; import at.gv.egiz.eaaf.core.exceptions.EaafFactoryException; import org.apache.commons.lang3.StringUtils; import org.apache.http.conn.ssl.TrustAllStrategy; import org.apache.http.ssl.SSLContextBuilder; import org.apache.http.ssl.SSLContexts; import org.apache.http.ssl.TrustStrategy; import lombok.extern.slf4j.Slf4j; @Slf4j public class HttpUtils { private static final String ERROR_03 = "internal.httpclient.03"; /** * Helper method to retrieve server URL including context path. * * @param request HttpServletRequest * @return Server URL including context path (e.g. * http://localhost:8443/moa-id-auth */ public static String getBaseUrl(final HttpServletRequest request) { final StringBuffer buffer = new StringBuffer(getServerUrl(request)); // add context path if available final String contextPath = request.getContextPath(); if (!StringUtils.isEmpty(contextPath)) { buffer.append(contextPath); } return buffer.toString(); } /** * Helper method to retrieve server URL. * * @param request HttpServletRequest * @return Server URL (e.g. http://localhost:8443) */ public static String getServerUrl(final HttpServletRequest request) { final StringBuffer buffer = new StringBuffer(); // get protocol final String protocol = request.getScheme(); buffer.append(protocol).append("://"); // server name buffer.append(request.getServerName()); // add port if necessary final int port = request.getServerPort(); if (protocol.equals("http") && port != 80 || protocol.equals("https") && port != 443) { buffer.append(':'); buffer.append(port); } return buffer.toString(); } /** * Extract the IDP PublicURLPrefix from authrequest. * * @param req HttpServletRequest * @return PublicURLPrefix which ends always without / */ public static String extractAuthUrlFromRequest(final HttpServletRequest req) { String authUrl = req.getScheme() + "://" + req.getServerName(); if (req.getScheme().equalsIgnoreCase("https") && req.getServerPort() != 443 || req.getScheme().equalsIgnoreCase("http") && req.getServerPort() != 80) { authUrl = authUrl.concat(":" + req.getServerPort()); } authUrl = authUrl.concat(req.getContextPath()); return authUrl; } /** * Extract the IDP requested URL from authrequest. * * @param req HttpServletRequest * @return RequestURL which ends always without / */ public static String extractAuthServletPathFromRequest(final HttpServletRequest req) { return extractAuthUrlFromRequest(req).concat(req.getServletPath()); } /** * Add a http GET parameter to URL. * * @param url URL * @param paramname Name of the parameter. * @param paramvalue Value of the parameter. * @return */ public static String addUrlParameter(final String url, final String paramname, final String paramvalue) { final String param = paramname + "=" + paramvalue; if (url.indexOf("?") < 0) { return url + "?" + param; } else { return url + "&" + param; } } /** * Initialize a {@link SSLContext} with a {@link KeyStore} that uses X509 Client * authentication. * * @param keyStore KeyStore with private keys that should be * used * @param keyAlias Alias of the key that should be used. If * the alias is null, than the first key that * is found will be selected. * @param keyPasswordString Password of the Key in this keystore * @param trustAllServerCertificates Deactivate SSL server-certificate * validation * @param friendlyName FriendlyName of the http client for logging * purposes * @return {@link SSLContext} with X509 client authentication * @throws EaafConfigurationException In case of a configuration error * @throws EaafFactoryException In case of a {@link SSLContext} * initialization error */ public static SSLContext buildSslContextWithSslClientAuthentication(@Nonnull final KeyStore keyStore, @Nullable String keyAlias, @Nullable String keyPasswordString, boolean trustAllServerCertificates, @Nonnull String friendlyName) throws EaafConfigurationException, EaafFactoryException { try { log.trace("Open SSL Client-Auth keystore with password: {}", keyPasswordString); final char[] keyPassword = keyPasswordString == null ? StringUtils.EMPTY.toCharArray() : keyPasswordString.toCharArray(); SSLContextBuilder sslContextBuilder = SSLContexts.custom(); if (StringUtils.isNotEmpty(keyAlias)) { sslContextBuilder = sslContextBuilder .loadKeyMaterial(keyStore, keyPassword, new EaafSslKeySelectionStrategy(keyAlias)); } else { sslContextBuilder = sslContextBuilder .loadKeyMaterial(keyStore, keyPassword); } if (trustAllServerCertificates) { log.warn("Http-client:{} trusts ALL TLS server-certificates!"); final TrustStrategy trustStrategy = new TrustAllStrategy(); sslContextBuilder = sslContextBuilder.loadTrustMaterial(trustStrategy); } return sslContextBuilder.build(); } catch (NoSuchAlgorithmException | KeyManagementException | UnrecoverableKeyException | KeyStoreException e) { throw new EaafFactoryException(ERROR_03, new Object[] { friendlyName, e.getMessage() }, e); } } }