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