diff --git a/config-templates/config.php b/config-templates/config.php
index 812e93985b4a04f4de85bb778fe4b789e539ba9f..386d58f6103208056bc6915f1baa4b0a88add1dd 100644
--- a/config-templates/config.php
+++ b/config-templates/config.php
@@ -172,6 +172,16 @@ $config = array (
 	'default-saml20-idp' => 'https://openidp.feide.no',
 	'default-shib13-idp' => NULL,
 	'default-wsfed-idp'	=> 'urn:federation:pingfederate:localhost',
+
+	/*
+	 * Default IdP discovery service urls.
+	 * This option sets the default IdP discovery service URLs for the SPs in this installation. These
+	 * URLs can be overridden on a per SP basis by setting this option in the metadata for the SP.
+	 *
+	 * By default simpleSAMLphp will use its builtin IdP discovery service.
+	 */
+	'idpdisco.url.shib13' => NULL,
+	'idpdisco.url.saml2' => NULL,
 	
 	/*
 	 * IdP Discovery service look configuration. 
diff --git a/docs/source/simplesamlphp-sp.xml b/docs/source/simplesamlphp-sp.xml
index 51d272805981951d039568bb7e2efb8b1c1f36ec..bfb6d04cab303940c86a0c93e90651937f93582b 100644
--- a/docs/source/simplesamlphp-sp.xml
+++ b/docs/source/simplesamlphp-sp.xml
@@ -286,6 +286,19 @@
               PHP page.</para>
             </glossdef>
           </glossentry>
+
+          <glossentry>
+            <glossterm>idpdisco.url</glossterm>
+
+            <glossdef>
+              <para>Set which IdP discovery service this SP should use. If
+              this is unset, the IdP discovery service specified in the global
+              option <literal>idpdisco.url.saml2</literal> in
+              <filename>config/config.php</filename> will be used. If that one
+              is also unset, the builtin default discovery service will be
+              used.</para>
+            </glossdef>
+          </glossentry>
         </glosslist>
       </section>
 
@@ -704,6 +717,19 @@
               PHP page.</para>
             </glossdef>
           </glossentry>
+
+          <glossentry>
+            <glossterm>idpdisco.url</glossterm>
+
+            <glossdef>
+              <para>Set which IdP discovery service this SP should use. If
+              this is unset, the IdP discovery service specified in the global
+              option <literal>idpdisco.url.shib13</literal> in
+              <filename>config/config.php</filename> will be used. If that one
+              is also unset, the builtin default discovery service will be
+              used.</para>
+            </glossdef>
+          </glossentry>
         </glosslist>
       </section>
     </section>
diff --git a/www/admin/metadata.php b/www/admin/metadata.php
index 610d6f1e67193f8588e1f91beca8d87ebf89150a..298496dc1524d33fd234fd0dfc46645f48ec4304 100644
--- a/www/admin/metadata.php
+++ b/www/admin/metadata.php
@@ -29,7 +29,7 @@ try {
 		foreach ($metalist AS $entityid => $mentry) {
 			$results[$entityid] = SimpleSAML_Utilities::checkAssocArrayRules($mentry,
 				array('entityid', 'host'),
-				array('request.signing','certificate','privatekey', 'privatekey_pass', 'NameIDFormat', 'ForceAuthn', 'AuthnContextClassRef', 'SPNameQualifier', 'attributemap', 'attributealter', 'attributes', 'metadata.sign.enable', 'metadata.sign.privatekey', 'metadata.sign.privatekey_pass', 'metadata.sign.certificate')
+				array('request.signing','certificate','privatekey', 'privatekey_pass', 'NameIDFormat', 'ForceAuthn', 'AuthnContextClassRef', 'SPNameQualifier', 'attributemap', 'attributealter', 'attributes', 'metadata.sign.enable', 'metadata.sign.privatekey', 'metadata.sign.privatekey_pass', 'metadata.sign.certificate', 'idpdisco.url')
 			);
 		}
 		$et->data['metadata.saml20-sp-hosted'] = $results;
@@ -79,7 +79,7 @@ try {
 		foreach ($metalist AS $entityid => $mentry) {
 			$results[$entityid] = SimpleSAML_Utilities::checkAssocArrayRules($mentry,
 				array('entityid', 'host'),
-				array('NameIDFormat', 'ForceAuthn', 'metadata.sign.enable', 'metadata.sign.privatekey', 'metadata.sign.privatekey_pass', 'metadata.sign.certificate')
+				array('NameIDFormat', 'ForceAuthn', 'metadata.sign.enable', 'metadata.sign.privatekey', 'metadata.sign.privatekey_pass', 'metadata.sign.certificate', 'idpdisco.url')
 			);
 		}
 		$et->data['metadata.shib13-sp-hosted'] = $results;
diff --git a/www/saml2/sp/initSSO.php b/www/saml2/sp/initSSO.php
index d2de59f323dce845a66b012664350d806f787d21..1e0a77f5af5a455327ca531ad129be4d71d200b6 100644
--- a/www/saml2/sp/initSSO.php
+++ b/www/saml2/sp/initSSO.php
@@ -29,6 +29,11 @@ try {
 	$idpentityid = isset($_GET['idpentityid']) ? $_GET['idpentityid'] : $config->getValue('default-saml20-idp') ;
 	$spentityid = isset($_GET['spentityid']) ? $_GET['spentityid'] : $metadata->getMetaDataCurrentEntityID();
 
+	if($idpentityid === NULL) {
+		/* We are going to need the SP metadata to determine which IdP discovery service we should use. */
+		$spmetadata = $metadata->getMetaData($spentityid);
+	}
+
 } catch (Exception $exception) {
 	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'METADATA', $exception);
 }
