diff --git a/docs/simplesamlphp-idp.txt b/docs/simplesamlphp-idp.txt
index e68824a68a153f08e0e5c2c801ab28f89f7e49af..661705d45e707cc94cc1f76d59b00b579590bfe9 100644
--- a/docs/simplesamlphp-idp.txt
+++ b/docs/simplesamlphp-idp.txt
@@ -689,6 +689,8 @@ redirect.validate
 
 
 
+
+
 Configuring metadata for a Shibboleth 1.3 IdP
 ---------------------------------------------
 
@@ -717,6 +719,9 @@ used as the scope.
      */
     'scopedattributes' => array('eduPersonPrincipalName'),
 
+
+
+
 Test IdP
 --------
 
@@ -752,7 +757,19 @@ improvements or contribute with code or plugins of your own.
     [Visit and contribute to the simpleSAMLphp wiki](https://ow.feide.no/simplesamlphp:start)
 
 
-A. Writing your own authentication module
+
+A. IdP-first setup
+------------------
+
+If you do not want to start the SSO flow at the SP, you may use the IdP-first setup. To do this, redirect the user to the SSOService endpoint on the IdP with one parameter `spentityid` that match the SP EntityId that the user should be logged into.
+
+Here is an example of such an url:
+
+	https://sp.example.org/simplesaml/saml2/idp/SSOService.php?spentityid=dev.andreas.feide.no
+
+
+
+B. Writing your own authentication module
 ----------------------------------------------
 
 You can write your own authentication module. Just copy one of the
diff --git a/docs/simplesamlphp-sp.txt b/docs/simplesamlphp-sp.txt
index 5434372d3ac8184cfa81cdaad092489c4f451ac6..c6f998259c5e8e039e41ad047f46910da7cdbf1c 100644
--- a/docs/simplesamlphp-sp.txt
+++ b/docs/simplesamlphp-sp.txt
@@ -165,6 +165,9 @@ idpdisco.url
     one is also unset, the builtin default discovery service will be
     used.
 
+RelayState
+:	This may be a relative or absolute URL on the Service Provider that the user should be redirected to after successful authentication. This parameter MUST be used if you are using an IdP-first setup with SAML 2.0, where no AuthNRequest is sent.
+
 privatekey
 :   File name of private key to be used for signing messages.
 
diff --git a/lib/SimpleSAML/Bindings/SAML20/HTTPRedirect.php b/lib/SimpleSAML/Bindings/SAML20/HTTPRedirect.php
index ffb55787a06020910f28ea2e962acc17da8c988a..23e6bcc93d1ccf4056ec37b7ddc3bf2f3d0de715 100644
--- a/lib/SimpleSAML/Bindings/SAML20/HTTPRedirect.php
+++ b/lib/SimpleSAML/Bindings/SAML20/HTTPRedirect.php
@@ -243,8 +243,6 @@ class SimpleSAML_Bindings_SAML20_HTTPRedirect {
 			SimpleSAML_Utilities::redirect($redirectURL);
 		
 		}
-
-		
 		
 	}
 
diff --git a/lib/SimpleSAML/XML/SAML20/AuthnResponse.php b/lib/SimpleSAML/XML/SAML20/AuthnResponse.php
index 72cf1cb2fdb83c644fa0091597ccf9633e66597f..a9245352b11f2b57229524b4997d71b964e2d6cc 100644
--- a/lib/SimpleSAML/XML/SAML20/AuthnResponse.php
+++ b/lib/SimpleSAML/XML/SAML20/AuthnResponse.php
@@ -718,8 +718,9 @@ class SimpleSAML_XML_SAML20_AuthnResponse extends SimpleSAML_XML_AuthnResponse {
 			$nameid = $this->generateNameID($nameidformat, $nameIdValue, $spnamequalifier);
 		}
 		
