//$HeadURL$ /*---------------------------------------------------------------------------- This file is part of deegree, http://deegree.org/ Copyright (C) 2001-2011 by: - Department of Geography, University of Bonn - and - lat/lon GmbH - This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Contact information: lat/lon GmbH Aennchenstr. 19, 53177 Bonn Germany http://lat-lon.de/ Department of Geography, University of Bonn Prof. Dr. Klaus Greve Postfach 1147, 53001 Bonn Germany http://www.geographie.uni-bonn.de/deegree/ e-mail: info@deegree.org ----------------------------------------------------------------------------*/ package org.deegree.securityproxy.sessionid; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; import org.apache.commons.io.IOUtils; import org.apache.http.HttpEntity; import org.apache.http.StatusLine; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.utils.URIBuilder; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.log4j.Logger; /** * Requests a sessionId from a WASS. * * @author <a href="mailto:goltz@lat-lon.de">Lyn Goltz</a> * @author last edited by: $Author: lyn $ * * @version $Revision: $, $Date: $ */ public class WassSessionIdRetriever implements SessionIdRetriever { private static final Logger LOG = Logger.getLogger( WassSessionIdRetriever.class ); private final String baseUrl; private int connectTimeout = -1; private int socketTimeout = -1; public WassSessionIdRetriever( String baseUrl ) { this.baseUrl = baseUrl; } @Override public String retrieveSessionId( String userName, String password ) { checkParameters( userName, password ); try { URI requestUri = createRequest( userName, password ); return requestSessionId( requestUri ); } catch ( ClientProtocolException e ) { LOG.error( "An error occured during requesting the session id.", e ); } catch ( IOException e ) { LOG.error( "An error occured during requesting the session id.", e ); } catch ( URISyntaxException e ) { LOG.error( "An error occured during requesting the session id.", e ); } return null; } CloseableHttpClient createHttpClient() { return HttpClientBuilder.create().build(); } private String requestSessionId( URI requestUri ) throws ClientProtocolException, IOException { LOG.info( "Request URI is " + requestUri ); CloseableHttpResponse response = exceuteRequest( requestUri ); try { StatusLine statusLine = response.getStatusLine(); if ( statusLine.getStatusCode() == 200 ) { return parseResponse( response ); } LOG.info( "Service does not response with status code 200: " + statusLine ); return null; } finally { IOUtils.closeQuietly( response ); } } private CloseableHttpResponse exceuteRequest( URI requestUri ) throws IOException, ClientProtocolException { HttpGet httpGet = createConfiguredHttpGet( requestUri ); CloseableHttpClient httpClient = createHttpClient(); return httpClient.execute( httpGet ); } private HttpGet createConfiguredHttpGet( URI requestUri ) { HttpGet httpGet = new HttpGet( requestUri ); RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout( socketTimeout ).setConnectTimeout( connectTimeout ).build(); httpGet.setConfig( requestConfig ); return httpGet; } private URI createRequest( String userName, String password ) throws URISyntaxException { URIBuilder uriBuilder = new URIBuilder( baseUrl ); uriBuilder.addParameter( "SERVICE", "WAS" ); uriBuilder.addParameter( "REQUEST", "GetSession" ); uriBuilder.addParameter( "VERSION", "1.0.0" ); uriBuilder.addParameter( "AUTHMETHOD", "urn:x-gdi-nrw:authnMethod:1.0:password" ); uriBuilder.addParameter( "CREDENTIALS", userName + "," + password ); return uriBuilder.build(); } private String parseResponse( CloseableHttpResponse httpResponse ) throws IOException { HttpEntity entity = httpResponse.getEntity(); if ( entity != null ) { return parseEntity( entity ); } LOG.info( "Response entity is null!" ); return null; } private String parseEntity( HttpEntity entity ) throws IOException { String response = readResponse( entity ); if ( isServiceException( response ) ) { LOG.info( "Response is a service exception: " + response ); return null; } return response; } private String readResponse( HttpEntity entity ) throws IOException { InputStream content = entity.getContent(); try { return IOUtils.toString( content, "UTF-8" ); } finally { IOUtils.closeQuietly( content ); } } private boolean isServiceException( String response ) { return response.contains( "ServiceExceptionReport" ); } private void checkParameters( String userName, String password ) { if ( userName == null ) throw new IllegalArgumentException( "User name must not be null!" ); if ( password == null ) throw new IllegalArgumentException( "Password must not be null!" ); } /** * @return timeout in milliseconds until a connection is established (s. {@link #setConnectTimeout(int)}) */ public int getConnectTimeout() { return connectTimeout; } /** * @param connectTimeout * timeout in milliseconds until a connection is established. A timeout value of zero is interpreted as * an infinite timeout. * <ul> * <li>A timeout value of zero is interpreted as an infinite timeout.</li> * <li>A negative value is interpreted as undefined (system default).</li> * </ul> * Default: <code>-1</code> */ public void setConnectTimeout( int connectTimeout ) { this.connectTimeout = connectTimeout; } /** * * @return the socket timeout (<code>SO_TIMEOUT</code>) in milliseconds (s. {@link #setSocketTimeout(int)}) */ public int getSocketTimeout() { return socketTimeout; } /** * @param socketTimeout * the socket timeout (<code>SO_TIMEOUT</code>) in milliseconds, which is the timeout for waiting for * data or, put differently, a maximum period inactivity between two consecutive data packets). * <ul> * <li> * A timeout value of zero is interpreted as an infinite timeout.</li> * <li>A negative value is interpreted as undefined (system default).</li> * </ul> * Default: <code>-1</code> */ public void setSocketTimeout( int socketTimeout ) { this.socketTimeout = socketTimeout; } }