@@ -41,7 +46,18 @@ if ($idpentityid == null) {
 
 	SimpleSAML_Logger::info('SAML2.0 - SP.initSSO: No chosen or default IdP, go to SAML2disco');
 
-	SimpleSAML_Utilities::redirect('/' . $config->getBaseURL() . 'saml2/sp/idpdisco.php', array(
+	/* Which IdP discovery service should we use? Can be set in SP metadata or in global configuration.
+	 * Falling back to builtin discovery service.
+	 */
+	if(array_key_exists('idpdisco.url', $spmetadata)) {
+		$discourl = $spmetadata['idpdisco.url'];
+	} elseif($config->getValue('idpdisco.url.saml2', NULL) !== NULL) {
+		$discourl = $config->getValue('idpdisco.url.saml2', NULL);
+	} else {
+		$discourl = '/' . $config->getBaseURL() . 'saml2/sp/idpdisco.php';
+	}
+
+	SimpleSAML_Utilities::redirect($discourl, array(
 		'entityID' => $spentityid,
 		'return' => SimpleSAML_Utilities::selfURL(),
 		'returnIDParam' => 'idpentityid')
diff --git a/www/shib13/sp/initSSO.php b/www/shib13/sp/initSSO.php
index 6cb61bc05ae38a245a5d1d76ff51fc9383f847bc..00bc56846a19bf905874170f7b16c312f5187388 100644
--- a/www/shib13/sp/initSSO.php
+++ b/www/shib13/sp/initSSO.php
@@ -29,6 +29,12 @@ try {
 	$idpentityid = isset($_GET['idpentityid']) ? $_GET['idpentityid'] : $config->getValue('default-shib13-idp') ;
 	$spentityid = isset($_GET['spentityid']) ? $_GET['spentityid'] : $metadata->getMetaDataCurrentEntityID('shib13-sp-hosted');
 
+	if($idpentityid === NULL) {
+		/* We are going to need the SP metadata to determine which IdP discovery service we should use. */
+		$spmetadata = $metadata->getMetaDataCurrent('shib13-sp-hosted');
+	}
+
+
 } catch (Exception $exception) {
 	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'METADATA', $exception);
 }
@@ -40,12 +46,23 @@ if (!isset($session) || !$session->isValid('shib13') ) {
 	if ($idpentityid == null) {
 	
 		SimpleSAML_Logger::info('Shib1.3 - SP.initSSO: No chosen or default IdP, go to Shib13disco');
-	
-		$returnURL = urlencode(SimpleSAML_Utilities::selfURL());
-		$discservice = '/' . $config->getBaseURL() . 'shib13/sp/idpdisco.php?entityID=' . $spentityid . 
-			'&return=' . $returnURL . '&returnIDParam=idpentityid';
-		SimpleSAML_Utilities::redirect($discservice);
-		
+
+		/* Which IdP discovery service should we use? Can be set in SP metadata or in global configuration.
+		 * Falling back to builtin discovery service.
+		 */
+		if(array_key_exists('idpdisco.url', $spmetadata)) {
+			$discservice = $spmetadata['idpdisco.url'];
+		} elseif($config->getValue('idpdisco.url.shib13', NULL) !== NULL) {
+			$discservice = $config->getValue('idpdisco.url.shib13', NULL);
+		} else {
+			$discservice = '/' . $config->getBaseURL() . 'shib13/sp/idpdisco.php';
+		}
+
+		SimpleSAML_Utilities::redirect($discservice, array(
+			'entityID' => $spentityid,
+			'return' => SimpleSAML_Utilities::selfURL(),
+			'returnIDParam' => 'idpentityid',
+			));
 	}