/*---------------- FILE HEADER ------------------------------------------
This file is part of deegree.
Copyright (C) 2001-2006 by:
University of Bonn
http://www.giub.uni-bonn.de/deegree/
lat/lon GmbH
http://www.lat-lon.de
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact:
Andreas Poth
lat/lon GmbH
Aennchenstr. 19
53177 Bonn
Germany
E-Mail: poth@lat-lon.de
Klaus Greve
Department of Geography
University of Bonn
Meckenheimer Allee 166
53115 Bonn
Germany
E-Mail: klaus.greve@uni-bonn.de
---------------------------------------------------------------------------*/
package org.deegree.portal.standard.context.control;
import java.io.IOException;
import java.net.URL;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.deegree.enterprise.control.AbstractListener;
import org.deegree.enterprise.control.RPCStruct;
import org.deegree.enterprise.control.RPCUtils;
import org.deegree.framework.log.ILogger;
import org.deegree.framework.log.LoggerFactory;
import org.deegree.framework.util.StringTools;
import org.deegree.framework.xml.NamespaceContext;
import org.deegree.framework.xml.XMLFragment;
import org.deegree.framework.xml.XMLParsingException;
import org.deegree.framework.xml.XMLTools;
import org.deegree.model.crs.CoordinateSystem;
import org.deegree.model.spatialschema.Envelope;
import org.deegree.model.spatialschema.GeometryFactory;
import org.deegree.model.spatialschema.Point;
import org.deegree.ogcbase.BaseURL;
import org.deegree.ogcbase.CommonNamespaces;
import org.deegree.ogcwebservices.OWSUtils;
import org.deegree.portal.Constants;
import org.deegree.portal.PortalException;
import org.deegree.portal.context.ContextException;
import org.deegree.portal.context.General;
import org.deegree.portal.context.GeneralExtension;
import org.deegree.portal.context.ViewContext;
import org.xml.sax.SAXException;
/**
* This exception shall be thrown when a session(ID) will be used that has been expired.
*
* @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a>
* @author last edited by: $Author: mays $
*
* @version 1.1, $Revision: 1.18 $, $Date: 2006/11/30 11:54:21 $
*
* @since 1.1
*/
abstract public class AbstractContextListener extends AbstractListener {
private static ILogger LOG = LoggerFactory.getLogger( AbstractContextListener.class );
private static final NamespaceContext nsContext = CommonNamespaces.getNamespaceContext();
/**
* gets the user name assigned to the passed session ID from an authentication service. If no
* user is assigned to the session ID <tt>null</tt> will be returned. If the session is closed
* or expired an exception will be thrown
*
* @param sessionId
* @return name of the user assigned to the passed session ID
* @throws XMLParsingException
* @throws SAXException
* @throws IOException
*/
protected String getUserName( String sessionId )
throws XMLParsingException, IOException, SAXException {
HttpSession session = ( (HttpServletRequest) getRequest() ).getSession( true );
ViewContext vc = (ViewContext) session.getAttribute( Constants.CURRENTMAPCONTEXT );
if( vc == null ){
return null;
}
GeneralExtension ge = vc.getGeneral().getExtension();
String userName = null;
if ( sessionId != null && ge.getAuthentificationSettings() != null) {
LOG.logDebug( "try getting user from WAS/sessionID" );
BaseURL baseUrl = ge.getAuthentificationSettings().getAuthentificationURL();
String url = OWSUtils.validateHTTPGetBaseURL( baseUrl.getOnlineResource().toExternalForm() );
StringBuffer sb = new StringBuffer( url );
sb.append( "request=DescribeUser&SESSIONID=" ).append( sessionId );
XMLFragment xml = new XMLFragment();
xml.load( new URL( sb.toString() ) );
userName = XMLTools.getRequiredNodeAsString( xml.getRootElement(), "/User/UserName",
nsContext );
} else {
LOG.logDebug( "try getting user from getUserPrincipal()" );
if ( ( (HttpServletRequest) getRequest() ).getUserPrincipal() != null ) {
userName = ( (HttpServletRequest) getRequest() ).getUserPrincipal().getName();
if ( userName.indexOf( "\\" ) > 1 ) {
String[] us = StringTools.toArray( userName, "\\", false );
userName = us[us.length-1];
}
}
}
LOG.logDebug( "userName: " + userName );
return userName;
}
/**
* reads the users session ID.<br>
* first the PRC will be parsed for a 'sessionID' element. If not present
* the sessionID will be read from the users session. If even the user's
* HTTP session does not contain a sessionID, it will be tried to get it
* from the WAS registered to the current context. If no WAS available
* <code>null</code> will be returned.
*
* @param struct
* @return the users session id
* @throws IOException
* @throws SAXException
* @throws XMLParsingException
*/
protected String readSessionID( RPCStruct struct )
throws XMLParsingException, SAXException, IOException {
String sid = RPCUtils.getRpcPropertyAsString( struct, "sessionID" );
if ( sid == null ) {
LOG.logDebug( "try getting sessionID from HTTP session" );
HttpSession session = ( (HttpServletRequest) getRequest() ).getSession();
sid = (String) session.getAttribute( "SESSIONID" );
}
if ( sid == null ) {
// try get SessionID from WAS if user name is available
// in this case it is assumed that a user's name can be determined
// evaluating the requests userPrincipal that will be available if
// the user has been logged in to the the server (or network)
String userName = getUserName( null );
if ( userName != null ) {
LOG.logDebug( "try getting sessionID by authorizing current user: " + userName );
HttpSession session = ( (HttpServletRequest) getRequest() ).getSession( true );
ViewContext vc = (ViewContext) session.getAttribute( Constants.CURRENTMAPCONTEXT );
GeneralExtension ge = vc.getGeneral().getExtension();
if ( ge.getAuthentificationSettings() != null ) {
BaseURL baseUrl = ge.getAuthentificationSettings().getAuthentificationURL();
StringBuffer sb = new StringBuffer( 500 );
String addr = baseUrl.getOnlineResource().toExternalForm();
sb.append( OWSUtils.validateHTTPGetBaseURL( addr ) );
sb.append( "SERVICE=WAS&VERSION=1.0.0&REQUEST=GetSession&" );
sb.append( "AUTHMETHOD=urn:x-gdi-nrw:authnMethod:1.0:password&CREDENTIALS=" );
sb.append( userName );
LOG.logDebug( "authentificat user: ", sb.toString() );
HttpClient client = new HttpClient();
GetMethod meth = new GetMethod( sb.toString() );
client.executeMethod( meth );
sid = meth.getResponseBodyAsString();
session.setAttribute( "SESSIONID", sid );
}
}
}
LOG.logDebug( "sessionID: " + sid );
return sid;
}
/**
* Convenience method to extract the boundig box from an rpc fragment.
*
* @param bboxStruct
* the <code>RPCStruct</code> containing the bounding box. For example,
* <code><member><name>boundingBox</name>etc...</code>.
*
* @return an envelope with the boundaries defined in the rpc structure
*/
protected Envelope extractBBox( RPCStruct bboxStruct ) {
Double minx = (Double) bboxStruct.getMember( Constants.RPC_BBOXMINX ).getValue();
Double miny = (Double) bboxStruct.getMember( Constants.RPC_BBOXMINY ).getValue();
Double maxx = (Double) bboxStruct.getMember( Constants.RPC_BBOXMAXX ).getValue();
Double maxy = (Double) bboxStruct.getMember( Constants.RPC_BBOXMAXY ).getValue();
Envelope bbox = GeometryFactory.createEnvelope( minx.doubleValue(), miny.doubleValue(),
maxx.doubleValue(), maxy.doubleValue(),
null );
return bbox;
}
/**
* changes the bounding box of a given view context
*
* @param vc
* the view context to be changed
* @param bbox
* the new bounding box
* @throws PortalException
*/
public static final void changeBBox( ViewContext vc, Envelope bbox )
throws PortalException {
General gen = vc.getGeneral();
CoordinateSystem cs = gen.getBoundingBox()[0].getCoordinateSystem();
Point[] p = new Point[] { GeometryFactory.createPoint( bbox.getMin(), cs ),
GeometryFactory.createPoint( bbox.getMax(), cs ) };
try {
gen.setBoundingBox( p );
} catch ( ContextException e ) {
throw new PortalException( "Error setting new BBOX \n"
+ StringTools.stackTraceToString( e.getStackTrace() ) );
}
}
}
/* ********************************************************************
Changes to this class. What the people have been up to:
$Log: AbstractContextListener.java,v $
Revision 1.18 2006/11/30 11:54:21 mays
change request in getUserName from "&ID=" to "&SESSIONID="
Revision 1.17 2006/10/17 20:31:18 poth
*** empty log message ***
Revision 1.16 2006/10/05 15:07:46 mays
bug fix : validateHTTPGetBaseURL
Revision 1.15 2006/09/12 13:59:25 poth
*** empty log message ***
Revision 1.14 2006/09/01 11:24:17 taddei
fixed NPE in getUserName
Revision 1.13 2006/08/30 11:51:50 poth
support for sessionID authentification/authorization added
Revision 1.12 2006/08/30 08:36:46 poth
bug fix - set logger to be static
Revision 1.11 2006/08/29 20:18:09 poth
code for initial accessing a session ID added
Revision 1.10 2006/08/29 19:54:14 poth
footer corrected
Revision 1.9 2006/08/29 19:18:16 poth
reading session ID from RPC centralized
Revision 1.8 2006/08/24 16:25:09 poth
parsing of DescribeUser response adapted
Revision 1.7 2006/06/22 06:55:02 poth
enabled reading user principals having '\' in its name by just using the part after the last '\'
Revision 1.6 2006/05/23 14:27:49 poth
support for UserPrincipal added if no sessionId is set
********************************************************************** */