-
-
+		$inresponsetoText = '';
+		if (!empty($inresponseto)) $inresponsetoText = 'InResponseTo="' . htmlspecialchars($inresponseto). '" ';
+		
 		$assertion = "";
 		if ($status === 'Success') {
 			$assertion = '<saml:Assertion Version="2.0"
@@ -729,7 +730,7 @@ class SimpleSAML_XML_SAML20_AuthnResponse extends SimpleSAML_XML_AuthnResponse {
 			' . $nameid . ' 
 			<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
 				<saml:SubjectConfirmationData NotOnOrAfter="' . $assertionExpire . '"
-					InResponseTo="' . htmlspecialchars($inresponseto). '"
+					' . $inresponsetoText . '
 					Recipient="' . htmlspecialchars($destination) . '"/>
 			</saml:SubjectConfirmation>
 		</saml:Subject>
@@ -763,7 +764,7 @@ class SimpleSAML_XML_SAML20_AuthnResponse extends SimpleSAML_XML_AuthnResponse {
 			xmlns:xs="http://www.w3.org/2001/XMLSchema"
 			xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 			ID="' . $id . '"
-			InResponseTo="' . htmlspecialchars($inresponseto) . '" Version="2.0"
+			' . $inresponsetoText . ' Version="2.0"
 			IssueInstant="' . $issueInstant . '"
 			Destination="' . htmlspecialchars($destination) . '">
 			<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">' . htmlspecialchars($issuer) . '</saml:Issuer>
diff --git a/www/saml2/idp/SSOService.php b/www/saml2/idp/SSOService.php
index 191d892d8e786b546683c8d2c5ff9f6a926b03e7..e6865f88225764dded261655688ec30d14cf5b8c 100644
--- a/www/saml2/idp/SSOService.php
+++ b/www/saml2/idp/SSOService.php
@@ -34,6 +34,11 @@ if (!$config->getValue('enable.saml20-idp', false))
 	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'NOACCESS');
 
 
+/*
+ * Initiate some variables
+ */
+$isPassive = FALSE;
+
 /*
  * If the SAMLRequest query parameter is set, we got an incoming Authentication Request 
  * at this interface.
@@ -145,6 +150,19 @@ if (isset($_GET['SAMLRequest'])) {
 	$authProcState = SimpleSAML_Auth_ProcessingChain::fetchProcessedState($authProcId);
 	$requestcache = $authProcState['core:saml20-idp:requestcache'];
 
+/**
+ * If the spentityid parameter is provided, we will fallback to a unsolited response to the SP.
+ */
+} elseif(array_key_exists('spentityid', $_GET)) {
+	
+	/* Creating a request cache, even though there was no request, and adding the
+	 * information that is neccessary to be able to respond with an unsolited response
+	 */
+	$requestcache = array(
+		'Issuer' => $_GET['spentityid'],
+	);
+
+
 } else {
 	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'SSOSERVICEPARAMS');
 }
@@ -322,14 +340,17 @@ if($needAuth && !$isPassive) {
 		// Right now the list is used for SAML 2.0 only.
 		$session->add_sp_session($spentityid);
 		
+		$requestID = NULL; $relayState = NULL;
+		if (array_key_exists('RequestID', $requestcache)) $requestID = $requestcache['RequestID'];
+		if (array_key_exists('RelayState', $requestcache)) $relayState = $requestcache['RelayState'];
 		
 		// Generate an SAML 2.0 AuthNResponse message
 		$ar = new SimpleSAML_XML_SAML20_AuthnResponse($config, $metadata);
-		$authnResponseXML = $ar->generate($idpentityid, $spentityid, $requestcache['RequestID'], null, $attributes);
+		$authnResponseXML = $ar->generate($idpentityid, $spentityid, $requestID, null, $attributes);
 	
 		// Sending the AuthNResponse using HTTP-Post SAML 2.0 binding
 		$httppost = new SimpleSAML_Bindings_SAML20_HTTPPost($config, $metadata);
-		$httppost->sendResponse($authnResponseXML, $idmetaindex, $spentityid, $requestcache['RelayState']);
+		$httppost->sendResponse($authnResponseXML, $idmetaindex, $spentityid, $relayState);
 		
 	} catch(Exception $exception) {
 		SimpleSAML_Utilities::fatalError($session->getTrackID(), 'GENERATEAUTHNRESPONSE', $exception);
diff --git a/www/saml2/sp/AssertionConsumerService.php b/www/saml2/sp/AssertionConsumerService.php
index 30026d8f7cf17ec813ef753c98e7aedc77cc548c..ba3cf812f01c2a1c9f4f27c0467bf288750c0865 100644
--- a/www/saml2/sp/AssertionConsumerService.php
+++ b/www/saml2/sp/AssertionConsumerService.php
@@ -70,7 +70,8 @@ if (empty($_POST['SAMLResponse']))
 try {
 	
 	$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
-
+	$spmetadata = $metadata->getMetaDataCurrent();
+	
 	$binding = new SimpleSAML_Bindings_SAML20_HTTPPost($config, $metadata);
 	$authnResponse = $binding->decodeResponse($_POST);
 	
@@ -83,7 +84,12 @@ try {
 		/* Fall back to RelayState. */
 		$info = array();
 		$info['RelayState'] = $authnResponse->getRelayState();
-		if(!isset($info['RelayState'])) {
+		if(empty($info['RelayState'])) {
+			if (array_key_exists('RelayState', $spmetadata)) {
+				$info['RelayState'] = $spmetadata['RelayState'];
+			}
+		}
+		if(empty($info['RelayState'])) {
 			/* RelayState missing. */
 			SimpleSAML_Utilities::fatalError($session->getTrackID(), 'NORELAYSTATE');
 		}
@@ -111,7 +117,7 @@ try {
 	$idpentityid = $authnResponse->getIssuer();
 	
 	$idpmetadata = $metadata->getMetaData($idpentityid, 'saml20-idp-remote');
-	$spmetadata = $metadata->getMetaDataCurrent();
+
 	
 	
 	/*