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 }