Skip to content
Permalink
Browse files
[BUGFIX] 9234 - WFS client doesn't expose Header Authorization
Like for the others OGC providers: WMS and WCS, the user can set the
login and password to access to WFS protected data. But the QGIS WFS
provider doen't expose header authorization. It doesn't use login and
password.

This patch set header authorization for all WFS connexion if login and
password are set.
And I think this patch has to be backported to release_2-2, because QGIS
can't acces to protected WFS data.
  • Loading branch information
rldhont committed Apr 3, 2014
1 parent a43bd62 commit a98df93a0db86db0b41431b44d0d5835c7c892a6
@@ -65,7 +65,7 @@ QgsGml::~QgsGml()
{
}

int QgsGml::getFeatures( const QString& uri, QGis::WkbType* wkbType, QgsRectangle* extent )
int QgsGml::getFeatures( const QString& uri, QGis::WkbType* wkbType, QgsRectangle* extent, const QString& userName, const QString& password )
{
mUri = uri;
mWkbType = wkbType;
@@ -79,6 +79,10 @@ int QgsGml::getFeatures( const QString& uri, QGis::WkbType* wkbType, QgsRectangl
mExtent.setMinimal();

QNetworkRequest request( mUri );
if ( !userName.isNull() || !password.isNull() )
{
request.setRawHeader( "Authorization", "Basic " + QString( "%1:%2" ).arg( userName ).arg( password ).toAscii().toBase64() );
}
QNetworkReply* reply = QgsNetworkAccessManager::instance()->get( request );

connect( reply, SIGNAL( finished() ), this, SLOT( setFinished() ) );
@@ -56,7 +56,7 @@ class CORE_EXPORT QgsGml : public QObject
* @param extent retrieved extents
* @return 0 in case of success
*/
int getFeatures( const QString& uri, QGis::WkbType* wkbType, QgsRectangle* extent = 0 );
int getFeatures( const QString& uri, QGis::WkbType* wkbType, QgsRectangle* extent = 0, const QString& userName = QString(), const QString& password = QString() );

/** Read from GML data. Constructor uri param is ignored
* Supports only UTF-8, UTF-16, ISO-8859-1, ISO-8859-1 XML encodings.
@@ -134,17 +134,34 @@ QString QgsWFSCapabilities::uriGetFeature( QString typeName, QString crsString,

//add a wfs layer to the map
uri += "SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=" + typeName + crsString + bBoxString + filterString;

//add authorization information
if ( mUri.hasParam( "username" ) && mUri.hasParam( "password" ) )
{
uri += "&username="+mUri.param( "username" );
uri += "&password="+mUri.param( "password" );
}
QgsDebugMsg( uri );
return uri;
}

void QgsWFSCapabilities::setAuthorization( QNetworkRequest &request ) const
{
QgsDebugMsg( "entered" );
if ( mUri.hasParam( "username" ) && mUri.hasParam( "password" ) )
{
QgsDebugMsg( "setAuthorization " + mUri.param( "username" ) );
request.setRawHeader( "Authorization", "Basic " + QString( "%1:%2" ).arg( mUri.param( "username" ) ).arg( mUri.param( "password" ) ).toAscii().toBase64() );
}
}

void QgsWFSCapabilities::requestCapabilities()
{
mErrorCode = QgsWFSCapabilities::NoError;
mErrorMessage.clear();

QNetworkRequest request( uriGetCapabilities() );
setAuthorization( request );
request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true );
mCapabilitiesReply = QgsNetworkAccessManager::instance()->get( request );
connect( mCapabilitiesReply, SIGNAL( finished() ), this, SLOT( capabilitiesReplyFinished() ) );
@@ -171,6 +188,7 @@ void QgsWFSCapabilities::capabilitiesReplyFinished()
{
QgsDebugMsg( "redirecting to " + redirect.toUrl().toString() );
QNetworkRequest request( redirect.toUrl() );
setAuthorization( request );
request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork );
request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true );

@@ -16,6 +16,7 @@
#define QGSWFSCAPABILITIES_H

#include <QObject>
#include <QNetworkRequest>

#include "qgsrectangle.h"
#include "qgsdatasourceuri.h"
@@ -72,6 +73,9 @@ class QgsWFSCapabilities : public QObject
//! return parsed capabilities - requestCapabilities() must be called before
GetCapabilities capabilities() { return mCaps; }

//! set authorization header
void setAuthorization( QNetworkRequest &request ) const;

signals:
void gotCapabilities();

@@ -90,6 +94,12 @@ class QgsWFSCapabilities : public QObject
GetCapabilities mCaps;
ErrorCode mErrorCode;
QString mErrorMessage;

//! Username for basic http authentication
QString mUserName;

//! Password for basic http authentication
QString mPassword;
};

#endif // QGSWFSCAPABILITIES_H
@@ -27,6 +27,7 @@
#include "qgscoordinatereferencesystem.h"
#include "qgswfsfeatureiterator.h"
#include "qgswfsprovider.h"
#include "qgsdatasourceuri.h"
#include "qgsspatialindex.h"
#include "qgslogger.h"
#include "qgsmessagelog.h"
@@ -89,6 +90,9 @@ QgsWFSProvider::QgsWFSProvider( const QString& uri )
mSourceCRS.createFromOgcWmsCrs( srsname );
}

mAuth.mUserName = parameterFromUrl( "username" );
mAuth.mPassword = parameterFromUrl( "password" );

//fetch attributes of layer and type of its geometry attribute
//WBC 111221: extracting geometry type here instead of getFeature allows successful
//layer creation even when no features are retrieved (due to, e.g., BBOX or FILTER)
@@ -682,7 +686,10 @@ int QgsWFSProvider::getFeatureGET( const QString& uri, const QString& geometryAt
}

//if ( dataReader.getWFSData() != 0 )
if ( dataReader.getFeatures( uri, &mWKBType, &mExtent ) != 0 )
QUrl getFeatureUrl( uri );
getFeatureUrl.removeQueryItem( "username" );
getFeatureUrl.removeQueryItem( "password" );
if ( dataReader.getFeatures( getFeatureUrl.toString(), &mWKBType, &mExtent, mAuth.mUserName, mAuth.mPassword ) != 0 )
{
QgsDebugMsg( "getWFSData returned with error" );
return 1;
@@ -751,10 +758,13 @@ int QgsWFSProvider::describeFeatureTypeGET( const QString& uri, QString& geometr
mNetworkRequestFinished = false;

QUrl describeFeatureUrl( uri );
describeFeatureUrl.removeQueryItem( "username" );
describeFeatureUrl.removeQueryItem( "password" );
describeFeatureUrl.removeQueryItem( "SRSNAME" );
describeFeatureUrl.removeQueryItem( "REQUEST" );
describeFeatureUrl.addQueryItem( "REQUEST", "DescribeFeatureType" );
QNetworkRequest request( describeFeatureUrl.toString() );
mAuth.setAuthorization( request );
QNetworkReply* reply = QgsNetworkAccessManager::instance()->get( request );

connect( reply, SIGNAL( finished() ), this, SLOT( networkRequestFinished() ) );
@@ -1338,6 +1348,8 @@ bool QgsWFSProvider::sendTransactionDocument( const QDomDocument& doc, QDomDocum
mNetworkRequestFinished = false;

QUrl typeDetectionUri( dataSourceUri() );
typeDetectionUri.removeQueryItem( "username" );
typeDetectionUri.removeQueryItem( "password" );
typeDetectionUri.removeQueryItem( "REQUEST" );
typeDetectionUri.removeQueryItem( "TYPENAME" );
typeDetectionUri.removeQueryItem( "BBOX" );
@@ -1349,6 +1361,7 @@ bool QgsWFSProvider::sendTransactionDocument( const QDomDocument& doc, QDomDocum
QString serverUrl = typeDetectionUri.toString();

QNetworkRequest request( serverUrl );
mAuth.setAuthorization( request );
request.setHeader( QNetworkRequest::ContentTypeHeader, "text/xml" );
QNetworkReply* reply = QgsNetworkAccessManager::instance()->post( request, doc.toByteArray( -1 ) );

@@ -1475,7 +1488,11 @@ void QgsWFSProvider::getLayerCapabilities()

QString uri = dataSourceUri();
uri.replace( QString( "GetFeature" ), QString( "GetCapabilities" ) );
QNetworkRequest request( uri );
QUrl getCapabilitiesUrl( uri );
getCapabilitiesUrl.removeQueryItem( "username" );
getCapabilitiesUrl.removeQueryItem( "password" );
QNetworkRequest request( getCapabilitiesUrl.toString() );
mAuth.setAuthorization( request );
QNetworkReply* reply = QgsNetworkAccessManager::instance()->get( request );

connect( reply, SIGNAL( finished() ), this, SLOT( networkRequestFinished() ) );
@@ -27,9 +27,32 @@
#include "qgsvectorlayer.h"
#include "qgswfsfeatureiterator.h"

#include <QNetworkRequest>

class QgsRectangle;
class QgsSpatialIndex;

// TODO: merge with QgsWmsAuthorization?
struct QgsWFSAuthorization
{
QgsWFSAuthorization( const QString& userName = QString(), const QString& password = QString() ) : mUserName( userName ), mPassword( password ) {}

//! set authorization header
void setAuthorization( QNetworkRequest &request ) const
{
if ( !mUserName.isNull() || !mPassword.isNull() )
{
request.setRawHeader( "Authorization", "Basic " + QString( "%1:%2" ).arg( mUserName ).arg( mPassword ).toAscii().toBase64() );
}
}

//! Username for basic http authentication
QString mUserName;

//! Password for basic http authentication
QString mPassword;
};

/**A provider reading features from a WFS server*/
class QgsWFSProvider: public QgsVectorDataProvider
{
@@ -130,6 +153,9 @@ class QgsWFSProvider: public QgsVectorDataProvider
private:
bool mNetworkRequestFinished;
friend class QgsWFSFeatureSource;

//! http authorization details
QgsWFSAuthorization mAuth;

protected:
/**Thematic attributes*/

0 comments on commit a98df93

Please sign in to comment.