[Mapbender-commits] r9836 - in trunk/mapbender: http/classes http_auth/http

svn_mapbender at osgeo.org svn_mapbender at osgeo.org
Tue Jan 2 06:14:46 PST 2018


Author: armin11
Date: 2018-01-02 06:14:46 -0800 (Tue, 02 Jan 2018)
New Revision: 9836

Modified:
   trunk/mapbender/http/classes/class_user.php
   trunk/mapbender/http_auth/http/index.php
Log:
New option to force http basic authentication  for wfs resources - default is digest

Modified: trunk/mapbender/http/classes/class_user.php
===================================================================
--- trunk/mapbender/http/classes/class_user.php	2017-12-21 08:59:36 UTC (rev 9835)
+++ trunk/mapbender/http/classes/class_user.php	2018-01-02 14:14:46 UTC (rev 9836)
@@ -670,7 +670,7 @@
 		$row = db_fetch_all($res);
 		if (count($row) == 1 && $row[0]['featuretype_id'] == null) {
 			//
-			new mb_exception("http_auth/index.php: Some featuretype is null - no anonymous access possible!");
+			new mb_notice("http_auth/index.php: Some featuretype is null - no anonymous access possible!");
 			return false;
 		}
 		//$e = new mb_exception("featuretype_id[0]: '".$row[0]['featuretype_id']."' - ".count($row));

Modified: trunk/mapbender/http_auth/http/index.php
===================================================================
--- trunk/mapbender/http_auth/http/index.php	2017-12-21 08:59:36 UTC (rev 9835)
+++ trunk/mapbender/http_auth/http/index.php	2018-01-02 14:14:46 UTC (rev 9836)
@@ -26,6 +26,20 @@
 
 $urlsToExclude = array();
 $postData = false;
