001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/portal/wac/WAClient.java $ 002 /*---------------------------------------------------------------------------- 003 This file is part of deegree, http://deegree.org/ 004 Copyright (C) 2001-2009 by: 005 Department of Geography, University of Bonn 006 and 007 lat/lon GmbH 008 009 This library is free software; you can redistribute it and/or modify it under 010 the terms of the GNU Lesser General Public License as published by the Free 011 Software Foundation; either version 2.1 of the License, or (at your option) 012 any later version. 013 This library is distributed in the hope that it will be useful, but WITHOUT 014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 016 details. 017 You should have received a copy of the GNU Lesser General Public License 018 along with this library; if not, write to the Free Software Foundation, Inc., 019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 020 021 Contact information: 022 023 lat/lon GmbH 024 Aennchenstr. 19, 53177 Bonn 025 Germany 026 http://lat-lon.de/ 027 028 Department of Geography, University of Bonn 029 Prof. Dr. Klaus Greve 030 Postfach 1147, 53001 Bonn 031 Germany 032 http://www.geographie.uni-bonn.de/deegree/ 033 034 e-mail: info@deegree.org 035 ----------------------------------------------------------------------------*/ 036 package org.deegree.portal.wac; 037 038 import java.io.BufferedReader; 039 import java.io.IOException; 040 import java.io.InputStream; 041 import java.io.InputStreamReader; 042 import java.net.URL; 043 import java.net.URLEncoder; 044 import java.net.UnknownHostException; 045 046 import org.apache.commons.httpclient.Header; 047 import org.apache.commons.httpclient.HeaderElement; 048 import org.apache.commons.httpclient.HttpClient; 049 import org.apache.commons.httpclient.contrib.ssl.EasySSLProtocolSocketFactory; 050 import org.apache.commons.httpclient.methods.GetMethod; 051 import org.apache.commons.httpclient.protocol.Protocol; 052 import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; 053 import org.deegree.enterprise.WebUtils; 054 import org.deegree.framework.util.CharsetUtils; 055 import org.deegree.framework.xml.XMLFragment; 056 import org.w3c.dom.Document; 057 import org.xml.sax.SAXException; 058 059 /** 060 * The class offers methods to enable a using program/class to act as a client to a Web Security 061 * Service (WSS) as specified in GDI-NRW. This implementation just supports authentication through 062 * sessionIDs and user/password. If other authentication mechanisms are needed this class should be 063 * extended by defining additional <tt>performDoService</tt> methods. 064 * 065 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a> 066 * @author last edited by: $Author: mschneider $ 067 * 068 * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18 Jun 2009) $ 069 */ 070 public class WAClient { 071 072 private String host = null; 073 074 private String path = null; 075 076 private int port = 443; 077 078 private String contentType = null; 079 080 /** 081 * The constructor assumes that the the certificate to be used is set by starting the java VM 082 * using -Djavax.net.ssl.trustStore parameter. The port to be used is set to SSL standard 443 083 * 084 * @param host 085 * @param path 086 */ 087 public WAClient( String host, String path ) { 088 this( host, path, 443 ); 089 } 090 091 /** 092 * The constructor assumes that the the certificate to be used is set by starting the java VM 093 * using -Djavax.net.ssl.trustStore parameter. 094 * 095 * @param host 096 * @param path 097 * @param port 098 */ 099 public WAClient( String host, String path, int port ) { 100 this( host, path, port, null ); 101 } 102 103 /** 104 * 105 * @param host 106 * @param path 107 * @param port 108 * @param trustStore 109 */ 110 public WAClient( String host, String path, int port, String trustStore ) { 111 this.host = host; 112 this.port = port; 113 this.path = path; 114 if ( trustStore != null ) { 115 System.setProperty( "javax.net.ssl.trustStore", trustStore ); 116 } 117 } 118 119 /** 120 * returns the name of the content type of the result to the last performed request 121 * 122 * @return name of the content type 123 */ 124 public String getContentType() { 125 return contentType; 126 } 127 128 private void extractContentType( Header header ) { 129 // code taken from deegree1: 130 if ( header != null ) { 131 HeaderElement[] element = header.getElements(); 132 if ( element != null && element.length > 0 ) { 133 this.contentType = element[0].getValue(); 134 } 135 } 136 } 137 138 /** 139 * performs a GetCapabilities request against the WSS that is assigned to a client 140 * 141 * @return Capabilities document if request was successful otherwise an exception document will 142 * be returned 143 * @throws WACException 144 */ 145 public Document performGetCapabilities() 146 throws WACException { 147 Document doc; 148 try { 149 StringBuffer sb = new StringBuffer( 200 ); 150 sb.append( path ).append( "?service=WSS&request=GetCapabilities&version=1.0.0" ); 151 HttpClient httpclient = new HttpClient(); 152 // httpclient = WebUtils.enableProxyUsage( httpclient, new URL( path ) ); 153 EasySSLProtocolSocketFactory fac = new EasySSLProtocolSocketFactory(); 154 Protocol myhttps = new Protocol( "https", (ProtocolSocketFactory) fac, port ); 155 httpclient.getHostConfiguration().setHost( host, port, myhttps ); 156 GetMethod httpget = new GetMethod( sb.toString() ); 157 httpclient.executeMethod( httpget ); 158 extractContentType( httpget.getResponseHeader( "" ) ); 159 160 XMLFragment xml = new XMLFragment(); 161 InputStream is = httpget.getResponseBodyAsStream(); 162 xml.load( is, path ); 163 is.close(); 164 doc = xml.getRootElement().getOwnerDocument(); 165 } catch ( IOException e ) { 166 throw new WACException( "can not access WSS", e ); 167 } catch ( SAXException e ) { 168 throw new WACException( "could not parse result from WSS GetCapabilities request", e ); 169 } 170 return doc; 171 } 172 173 /** 174 * performs a GetSession request against the WSS that is assigned to a client. The method 175 * assumed that user/password (urn:x-gdi-nrw:authnMethod:1.0:password) is used for 176 * authentication 177 * 178 * @param user 179 * name of the user who like to get a session 180 * @param password 181 * password of the user 182 * @return GetSession result string if request was successful, otherwise ? 183 * @throws WACException 184 */ 185 public String performGetSession( String user, String password ) 186 throws WACException { 187 String s = null; 188 try { 189 StringBuffer sb = new StringBuffer( 200 ); 190 sb.append( path ).append( "?service=WSS&request=GetSession&version=1.0.0&" ); 191 sb.append( "AUTHMETHOD=urn:x-gdi-nrw:authnMethod:1.0:password&" ); 192 sb.append( "CREDENTIALS=" ).append( user ).append( ',' ).append( password ); 193 194 HttpClient httpclient = new HttpClient(); 195 // httpclient = WebUtils.enableProxyUsage( httpclient, new URL( path ) ); 196 EasySSLProtocolSocketFactory fac = new EasySSLProtocolSocketFactory(); 197 Protocol myhttps = new Protocol( "https", (ProtocolSocketFactory) fac, port ); 198 httpclient.getHostConfiguration().setHost( host, port, myhttps ); 199 GetMethod httpget = new GetMethod( sb.toString() ); 200 httpclient.executeMethod( httpget ); 201 extractContentType( httpget.getResponseHeader( "" ) ); 202 203 InputStream is = httpget.getResponseBodyAsStream(); 204 InputStreamReader ireader = new InputStreamReader( is ); 205 BufferedReader br = new BufferedReader( ireader ); 206 StringBuffer sb2 = new StringBuffer( 5000 ); 207 while ( ( s = br.readLine() ) != null ) { 208 sb2.append( s ); 209 } 210 s = sb2.toString(); 211 br.close(); 212 } catch ( UnknownHostException e ) { 213 throw new WACException( "Host: " + host + " is not known. Host must be set without protocol", e ); 214 } catch ( IOException e ) { 215 throw new WACException( "can not access WSS", e ); 216 } 217 return s; 218 } 219 220 /** 221 * closes a Session by sending a CloseSession request against the WSS that is assigned to a 222 * client. If the passed sessionID is not valid an WSS exception document will be returned 223 * instead of the success message/answer. 224 * 225 * @param sessionID 226 * @return document that indicates that session has been closed otherwise an exception document 227 * will be returned 228 * @throws WACException 229 */ 230 public Document performCloseSession( String sessionID ) 231 throws WACException { 232 Document doc; 233 try { 234 StringBuffer sb = new StringBuffer( 200 ); 235 sb.append( path ).append( "?service=WSS&request=CloseSession&version=1.0.0&" ); 236 sb.append( "SESSIONID=" ).append( sessionID ); 237 HttpClient httpclient = new HttpClient(); 238 // httpclient = WebUtils.enableProxyUsage( httpclient, new URL( path ) ); 239 EasySSLProtocolSocketFactory fac = new EasySSLProtocolSocketFactory(); 240 Protocol myhttps = new Protocol( "https", (ProtocolSocketFactory) fac, port ); 241 httpclient.getHostConfiguration().setHost( host, port, myhttps ); 242 GetMethod httpget = new GetMethod( sb.toString() ); 243 httpclient.executeMethod( httpget ); 244 extractContentType( httpget.getResponseHeader( "" ) ); 245 XMLFragment xml = new XMLFragment(); 246 InputStream is = httpget.getResponseBodyAsStream(); 247 xml.load( is, path ); 248 is.close(); 249 doc = xml.getRootElement().getOwnerDocument(); 250 } catch ( IOException e ) { 251 throw new WACException( "can not access WSS", e ); 252 } catch ( SAXException e ) { 253 throw new WACException( "could not parse result from WSS GetCapabilities request", e ); 254 } 255 return doc; 256 } 257 258 /** 259 * performs a DoService request against the WSS that is assigned to a client. According to the 260 * WSS specification the request will be send using HTTP POST.<BR> 261 * The method uses a user/password authentification 262 * 263 * @see #performDoService(String, String) 264 * 265 * @param request 266 * request to perform 267 * @param user 268 * name of the user who like to get a session 269 * @param password 270 * password of the user 271 * @return result of the passed request. the type depends on target service and request 272 * @throws WACException 273 */ 274 public InputStream performDoService( String request, String user, String password ) 275 throws WACException { 276 InputStream is = null; 277 try { 278 StringBuffer sb = new StringBuffer( 2000 ); 279 sb.append( path ).append( "?service=WSS&request=DoService&version=1.0.0&" ); 280 sb.append( "AUTHMETHOD=USERPASSWORD&" ); 281 sb.append( "CREDENTIALS=" ).append( user ).append( ';' ).append( password ); 282 sb.append( "&SERVICEREQUEST=" ).append( URLEncoder.encode( request, CharsetUtils.getSystemCharset() ) ); 283 HttpClient httpclient = new HttpClient(); 284 // httpclient = WebUtils.enableProxyUsage( httpclient, new URL( path ) ); 285 EasySSLProtocolSocketFactory fac = new EasySSLProtocolSocketFactory(); 286 Protocol myhttps = new Protocol( "https", (ProtocolSocketFactory) fac, port ); 287 httpclient.getHostConfiguration().setHost( host, port, myhttps ); 288 GetMethod httpget = new GetMethod( sb.toString() ); 289 httpclient.executeMethod( httpget ); 290 extractContentType( httpget.getResponseHeader( "" ) ); 291 is = httpget.getResponseBodyAsStream(); 292 } catch ( IOException e ) { 293 throw new WACException( "can not access WSS", e ); 294 } 295 return is; 296 } 297 298 /** 299 * performs a DoService request against the WSS that is assigned to a client. According to the 300 * WSS specification the request will be send using HTTP POST.<BR> 301 * The method uses an authentification through a sessionID 302 * 303 * @see #performDoService(String, String, String) 304 * 305 * @param request 306 * request to perform 307 * @param sessionID 308 * id to authentificate a user 309 * @return result of the passed request. the type depends on target service and request 310 * @throws WACException 311 */ 312 public InputStream performDoService( String request, String sessionID ) 313 throws WACException { 314 InputStream is = null; 315 try { 316 StringBuffer sb = new StringBuffer( 2000 ); 317 sb.append( path ).append( "?service=WSS&request=DoService&version=1.0.0&" ); 318 sb.append( "AUTHMETHOD=urn:x-gdi-nrw:authnMethod:1.0:session&" ); 319 sb.append( "DCP=http_get&" ); 320 sb.append( "CREDENTIALS=" ).append( sessionID ).append( "&" ); 321 sb.append( "SERVICEREQUEST=" ).append( URLEncoder.encode( request, CharsetUtils.getSystemCharset() ) ); 322 323 HttpClient httpclient = new HttpClient(); 324 // httpclient = WebUtils.enableProxyUsage( httpclient, new URL( path ) ); 325 EasySSLProtocolSocketFactory fac = new EasySSLProtocolSocketFactory(); 326 Protocol myhttps = new Protocol( "https", (ProtocolSocketFactory) fac, port ); 327 httpclient.getHostConfiguration().setHost( host, port, myhttps ); 328 GetMethod httpget = new GetMethod( sb.toString() ); 329 httpclient.executeMethod( httpget ); 330 extractContentType( httpget.getResponseHeader( "" ) ); 331 is = httpget.getResponseBodyAsStream(); 332 } catch ( IOException e ) { 333 throw new WACException( "can not access WSS", e ); 334 } 335 return is; 336 } 337 338 }