    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( "ConfigurableOWSProxyServletFilter: 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    }