001    //$HeadURL: svn+ssh://developername@svn.wald.intevation.org/deegree/base/trunk/src/org/deegree/security/owsproxy/OWSProxyServletFilter.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.security.owsproxy;
037    
038    import static java.lang.System.getProperty;
039    import static org.deegree.framework.util.CharsetUtils.getSystemCharset;
040    import static org.deegree.i18n.Messages.getMessage;
041    
042    import java.awt.Color;
043    import java.awt.Font;
044    import java.awt.Graphics;
045    import java.awt.image.BufferedImage;
046    import java.io.File;
047    import java.io.IOException;
048    import java.io.InputStream;
049    import java.io.OutputStream;
050    import java.lang.reflect.Constructor;
051    import java.lang.reflect.InvocationTargetException;
052    import java.net.MalformedURLException;
053    import java.net.URL;
054    import java.util.Enumeration;
055    import java.util.HashMap;
056    import java.util.List;
057    import java.util.Map;
058    import java.util.Properties;
059    
060    import javax.servlet.Filter;
061    import javax.servlet.FilterChain;
062    import javax.servlet.FilterConfig;
063    import javax.servlet.ServletContext;
064    import javax.servlet.ServletException;
065    import javax.servlet.ServletRequest;
066    import javax.servlet.ServletResponse;
067    import javax.servlet.http.HttpServletRequest;
068    import javax.servlet.http.HttpServletResponse;
069    
070    import org.deegree.enterprise.servlet.ServletRequestWrapper;
071    import org.deegree.enterprise.servlet.ServletResponseWrapper;
072    import org.deegree.framework.log.ILogger;
073    import org.deegree.framework.log.LoggerFactory;
074    import org.deegree.framework.trigger.TriggerProvider;
075    import org.deegree.framework.util.ImageUtils;
076    import org.deegree.framework.util.MimeTypeMapper;
077    import org.deegree.framework.util.StringTools;
078    import org.deegree.framework.xml.XMLFragment;
079    import org.deegree.framework.xml.XMLParsingException;
080    import org.deegree.model.spatialschema.Envelope;
081    import org.deegree.ogcwebservices.InvalidParameterValueException;
082    import org.deegree.ogcwebservices.OGCRequestFactory;
083    import org.deegree.ogcwebservices.OGCWebServiceException;
084    import org.deegree.ogcwebservices.OGCWebServiceRequest;
085    import org.deegree.ogcwebservices.csw.discovery.GetRecords;
086    import org.deegree.ogcwebservices.wcs.getcoverage.GetCoverage;
087    import org.deegree.ogcwebservices.wfs.XMLFactory;
088    import org.deegree.ogcwebservices.wfs.operation.GetFeature;
089    import org.deegree.ogcwebservices.wfs.operation.transaction.Transaction;
090    import org.deegree.ogcwebservices.wms.operation.GetLegendGraphic;
091    import org.deegree.ogcwebservices.wms.operation.GetMap;
092    import org.deegree.security.AbstractAuthentication;
093    import org.deegree.security.AuthenticationDocument;
094    import org.deegree.security.Authentications;
095    import org.deegree.security.SecurityConfigurationException;
096    import org.deegree.security.UnauthorizedException;
097    import org.deegree.security.drm.WrongCredentialsException;
098    import org.deegree.security.drm.model.User;
099    import org.deegree.security.owsrequestvalidator.OWSValidator;
100    import org.deegree.security.owsrequestvalidator.Policy;
101    import org.deegree.security.owsrequestvalidator.PolicyDocument;
102    import org.xml.sax.SAXException;
103    
104    /**
105     * An OWSProxyPolicyFilter can be registered as a ServletFilter to a web context. It offers a facade that looks like a
106     * OWS but additionaly enables validating incoming requests and outgoing responses against rules defined in a policy
107     * document and/or a deegree user and right management system.
108     *
109     * @see org.deegree.security.drm.SecurityRegistry
110     *
111     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a>
112     * @author last edited by: $Author: apoth $
113     *
114     * @version $Revision: 7461 $, $Date: 2007-06-05 15:35:14 +0200 (Di, 05 Jun 2007) $
115     */
116    public class ConfigurableOWSProxyServletFilter implements Filter {
117    
118        private static TriggerProvider TP = TriggerProvider.create( ConfigurableOWSProxyServletFilter.class );
119    
120        private static final ILogger LOG = LoggerFactory.getLogger( ConfigurableOWSProxyServletFilter.class );
121    
122        private FilterConfig config;
123    
124        private OWSProxyPolicyFilter pFilter;
125    
126        private Authentications authentications;
127    
128        private SecurityConfig secConfig;
129    
130        private String altRequestPage;
131    
132        private String altResponsePage;
133    
134        private boolean imageExpected = false;
135    
136        private String proxiedUrl;
137    
138        /**
139         * initialize the filter with parameters from the deployment descriptor
140         *
141         * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
142         */
143        public void init( FilterConfig config )
144                                throws ServletException {
145            this.config = config;
146    
147            Properties validators = new Properties();
148            try {
149                InputStream is = ConfigurableOWSProxyServletFilter.class.getResourceAsStream( "validators.properties" );
150                validators.load( is );
151                is.close();
152            } catch ( Exception e ) {
153                throw new ServletException( e );
154            }
155    
156            pFilter = new OWSProxyPolicyFilter();
157            String proxyURL = "http://127.0.0.1/owsproxy/proxy";
158            if ( config.getInitParameter( "PROXYURL" ) != null ) {
159                proxyURL = config.getInitParameter( "PROXYURL" );
160            }
161    
162            // may be null
163            proxiedUrl = config.getInitParameter( "PROXIED_URL" );
164            if ( proxiedUrl == null ) {
165                LOG.logInfo( "NOT using service prefixes for layers and feature types." );
166            } else {
167                LOG.logInfo( "Using service prefix '" + proxiedUrl + "' for layers and feature types." );
168            }
169    
170            Enumeration<?> iterator = config.getInitParameterNames();
171            while ( iterator.hasMoreElements() ) {
172                String paramName = (String) iterator.nextElement();
173                String paramValue = config.getInitParameter( paramName );
174                if ( paramName.endsWith( "POLICY" ) ) {
175                    paramValue = config.getServletContext().getRealPath( paramValue );
176                    File file = new File( paramValue );
177                    URL fileURL = null;
178                    try {
179                        fileURL = file.toURI().toURL();
180                    } catch ( MalformedURLException e ) {
181                        LOG.logError( "Couldn't create an url from the configured POLICY parameter: " + paramValue
182                                      + " because: " + e.getMessage() );
183                        throw new ServletException( e );
184                    }
185                    if ( fileURL != null ) {
186                        LOG.logDebug( "OWSProxyFilter: reading configuration file from : " + fileURL.toExternalForm() );
187                        initValidator( proxyURL, paramName, fileURL, validators );
188                    }
189                }
190    
191            }
192            // } catch ( Exception e ) {
193            // LOG.logError( e.getMessage(), e );
194            // throw new ServletException( e );
195            // }
196            LOG.logInfo( "OWSProxyServlet intitialized successfully" );
197            LOG.logInfo( "-DCHARSET setting: " + getSystemCharset() );
198            LOG.logInfo( "-Dfile.encoding setting: " + getProperty( "file.encoding" ) );
199            altRequestPage = config.getInitParameter( "ALTREQUESTPAGE" );
200            altResponsePage = config.getInitParameter( "ALTRESPONSEPAGE" );
201    
202            if ( altRequestPage == null ) {
203                LOG.logWarning( "You did not configure the ALTREQUESTPAGE parameter." );
204                LOG.logWarning( "The servlet filter will not be fully functional." );
205            }
206            if ( altResponsePage == null ) {
207                LOG.logWarning( "You did not configure the ALTRESPONSEPAGE parameter." );
208                LOG.logWarning( "The servlet filter will not be fully functional." );
209            }
210    
211            try {
212                initAuthentications( config.getInitParameter( "AuthenticationSettings" ) );
213            } catch ( Exception e ) {
214                LOG.logDebug( "Error while initializing", e );
215                throw new ServletException( e );
216            }
217        }
218    
219        /**
220         *
221         * @param configFile
222         * @throws IOException
223         * @throws SAXException
224         * @throws XMLParsingException
225         */
226        private void initAuthentications( String configFile )
227                                throws IOException, SAXException, XMLParsingException {
228            URL url = null;
229            if ( configFile == null ) {
230                // TODO what to do here?
231            } else {
232                File file = new File( configFile );
233                if ( !file.isAbsolute() ) {
234                    String s = this.config.getServletContext().getRealPath( configFile );
235                    url = new File( s ).toURI().toURL();
236                } else {
237                    url = file.toURI().toURL();
238                }
239            }
240            AuthenticationDocument ad = new AuthenticationDocument( url );
241            authentications = ad.createAuthentications();
242    
243        }
244    
245        /**
246         *
247         * @param proxyURL
248         * @param paramName
249         * @param paramValue
250         * @param validators
251         * @throws ServletException
252         */
253        private void initValidator( String proxyURL, String paramName, URL paramValue, Properties validators )
254                                throws ServletException {
255            try {
256                PolicyDocument doc = new PolicyDocument( paramValue );
257                Policy policy = doc.getPolicy();
258                if ( secConfig == null && policy.getSecurityConfig() != null ) {
259                    // use security configuration of the first policy that defined one.
260                    // this is possible because just one security configuration can be
261                    // used within a deegree/VM instance
262                    secConfig = policy.getSecurityConfig();
263                }
264    
265                if ( secConfig != null ) {
266                    secConfig.setProxiedUrl( proxiedUrl );
267                }
268    
269                int pos = paramName.indexOf( ':' );
270                String service = paramName.substring( 0, pos );
271    
272                // describes the signature of the required constructor
273                Class<?>[] cl = new Class<?>[2];
274                cl[0] = Policy.class;
275                cl[1] = String.class;
276    
277                // set parameter to submit to the constructor
278                Object[] o = new Object[2];
279                o[0] = policy;
280                o[1] = proxyURL;
281    
282                Class<?> clzz = Class.forName( validators.getProperty( service ) );
283                Constructor<?> con = clzz.getConstructor( cl );
284    
285                pFilter.addValidator( service, (OWSValidator) con.newInstance( o ) );
286            } catch ( SecurityConfigurationException e ) {
287                LOG.logError( "Couldn't create a policy document from given value: " + paramValue + ", because : "
288                              + e.getMessage(), e );
289                throw new ServletException( e );
290            } catch ( XMLParsingException e ) {
291                LOG.logError( "Couldn't create a policy from given value: " + paramValue + ", because : " + e.getMessage(),
292                              e );
293                throw new ServletException( e );
294            } catch ( ClassNotFoundException e ) {
295                LOG.logError( "The classloader couldn't find an appropriate class  for the configured service, because"
296                              + e.getMessage(), e );
297                throw new ServletException( e );
298            } catch ( NoSuchMethodException e ) {
299                LOG.logError( "The classloader couldn't find a constructor for the configured service, because"
300                              + e.getMessage(), e );
301                throw new ServletException( e );
302            } catch ( InstantiationException e ) {
303                LOG.logError( "The classloader couldn't instantiate the configured service, because" + e.getMessage(), e );
304                throw new ServletException( e );
305            } catch ( IllegalAccessException e ) {
306                LOG.logError( "The classloader couldn't instantiate the configured service, because" + e.getMessage(), e );
307                throw new ServletException( e );
308            } catch ( InvocationTargetException e ) {
309                LOG.logError( "The classloader couldn't instantiate the configured service, because" + e.getMessage(), e );
310                throw new ServletException( e );
311            }
312        }
313    
314        /**
315         * free resources allocated by the filter
316         *
317         * @see javax.servlet.Filter#destroy()
318         */
319        public void destroy() {
320            config = null;
321        }
322    
323        /**
324         * perform filter
325         *
326         * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse,
327         *      javax.servlet.FilterChain)
328         */
329        public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain )
330                                throws IOException, ServletException {
331    
332            Object[] o = TP.doPreTrigger( this, request, response, chain );
333            request = (ServletRequest) o[0];
334            response = (ServletResponse) o[1];
335            chain = (FilterChain) o[2];
336    
337            // encapsulate the servlet request into a wrapper object to ensure
338            // the availability of the InputStream
339            ServletRequestWrapper requestWrapper = null;
340    
341            if ( request instanceof ServletRequestWrapper ) {
342                LOG.logDebug( "OWSProxySerlvetFilter: the incoming request is actually an org.deegree.enterprise.servlet.RequestWrapper, so not creating new instance." );
343                requestWrapper = (ServletRequestWrapper) request;
344            } else {
345                requestWrapper = new ServletRequestWrapper( (HttpServletRequest) request );
346            }
347    
348            LOG.logDebug( "OWSProxySerlvetFilter: GetContentype(): " + requestWrapper.getContentType() );
349    
350            OGCWebServiceRequest owsReq = null;
351            try {
352                owsReq = OGCRequestFactory.create( requestWrapper );
353            } catch ( OGCWebServiceException e ) {
354                LOG.logError( "OWSProxyServletFilter: Couln't create an OGCWebserviceRequest because: " + e.getMessage(), e );
355                throw new ServletException( e.getMessage() );
356            }
357            imageExpected = isImageRequested( owsReq );
358            // extract user from the request
359            User user = null;
360            try {
361                user = getUser( requestWrapper, owsReq );
362            } catch ( Exception e1 ) {
363                handleResponseMissingAutorization( (HttpServletRequest) request, (HttpServletResponse) response, owsReq,
364                                                   e1.getMessage() );
365                return;
366            }
367            try {
368                pFilter.validateGeneralConditions( (HttpServletRequest) request, requestWrapper.getContentLength(), user );
369                pFilter.validate( owsReq, user );
370            } catch ( InvalidParameterValueException e ) {
371                handleRequestMissingAutorization( (HttpServletRequest) request, (HttpServletResponse) response, owsReq,
372                                                  e.getMessage() );
373                return;
374            } catch ( UnauthorizedException e ) {
375                handleRequestMissingAutorization( (HttpServletRequest) request, (HttpServletResponse) response, owsReq,
376                                                  e.getMessage() );
377                return;
378            } catch ( Exception e ) {
379                LOG.logError( e.getMessage(), e );
380                request.setAttribute( "MESSAGE", e.getMessage() );
381                ServletContext sc = config.getServletContext();
382                sc.getRequestDispatcher( altResponsePage ).forward( request, response );
383                return;
384            }
385    
386            export( requestWrapper, owsReq );
387    
388            // encapsulate the servlet response into a wrapper object to ensure
389            // the availability of the OutputStream
390            ServletResponseWrapper resWrap = new ServletResponseWrapper( (HttpServletResponse) response );
391            logHttpRequest( requestWrapper );
392            // forward request to the next filter or servlet
393            chain.doFilter( requestWrapper, resWrap );
394            // get result from performing the request
395            OutputStream os = resWrap.getOutputStream();
396            byte[] b = ( (ServletResponseWrapper.ProxyServletOutputStream) os ).toByteArray();
397    
398            if ( !imageExpected ) {
399                // fixup encoding mess: convert byte array into system character set for processing
400                String str = new String( b, resWrap.getCharacterEncoding() );
401                b = str.getBytes( getSystemCharset() );
402                LOG.logDebug( "Internal response was", str );
403            } else {
404                LOG.logDebug( "Expecting image." );
405            }
406            try {
407                // validate the result of a request performing
408                String mime = resWrap.getContentType();
409                LOG.logDebug( "mime type raw: " + mime );
410                if ( mime != null ) {
411                    mime = StringTools.toArray( mime, ";", false )[0];
412                } else {
413                    if ( imageExpected ) {
414                        mime = "image/jpeg";
415                    } else {
416                        mime = "text/xml";
417                    }
418                }
419                LOG.logDebug( "mime type", mime );
420                b = pFilter.validate( owsReq, b, mime, user );
421            } catch ( InvalidParameterValueException ee ) {
422                LOG.logError( ee.getMessage(), ee );
423                handleResponseMissingAutorization( (HttpServletRequest) request, (HttpServletResponse) response, owsReq,
424                                                   ee.getMessage() );
425                return;
426            } catch ( UnauthorizedException e ) {
427                LOG.logError( e.getMessage(), e );
428                handleResponseMissingAutorization( (HttpServletRequest) request, (HttpServletResponse) response, owsReq,
429                                                   e.getMessage() );
430                return;
431            }
432    
433            // fix up encoding mess: convert encoding of byte array into response character set for sending
434            if ( !imageExpected ) {
435                if ( resWrap.getCharacterEncoding() != null ) {
436                    String str = new String( b, getSystemCharset() );
437                    b = str.getBytes( resWrap.getCharacterEncoding() );
438                }
439            }
440            response.setContentType( resWrap.getContentType() );
441            response.setCharacterEncoding( resWrap.getCharacterEncoding() );
442            // write result back to the client
443            os = response.getOutputStream();
444            os.write( b );
445            os.close();
446    
447            TP.doPostTrigger( this, b );
448        }
449    
450        /**
451         * exports the changed request to a XML document/string that will substitute the original request contained in the
452         * passed {@link ServletRequestWrapper}
453         *
454         * @param requestWrapper
455         * @param owsReq
456         */
457        private void export( ServletRequestWrapper requestWrapper, OGCWebServiceRequest owsReq ) {
458            try {
459                XMLFragment doc = null;
460                if ( owsReq instanceof GetFeature ) {
461                    doc = XMLFactory.export( (GetFeature) owsReq );
462                } else if ( owsReq instanceof Transaction ) {
463                    doc = XMLFactory.export( (Transaction) owsReq );
464                } else if ( owsReq instanceof GetRecords ) {
465                    doc = org.deegree.ogcwebservices.csw.discovery.XMLFactory.export( (GetRecords) owsReq );
466                } else if ( owsReq instanceof org.deegree.ogcwebservices.csw.manager.Transaction ) {
467                    doc = org.deegree.ogcwebservices.csw.manager.XMLFactory.export( (org.deegree.ogcwebservices.csw.manager.Transaction) owsReq );
468                }
469                if ( doc != null ) {
470                    requestWrapper.setInputStreamAsByteArray( doc.getAsString().getBytes() );
471                }
472            } catch ( Exception e ) {
473                // TODO Auto-generated catch block
474                e.printStackTrace();
475            }
476        }
477    
478        /**
479         * logs a requests parameters and meta informations
480         *
481         * @param reqWrap
482         */
483        private void logHttpRequest( ServletRequestWrapper reqWrap ) {
484            if ( LOG.getLevel() == ILogger.LOG_DEBUG ) {
485                LOG.logDebug( "getRemoteAddr " + reqWrap.getRemoteAddr() );
486                LOG.logDebug( "getPort " + reqWrap.getServerPort() );
487                LOG.logDebug( "getMethod " + reqWrap.getMethod() );
488                LOG.logDebug( "getQueryString " + reqWrap.getQueryString() );
489                LOG.logDebug( "getPathInfo " + reqWrap.getPathInfo() );
490                LOG.logDebug( "getRequestURI " + reqWrap.getRequestURI() );
491                LOG.logDebug( "getServerName " + reqWrap.getServerName() );
492                LOG.logDebug( "getServerPort " + reqWrap.getServerPort() );
493                LOG.logDebug( "getServletPath " + reqWrap.getServletPath() );
494            }
495        }
496    
497        /**
498         * go to alternative page if authorization to perform the desired request ist missing
499         *
500         * @param request
501         * @param response
502         * @param owsReq
503         * @param message
504         * @throws IOException
505         * @throws ServletException
506         */
507        private void handleRequestMissingAutorization( HttpServletRequest request, HttpServletResponse response,
508                                                       OGCWebServiceRequest owsReq, String message )
509                                throws IOException, ServletException {
510            if ( message == null ) {
511                message = "missing authorization";
512            }
513            if ( imageExpected ) {
514                int width = 500;
515                int height = 500;
516                if ( owsReq != null && owsReq instanceof GetMap ) {
517                    width = ( (GetMap) owsReq ).getWidth();
518                    height = ( (GetMap) owsReq ).getHeight();
519                } else if ( owsReq != null && owsReq instanceof GetCoverage ) {
520                    Envelope env = (Envelope) ( (GetCoverage) owsReq ).getDomainSubset().getSpatialSubset().getGrid();
521                    width = (int) env.getWidth();
522                    height = (int) env.getHeight();
523                }
524                response.setContentType( "image/jpeg" );
525                OutputStream os = response.getOutputStream();
526                BufferedImage bi = new BufferedImage( width, height, BufferedImage.TYPE_INT_RGB );
527                Graphics g = bi.getGraphics();
528                g.setColor( Color.WHITE );
529                g.fillRect( 0, 0, width, height );
530                g.setColor( Color.BLACK );
531                g.setFont( new Font( "DIALOG", Font.PLAIN, 14 ) );
532                g.drawString( Messages.getString( "MISSINGAUTHORIZATION" ), 5, 60 );
533                String[] lines = StringTools.toArray( message, ":|", false );
534                int y = 100;
535                for ( int i = 0; i < lines.length; i++ ) {
536                    g.drawString( lines[i], 5, y );
537                    y = y + 30;
538                }
539                g.dispose();
540                try {
541                    ImageUtils.saveImage( bi, os, "jpeg", 0.95f );
542                } catch ( Exception e ) {
543                    e.printStackTrace();
544                }
545                os.close();
546            } else {
547                request.setAttribute( "MESSAGE", message );
548                ServletContext sc = config.getServletContext();
549                sc.getRequestDispatcher( altRequestPage ).forward( request, response );
550            }
551        }
552    
553        /**
554         * go to alternative page if authorization to deliver the result to a request is missing
555         *
556         * @param request
557         * @param response
558         * @param owsReq
559         * @param message
560         * @throws IOException
561         * @throws ServletException
562         */
563        private void handleResponseMissingAutorization( HttpServletRequest request, HttpServletResponse response,
564                                                        OGCWebServiceRequest owsReq, String message )
565                                throws IOException, ServletException {
566    
567            if ( imageExpected ) {
568                int width = 500;
569                int height = 500;
570                if ( owsReq != null && owsReq instanceof GetMap ) {
571                    width = ( (GetMap) owsReq ).getWidth();
572                    height = ( (GetMap) owsReq ).getHeight();
573                } else if ( owsReq != null && owsReq instanceof GetCoverage ) {
574                    Envelope env = (Envelope) ( (GetCoverage) owsReq ).getDomainSubset().getSpatialSubset().getGrid();
575                    width = (int) env.getWidth();
576                    height = (int) env.getHeight();
577                }
578                response.setContentType( "image/jpeg" );
579                OutputStream os = response.getOutputStream();
580                BufferedImage bi = new BufferedImage( width, height, BufferedImage.TYPE_INT_RGB );
581                Graphics g = bi.getGraphics();
582                g.setColor( Color.WHITE );
583                g.fillRect( 0, 0, width, height );
584                g.setColor( Color.BLACK );
585                g.setFont( new Font( "DIALOG", Font.PLAIN, 14 ) );
586                String[] lines = StringTools.toArray( message, ":|", false );
587                int y = 100;
588                for ( int i = 0; i < lines.length; i++ ) {
589                    g.drawString( lines[i], 5, y );
590                    y = y + 30;
591                }
592                g.dispose();
593                try {
594                    ImageUtils.saveImage( bi, os, "jpeg", 0.95f );
595                } catch ( Exception e ) {
596                    LOG.logError( e.getMessage(), e );
597                }
598                os.write( message.getBytes() );
599                os.close();
600            } else {
601                request.setAttribute( "MESSAGE", message );
602                ServletContext sc = config.getServletContext();
603                sc.getRequestDispatcher( altResponsePage ).forward( request, response );
604            }
605        }
606    
607        /**
608         * returns the user from the incoming request.
609         *
610         * @param request
611         * @return the user from the incoming request.
612         * @throws WrongCredentialsException
613         */
614        private User getUser( HttpServletRequest request, OGCWebServiceRequest owsReq )
615                                throws WrongCredentialsException {
616    
617            String sessionId = owsReq.getVendorSpecificParameter( "SESSIONID" );
618            String user = owsReq.getVendorSpecificParameter( "USER" );
619            String password = owsReq.getVendorSpecificParameter( "PASSWORD" );
620            Map<String, String> params = new HashMap<String, String>();
621            // known Authentication classes requires following parameters. Depending on the
622            // concrete implementation not all parameters are used for authentication
623            params.put( "SESSIONID", sessionId );
624            params.put( "USER", user );
625            params.put( "PASSWORD", password );
626            params.put( "USERPRINCIPAL", request.getUserPrincipal().getName() );
627            params.put( "IPADDRESS", request.getRemoteHost() );
628    
629            User usr = null;
630    
631            List<AbstractAuthentication> authList = authentications.getAuthenticationsAsOrderedList();
632            // the available authentication implementations and their order are defined in a
633            // configuration file. Depending on their order it will be tried to authenticate
634            // the current user against DRM. As soon as a authentication method succeeds the
635            // authenticated user will be returned. If no authentication method succeeds an
636            // exception will be thrown.
637            // So it can be configured which authentication methods in which order shall be used.
638            StringBuffer sb = new StringBuffer( 1000 );
639            if ( authList.size() == 0 ) {
640                LOG.logInfo( "no authentication method defined, return null as user" );
641                return null;
642            }
643            sb.append( "following authentication methods have been performed: " );
644            for ( AbstractAuthentication authentication : authList ) {
645                try {
646                    LOG.logDebug( "authenticate using: " + authentication.getAuthenticationName() );
647                    usr = authentication.authenticate( params );
648                    if ( usr != null ) {
649                        return usr;
650                    }
651                    sb.append( "cannot get user with authentication method: " );
652                    sb.append( authentication.getAuthenticationName() ).append( " | " );
653                } catch ( WrongCredentialsException e ) {
654                    LOG.logInfo( "user cannot be authenticated with: " + authentication.getAuthenticationName() );
655                    LOG.logInfo( "reason: " + e.getMessage() );
656                    sb.append( "authentication method " ).append( authentication.getAuthenticationName() );
657                    sb.append( ": " ).append( e.getMessage() ).append( " | " );
658                }
659            }
660    
661            // no authentication method succeeded (user is still null)
662            String msg = getMessage( "OWSPROXY_UNAUTHORIZED_USER", sb );
663            throw new WrongCredentialsException( msg );
664    
665        }
666    
667        private boolean isImageRequested( OGCWebServiceRequest request ) {
668            boolean imageReq = false;
669    
670            if ( request instanceof GetMap ) {
671                imageReq = ( (GetMap) request ).getExceptions().indexOf( "image" ) > -1
672                           || ( (GetMap) request ).getFormat().indexOf( "image" ) > -1;
673            } else if ( request instanceof GetLegendGraphic ) {
674                imageReq = ( (GetLegendGraphic) request ).getExceptions().indexOf( "image" ) > -1
675                           || ( (GetLegendGraphic) request ).getFormat().indexOf( "image" ) > -1;
676            } else if ( request instanceof GetCoverage ) {
677                String format = ( (GetCoverage) request ).getOutput().getFormat().getCode();
678                imageReq = MimeTypeMapper.isKnownImageType( "image/" + format );
679            }
680    
681            LOG.logDebug( "authorization problems expected to be returned as image: ", imageReq );
682    
683            return imageReq;
684        }
685    
686    }