+//default http auth type to digest
+$authType = 'digest';
+
+if (isset($_REQUEST["forceBasicAuth"]) && $_REQUEST["forceBasicAuth"] != "") {
+	$testMatch = $_REQUEST["forceBasicAuth"];	
+ 	if (!($testMatch == 'true')){ 
+		echo 'Parameter <b>forceBasicAuth</b> is not valid (true).<br/>'; 
+		die(); 		
+ 	} else {
+		$authType = 'basic';
+	}
+	$testMatch = NULL;
+}
+
 if (is_file(dirname(__FILE__) . "/../../conf/excludeproxyurls.conf"))
 {
     require_once(dirname(__FILE__) . "/../../conf/excludeproxyurls.conf");
@@ -158,72 +172,92 @@
 if ($anonymousAccess == true) {
 	$userId = PUBLIC_USER;
 } else {
-
-	//special for type of authentication ******************************
-	//control if digest auth is set, if not set, generate the challenge with getNonce()
-	if (empty($_SERVER['PHP_AUTH_DIGEST'])) {
-    	header('HTTP/1.1 401 Unauthorized');
-    	header('WWW-Authenticate: Digest realm="' . REALM .
-        '",qop="auth",nonce="' . getNonce() . '",opaque="' . md5(REALM) . '"');
-    	die('Text to send if user hits Cancel button');
-	}
-
-	//read out the header in an array
-	$requestHeaderArray = http_digest_parse($_SERVER['PHP_AUTH_DIGEST']);
-
-	//error if header could not be read
-	if (!($requestHeaderArray)) {
-    		echo 'Following Header information cannot be validated - check your clientsoftware!<br>';
-    		echo $_SERVER['PHP_AUTH_DIGEST'] . '<br>';
-    		die();
-	}
-
-	//get mb_username and email out of http_auth username string
-	$userIdentification = explode(';', $requestHeaderArray['username']);
-	$mbUsername = $userIdentification[0];
-	$mbEmail = $userIdentification[1]; //not given in all circumstances
-
-	$userInformation = getUserInfo($mbUsername, $mbEmail);
-
-	if ($userInformation[0] == '-1') {
-    		die('User with name: ' . $mbUsername . ' and email: ' . $mbEmail . ' not known to security proxy!');
-	}
-
-	if ($userInformation[1] == '') { //check if digest exists in db - if no digest exists it should be a null string!
-    		die('User with name: ' . $mbUsername . ' and email: ' . $mbEmail . ' has no digest - please set a new password and try again!');
-	}
-
-	//first check the stale!
-	if ($requestHeaderArray['nonce'] == getNonce()) {
-    		// Up-to-date nonce received
-    		$stale = false;
-	} else {
-    		// Stale nonce received (probably more than x seconds old)
-    		$stale = true;
-    		//give another chance to authenticate
-    		header('HTTP/1.1 401 Unauthorized');
-    		header('WWW-Authenticate: Digest realm="' . REALM . '",qop="auth",nonce="' . getNonce() . '",opaque="' . md5(REALM) . '" ,stale=true');
-	}
-	// generate the valid response to check the request of the client
-	$A1 = $userInformation[1];
-	$A2 = md5($_SERVER['REQUEST_METHOD'] . ':' . $requestHeaderArray['uri']);
-	$valid_response = $A1 . ':' . getNonce() . ':' . $requestHeaderArray['nc'];
-	$valid_response .= ':' . $requestHeaderArray['cnonce'] . ':' . $requestHeaderArray['qop'] . ':' . $A2;
-
-	$valid_response = md5($valid_response);
-
-	if ($requestHeaderArray['response'] != $valid_response) {//the user have to authenticate new - cause something in the authentication went wrong
-    	die('Authentication failed - sorry, you have to authenticate once more!');
-	}
-	//if we are here - authentication has been done well!
-	//let's do the proxy things (came from owsproxy.php):
-	//special for type of authentication ******************************
-
-	//user information
-	//define $userId from database information
-	$userId = $userInformation[0];
+	switch ($authType) {
+		case 'digest':
+			//special for type of authentication ******************************
+			//control if digest auth is set, if not set, generate the challenge with getNonce()
+			if (empty($_SERVER['PHP_AUTH_DIGEST'])) {
+    				header('HTTP/1.1 401 Unauthorized');
+    				header('WWW-Authenticate: Digest realm="' . REALM .
+        			'",qop="auth",nonce="' . getNonce() . '",opaque="' . md5(REALM) . '"');
+    				die('Text to send if user hits Cancel button');
+			}
+			//read out the header in an array
+			$requestHeaderArray = http_digest_parse($_SERVER['PHP_AUTH_DIGEST']);
+			//error if header could not be read
+			if (!($requestHeaderArray)) {
+    				echo 'Following Header information cannot be validated - check your clientsoftware!<br>';
+    				echo $_SERVER['PHP_AUTH_DIGEST'] . '<br>';
+    				die();
+			}
+			//get mb_username and email out of http_auth username string
+			$userIdentification = explode(';', $requestHeaderArray['username']);
+			$mbUsername = $userIdentification[0];
+			$mbEmail = $userIdentification[1]; //not given in all circumstances
+			$userInformation = getUserInfo($mbUsername, $mbEmail);
+			if ($userInformation[0] == '-1') {
+    				die('User with name: ' . $mbUsername . ' and email: ' . $mbEmail . ' not known to security proxy!');
+			}
+			if ($userInformation[1] == '') { //check if digest exists in db - if no digest exists it should be a null string!
+    				die('User with name: ' . $mbUsername . ' and email: ' . $mbEmail . ' has no digest - please set a new password and try again!');
+			}
+			//first check the stale!
+			if ($requestHeaderArray['nonce'] == getNonce()) {
+    				// Up-to-date nonce received
+    				$stale = false;
+			} else {
+    				// Stale nonce received (probably more than x seconds old)
+    				$stale = true;
+    				//give another chance to authenticate
+    				header('HTTP/1.1 401 Unauthorized');
+    				header('WWW-Authenticate: Digest realm="' . REALM . '",qop="auth",nonce="' . getNonce() . '",opaque="' . md5(REALM) . '" ,stale=true');
+			}
+			// generate the valid response to check the request of the client
+			$A1 = $userInformation[1];
+			$A2 = md5($_SERVER['REQUEST_METHOD'] . ':' . $requestHeaderArray['uri']);
+			$valid_response = $A1 . ':' . getNonce() . ':' . $requestHeaderArray['nc'];
+			$valid_response .= ':' . $requestHeaderArray['cnonce'] . ':' . $requestHeaderArray['qop'] . ':' . $A2;
+			$valid_response = md5($valid_response);
+			if ($requestHeaderArray['response'] != $valid_response) {//the user have to authenticate new - cause something in the authentication went wrong
+    				die('Authentication failed - sorry, you have to authenticate once more!');
+			}
+			//if we are here - authentication has been done well!
+			//let's do the proxy things (came from owsproxy.php):
+			//special for type of authentication ******************************
+			//user information
+			//define $userId from database information
+			$userId = $userInformation[0];
+			break;
+		case 'basic':
+			if (!isset($_SERVER['PHP_AUTH_USER'])) {
+    				header('WWW-Authenticate: Basic realm="' . REALM .'"');				
+				header('HTTP/1.1 401 Unauthorized');
+				die('Authentication failed - sorry, you have to authenticate once more!');
+			} else {
+				//get mb_username and email out of http_auth username string
+				$userIdentification = explode(';', $_SERVER['PHP_AUTH_USER']);
+				$mbUsername = $userIdentification[0];
+				$mbEmail = $userIdentification[1]; //not given in all circumstances
+				$userInformation = getUserInfo($mbUsername, $mbEmail);
+				if ($userInformation[0] == '-1') {
+    					die('User with name: ' . $mbUsername . ' and email: ' . $mbEmail . ' not known to security proxy!');
+				}
+				if ($userInformation[1] == '') { //check if digest exists in db - if no digest exists it should be a null string!
+    					die('User with name: ' . $mbUsername . ' and email: ' . $mbEmail . ' has no digest - please set a new password and try again!');
+				}
+				//check password
+				if ($userInformation[2] !== md5($_SERVER['PHP_AUTH_PW'])) {
+					die('HTTP Authentication failed for user: ' . $mbUsername.'!');
+				} else {
+					$userId = $userInformation[0];
+					//$e = new mb_exception("requesting userid: ".$userInformation[0]);
+				}	
+			}
+			break;
+		}//end switch	
+	//}
 }
-
+//$e = new mb_exception("authentication successful!");
 $layerId = $_REQUEST['layer_id'];
 $wfsId = $_REQUEST['wfs_id'];
 //new option for nested layers
@@ -231,7 +265,6 @@
 if (isset($_REQUEST["withChilds"]) && $_REQUEST["withChilds"] === "1") {
     $withChilds = true;
 }
-
 /*$query = new QueryHandler($postData);
 
 // an array with keys and values toLoserCase -> caseinsensitiv
@@ -278,14 +311,20 @@
 			$request = str_replace('?&','?',$request);
 			//TODO: following is not the standard way because ows has not to handle vsp!!!
 			$request = delTotalFromQuery("wfs_id",$request);
+			//add force basic to request!!!!! - not for capabilities?
+			if ($authType == 'basic') {
+				$extraParameter = "forceBasicAuth=true";
+			} else {
+				$extraParameter = false;
+			}
 			//don't allow get parameters in conjunction with post!
 			if ($postData !== false) {
 				$request = $arrayOnlineresources['wfs_getcapabilities'];
 			}
 			if (isset($auth)) {
-            			getWfsCapabilities($request, $auth);
+            			getWfsCapabilities($request, $extraParameter, $auth);
         		} else {
-            			getWfsCapabilities($request);
+            			getWfsCapabilities($request, $extraParameter);
         		}		
 		break;
 		case 'wms':
@@ -306,6 +345,9 @@
         		} else {
             			$requestFull .= $request . '&REQUEST=GetCapabilities&VERSION=1.1.1&SERVICE=WMS';
         		}
+			if ($authType == 'basic') {
+				$requestFull .= "&forceBasicAuth=true";
+			}
         		if (isset($auth)) {
             			getCapabilities($request, $requestFull, $auth);
         		} else {
@@ -514,11 +556,11 @@
 {
     $result = array();
     if (preg_match('#[@]#', $mbEmail)) {
-        $sql = "SELECT mb_user_id, mb_user_digest FROM mb_user where mb_user_name = $1 AND mb_user_email = $2";
+        $sql = "SELECT mb_user_id, mb_user_digest, mb_user_password FROM mb_user where mb_user_name = $1 AND mb_user_email = $2";
         $v = array($mbUsername, $mbEmail);
         $t = array("s", "s");
     } else {
-        $sql = "SELECT mb_user_id, mb_user_aldigest As mb_user_digest FROM mb_user where mb_user_name = $1";
+        $sql = "SELECT mb_user_id, mb_user_aldigest As mb_user_digest, mb_user_password FROM mb_user where mb_user_name = $1";
         $v = array($mbUsername);
         $t = array("s");
     }
@@ -528,6 +570,7 @@
     } else {
         $result[0] = $row['mb_user_id'];
         $result[1] = $row['mb_user_digest'];
+	$result[2] = $row['mb_user_password'];
     }
     return $result;
 }
@@ -905,17 +948,17 @@
 function registerUrl($url)
 {
     if (!in_array($url, $_SESSION["owsproxyUrls"]["url"])) {
-        $e = new mb_exception("Is noch net drin!");
+        //$e = new mb_exception("Is noch net drin!");
         $id = md5($url);
-        $e = new mb_exception("ID: " . $id . "  URL: " . $url . " will be written to session");
+        //$e = new mb_exception("ID: " . $id . "  URL: " . $url . " will be written to session");
         array_push($_SESSION["owsproxyUrls"]["url"], $url);
         array_push($_SESSION["owsproxyUrls"]["id"], $id);
     } else {
-        $e = new mb_exception("It was found! Search content and return ID!");
+        //$e = new mb_exception("It was found! Search content and return ID!");
         for ($i = 0; $i < count($_SESSION["owsproxyUrls"]["url"]); $i++) {
-            $e = new mb_exception("Content " . $i . " : proxyurl:" . $_SESSION["owsproxyUrls"]["url"][$i] . " - new: " . $url);
+            //$e = new mb_exception("Content " . $i . " : proxyurl:" . $_SESSION["owsproxyUrls"]["url"][$i] . " - new: " . $url);
             if ($url == $_SESSION["owsproxyUrls"]["url"][$i]) {
-                $e = new mb_exception("Identical! ID:" . $_SESSION["owsproxyUrls"]["id"][$i] . " will be used");
+                //$e = new mb_exception("Identical! ID:" . $_SESSION["owsproxyUrls"]["id"][$i] . " will be used");
                 $id = $_SESSION["owsproxyUrls"]["id"][$i];
             }
         }
@@ -956,7 +999,7 @@
     }
     //exchanging urls in some special fields
     //
-	//GetCapabilities, GetMap, GetFeatureInfo, GetLegendGraphics, ...
+    //GetCapabilities, GetMap, GetFeatureInfo, GetLegendGraphics, ...
     $capFromFascadeXmlObject->registerXPathNamespace("xlink", "http://www.w3.org/1999/xlink");
     //Mapping of urls for wms 1.1.1 which should be exchanged 
     $urlsToChange = array(
@@ -1003,13 +1046,58 @@
     return $httpAuthUrl;
 }
 
-function getWfsCapabilities($request, $auth = false)
+function getWfsCapabilities($request, $extraParameter, $auth = false)
 {
     global $arrayOnlineresources, $postData;
     global $sid, $serviceId, $wfsId;
-    $t = array(htmlentities(preg_replace('/\?$/','',$arrayOnlineresources["wfs_getcapabilities"])), htmlentities($arrayOnlineresources["wfs_getfeature"]),
-        htmlentities($arrayOnlineresources["wfs_describefeaturetype"]));
-    //$new = OWSPROXY . "/" . $sid . "/" . $serviceId . "?";
+    global $reqParams;
+    $urlsToChange = array();
+    switch ($reqParams['version']) {
+	case "2.0.0":
+	    $operations = array("GetCapabilities", "DescribeFeatureType", "GetFeature", "Transaction", "GetPropertyValue", "ListStoredQueries", "DescribeStoredQueries", "CreateStoredQuery", "DropStoredQuery");
+	    foreach($operations as $operation) {
+		$urlsToChange[] = '/wfs:WFS_Capabilities/ows:OperationsMetadata/ows:Operation[@name="'.$operation.'"]/ows:DCP/ows:HTTP/ows:Get/@xlink:href';
+		$urlsToChange[] = '/wfs:WFS_Capabilities/ows:OperationsMetadata/ows:Operation[@name="'.$operation.'"]/ows:DCP/ows:HTTP/ows:Post/@xlink:href';
+	    }
+	    $namespaces = array("ows" => "http://www.opengis.net/ows/1.1",
+				"wfs" => "http://www.opengis.net/wfs/2.0",
+				"xlink" => "http://www.w3.org/1999/xlink"
+	    );
+		break;
+	case "2.0.2":
+	    $operations = array("GetCapabilities", "DescribeFeatureType", "GetFeature", "Transaction", "GetPropertyValue", "ListStoredQueries", "DescribeStoredQueries", "CreateStoredQuery", "DropStoredQuery");
+	    foreach($operations as $operation) {
+		$urlsToChange[] = '/wfs:WFS_Capabilities/ows:OperationsMetadata/ows:Operation[@name="'.$operation.'"]/ows:DCP/ows:HTTP/ows:Get/@xlink:href';
+		$urlsToChange[] = '/wfs:WFS_Capabilities/ows:OperationsMetadata/ows:Operation[@name="'.$operation.'"]/ows:DCP/ows:HTTP/ows:Post/@xlink:href';
+	    }	    
+	    $namespaces = array("ows" => "http://www.opengis.net/ows/1.1",
+				"wfs" => "http://www.opengis.net/wfs/2.0",
+				"xlink" => "http://www.w3.org/1999/xlink"
+	    );
+		break;
+	case "1.1.0":
+	    $operations = array("GetCapabilities", "DescribeFeatureType", "GetFeature", "GetGmlObject", "Transaction");
+	    foreach($operations as $operation) {
+		$urlsToChange[] = '/wfs:WFS_Capabilities/ows:OperationsMetadata/ows:Operation[@name="'.$operation.'"]/ows:DCP/ows:HTTP/ows:Get/@xlink:href';
+		$urlsToChange[] = '/wfs:WFS_Capabilities/ows:OperationsMetadata/ows:Operation[@name="'.$operation.'"]/ows:DCP/ows:HTTP/ows:Post/@xlink:href';
+	    }	    
+	    $namespaces = array("ows" => "http://www.opengis.net/ows",
+				"wfs" => "http://www.opengis.net/wfs",
+				"xlink" => "http://www.w3.org/1999/xlink"
+	    );
+		break;
+	case "1.0.0":
+	    $operations = array("GetCapabilities", "DescribeFeatureType", "GetFeature", "Transaction");
+	    foreach($operations as $operation) {
+		$urlsToChange[] = '/wfs:WFS_Capabilities/wfs:Capability/wfs:Request/wfs:'.$operation.'/wfs:DCPType/wfs:HTTP/wfs:Get/@onlineResource';
+		$urlsToChange[] = '/wfs:WFS_Capabilities/wfs:Capability/wfs:Request/wfs:'.$operation.'/wfs:DCPType/wfs:HTTP/wfs:Post/@onlineResource';
+	    }
+	    $namespaces = array("wfs" => "http://www.opengis.net/wfs");
+		break;
+	default:
+		break;
+	
+    }
     //TODO - set to persistent url
     $owsproxyUrl = parse_url(OWSPROXY);
     if ($owsproxyUrl['port'] == '80' || $owsproxyUrl['port'] == '') {
@@ -1018,10 +1106,12 @@
 	$port = ":".$owsproxyUrl['port'];
     }
     $new = $owsproxyUrl['scheme'] . "://" .$owsproxyUrl['host']. $port . "/registry/wfs/" . $wfsId;# ."?";
-		
+    if ($extraParameter !== false) {
+	$new .= '?'.$extraParameter;
+    }
     if ($postData == false) {
-    	if (func_num_args() == 4) { //new for HTTP Authentication
-    	    $auth = func_get_arg(3);
+    	if (func_num_args() == 3) { //new for HTTP Authentication
+    	    $auth = func_get_arg(2);
     	    $d = new connector($request, $auth);
    	 } else {
     	    $d = new connector($request);
@@ -1034,19 +1124,54 @@
 		$postInterfaceObject->set('curlSendCustomHeaders',true);
 		$postInterfaceObject->set('httpPostData', $postData);
 		$postInterfaceObject->set('httpContentType','text/xml');
-		if (func_num_args() == 4) { //new for HTTP Authentication
-    	  		$auth = func_get_arg(3);
+		if (func_num_args() == 3) { //new for HTTP Authentication
+    	  		$auth = func_get_arg(2);
 			$postInterfaceObject->load($request, $auth);
 		} else {
 			$postInterfaceObject->load($request);
 		}		 
 		$wfsCaps = $postInterfaceObject->file;
     }
-    $r = str_replace($t, $new, $wfsCaps);
+
+    //load xml and replace urls
+    libxml_use_internal_errors(true);
+    try {
+        $capFromFascadeXmlObject = simplexml_load_string($wfsCaps);
+        if ($capFromFascadeXmlObject === false) {
+            foreach (libxml_get_errors() as $error) {
+                $err = new mb_exception("http_auth/index.php: " . $error->message);
+            }
+            throw new Exception("http_auth/index.php: " . 'Cannot parse Metadata XML!');
+            echo "<error>http_auth/index.php: Cannot parse WFS Capabilities XML!</error>";
+            die();
+        }
+    } catch (Exception $e) {
+        $err = new mb_exception("http_auth/index.php: " . $e->getMessage());
+        echo "<error>http_auth/index.php: " . $e->getMessage() . "</error>";
+        die();
+    }
+    //exchange via xpath
+    //register namespaces
+    
+    foreach($namespaces as $key => $value){
+	$capFromFascadeXmlObject->registerXPathNamespace($key, $value);
+    }
+    $test = $capFromFascadeXmlObject->xpath("");
+    //replace
+    foreach ($urlsToChange as $xpath) {
+	//$e = new mb_exception($xpath);
+        $href = $capFromFascadeXmlObject->xpath($xpath);
+	//$e = new mb_exception($href[0]);
+        $href[0][0] = $new;
+    }
+    header("Content-Type: application/xml");
+    echo $capFromFascadeXmlObject->asXML();
+    //TODO: check if the following is further needed
+    //$r = str_replace($t, $new, $wfsCaps);
     //delete trailing amp; 's
-    $r = str_replace('amp;', '', $r);
-    header("Content-Type: application/xml");
-    echo $r;
+    //$r = str_replace('amp;', '', $r);
+    //header("Content-Type: application/xml");
+    //echo $r;
 }
 
 /**



More information about the Mapbender_commits mailing list