diff --git a/docs/simplesamlphp-changelog.txt b/docs/simplesamlphp-changelog.txt
index b3e6f07873069bc6412c38ebc458cb80fee0a1b4..faeae606bd15d7a0ad5fc6b784ba4f6bb90a0363 100644
--- a/docs/simplesamlphp-changelog.txt
+++ b/docs/simplesamlphp-changelog.txt
@@ -34,6 +34,8 @@ See the upgrade notes for specific information about upgrading.
   * Removed www/auth/login-auto.php.
   * Removed www/auth/login-feide.php.
   * Removed optional parameters from `SimpleSAML_XHTML_Template::getLanguage()`.
+  * Removed functions from `SAML2_Assertion`: `get/setDestination`, `get/setInResponseTo`.
+    Replaced with `setSubjectConfirmation`.
 
 ### SAML 2 IdP
 
diff --git a/lib/SAML2/Assertion.php b/lib/SAML2/Assertion.php
index 768795d57fcf64aa6219d9d4f45df510d37571c2..76c1b96388b9eb727bcec24876acd4df9a2414fb 100644
--- a/lib/SAML2/Assertion.php
+++ b/lib/SAML2/Assertion.php
@@ -78,24 +78,6 @@ class SAML2_Assertion implements SAML2_SignedElement {
 	private $notOnOrAfter;
 
 
-	/**
-	 * The destination URL for this assertion.
-	 *
-	 * @var string|NULL
-	 */
-	private $destination;
-
-
-	/**
-	 * The id of the request this assertion is sent as a response to.
-	 *
-	 * This should be NULL if this isn't a response to a request.
-	 *
-	 * @var string|NULL
-	 */
-	private $inResponseTo;
-
-
 	/**
 	 * The set of audiences that are allowed to receive this assertion.
 	 *
@@ -203,6 +185,14 @@ class SAML2_Assertion implements SAML2_SignedElement {
 	private $requiredEncAttributes;
 
 
+	/**
+	 * The SubjectConfirmation elements of the Subject in the assertion.
+	 *
+	 * @var array  Array of SAML2_XML_saml_SubjectConfirmation elements.
+	 */
+	private $SubjectConfirmation;
+
+
 	/**
 	 * Constructor for SAML 2 assertions.
 	 *
@@ -218,6 +208,7 @@ class SAML2_Assertion implements SAML2_SignedElement {
 		$this->nameFormat = SAML2_Const::NAMEFORMAT_UNSPECIFIED;
 		$this->certificates = array();
 		$this->AuthenticatingAuthority = array();
+		$this->SubjectConfirmation = array();
 
 		if ($xml === NULL) {
 			return;
@@ -283,38 +274,10 @@ class SAML2_Assertion implements SAML2_SignedElement {
 		$subjectConfirmation = SAML2_Utils::xpQuery($subject, './saml_assertion:SubjectConfirmation');
 		if (empty($subjectConfirmation)) {
 			throw new Exception('Missing <saml:SubjectConfirmation> in <saml:Subject>.');
-		} elseif (count($subjectConfirmation) > 1) {
-			throw new Exception('More than one <saml:SubjectConfirmation> in <saml:Subject>.');
 		}
-		$subjectConfirmation = $subjectConfirmation[0];
-		$subjectConfirmation = new SAML2_XML_saml_SubjectConfirmation($subjectConfirmation);
 
-		if ($subjectConfirmation->Method !== SAML2_Const::CM_BEARER) {
-			throw new Exception('Unsupported subject confirmation method: ' . var_export($method, TRUE));
-		}
-
-		$confirmationData = $subjectConfirmation->SubjectConfirmationData;
-		if ($confirmationData === NULL) {
-			return;
-		}
-
-		if ($confirmationData->NotBefore !== NULL) {
-			$notBefore = $confirmationData->NotBefore;
-			if ($this->notBefore === NULL || $this->notBefore < $notBefore) {
-				$this->notBefore = $notBefore;
-			}
-		}
-		if ($confirmationData->NotOnOrAfter !== NULL) {
-			$notOnOrAfter = $confirmationData->NotOnOrAfter;
-			if ($this->notOnOrAfter === NULL || $this->notOnOrAfter > $notOnOrAfter) {
-				$this->notOnOrAfter = $notOnOrAfter;
-			}
-		}
-		if ($confirmationData->InResponseTo !== NULL) {
-			$this->inResponseTo = $confirmationData->InResponseTo;
-		}
-		if ($confirmationData->Recipient !== NULL) {
-			$this->destination = $confirmationData->Recipient;
+		foreach ($subjectConfirmation as $sc) {
+			$this->SubjectConfirmation[] = new SAML2_XML_saml_SubjectConfirmation($sc);
 		}
 	}
 
@@ -763,32 +726,6 @@ class SAML2_Assertion implements SAML2_SignedElement {
 	}
 
 
-	/**
-	 * Retrieve the destination URL of this assertion.
-	 *
-	 * This function returns NULL if there are no restrictions on which URL can
-	 * receive the assertion.
-	 *
-	 * @return string|NULL  The destination URL of this assertion.
-	 */
-	public function getDestination() {
-
-		return $this->destination;
-	}
-
-
-	/**
-	 * Set the destination URL of this assertion.
-	 *
-	 * @return string|NULL  The destination URL of this assertion.
-	 */
-	public function setDestination($destination) {
-		assert('is_string($destination) || is_null($destination)');
-
-		$this->destination = $destination;
-	}
-
-
 	/**
 	 * Set $EncryptedAttributes if attributes will send encrypted
 	 *
@@ -799,33 +736,6 @@ class SAML2_Assertion implements SAML2_SignedElement {
 	}
 
 
-	/**
-	 * Retrieve the request this assertion is sent in response to.
-	 *
-	 * Can be NULL, in which case this assertion isn't sent in response to a specific request.
-	 *
-	 * @return string|NULL  The id of the request this assertion is sent in response to.
-	 */
-	public function getInResponseTo() {
-
-		return $this->inResponseTo;
-	}
-
-
-	/**
-	 * Set the request this assertion is sent in response to.
-	 *
-	 * Can be set to NULL, in which case this assertion isn't sent in response to a specific request.
-	 *
-	 * @param string|NULL $inResponseTo  The id of the request this assertion is sent in response to.
-	 */
-	public function setInResponseTo($inResponseTo) {
-		assert('is_string($inResponseTo) || is_null($inResponseTo)');
-
-		$this->inResponseTo = $inResponseTo;
-	}
-
-
 	/**
 	 * Retrieve the audiences that are allowed to receive this assertion.
 	 *
@@ -1028,6 +938,27 @@ class SAML2_Assertion implements SAML2_SignedElement {
 	}
 
 
+	/**
+	 * Retrieve the SubjectConfirmation elements we have in our Subject element.
+	 *
+	 * @return array  Array of SAML2_XML_saml_SubjectConfirmation elements.
+	 */
+	public function getSubjectConfirmation() {
+		return $this->SubjectConfirmation;
+	}
+
+
+	/**
+	 * Set the SubjectConfirmation elements that should be included in the assertion.
+	 *
+	 * @param array $SubjectConfirmation Array of SAML2_XML_saml_SubjectConfirmation elements.
+	 */
+	public function setSubjectConfirmation(array $SubjectConfirmation) {
+
+		$this->SubjectConfirmation = $SubjectConfirmation;
+	}
+
+
 	/**
 	 * Retrieve the private key we should use to sign the assertion.
 	 *
@@ -1159,22 +1090,9 @@ class SAML2_Assertion implements SAML2_SignedElement {
 
 		SAML2_Utils::addNameId($subject, $this->nameId);
 
-		$sc = new SAML2_XML_saml_SubjectConfirmation();
-		$sc->Method = SAML2_Const::CM_BEARER;
-		$sc->SubjectConfirmationData = new SAML2_XML_saml_SubjectConfirmationData();
-		$sc->SubjectConfirmationData->Recipient = $this->destination;
-
-		if ($this->notOnOrAfter !== NULL) {
-			$sc->SubjectConfirmationData->NotOnOrAfter = $this->notOnOrAfter;
-		}
-		if ($this->destination !== NULL) {
-			$sc->SubjectConfirmationData->Recipient = $this->destination;
+		foreach ($this->SubjectConfirmation as $sc) {
+			$sc->toXML($subject);
 		}
-		if ($this->inResponseTo !== NULL) {
-			$sc->SubjectConfirmationData->InResponseTo = $this->inResponseTo;
-		}
-
-		$sc->toXML($subject);
 	}
 
 
diff --git a/modules/exampleattributeserver/www/attributeserver.php b/modules/exampleattributeserver/www/attributeserver.php
index abce3e17ea8d72da2d331ce0a2046c2cd3429b82..19cbee44ee295e3dba9133965d2d8af7fe988c41 100644
--- a/modules/exampleattributeserver/www/attributeserver.php
+++ b/modules/exampleattributeserver/www/attributeserver.php
@@ -63,15 +63,22 @@ if (count($returnAttributes) === 0) {
 
 /* $returnAttributes contains the attributes we should return. Send them. */
 $assertion = new SAML2_Assertion();
-$assertion->setDestination($endpoint);
 $assertion->setIssuer($idpEntityId);
 $assertion->setNameId($query->getNameId());
 $assertion->setNotBefore(time());
 $assertion->setNotOnOrAfter(time() + 5*60);
-$assertion->setInResponseTo($query->getId());
 $assertion->setValidAudiences(array($spEntityId));
 $assertion->setAttributes($returnAttributes);
 $assertion->setAttributeNameFormat($attributeNameFormat);
+
+$sc = new SAML2_XML_saml_SubjectConfirmation();
+$sc->Method = SAML2_Const::CM_BEARER;
+$sc->SubjectConfirmationData = new SAML2_XML_saml_SubjectConfirmationData();
+$sc->SubjectConfirmationData->NotOnOrAfter = time() + 5*60;
+$sc->SubjectConfirmationData->Recipient = $endpoint;
+$sc->SubjectConfirmationData->InResponseTo = $query->getId();
+$assertion->setSubjectConfirmation(array($sc));
+
 sspmod_saml_Message::addSign($idpMetadata, $spMetadata, $assertion);
 
 $response = new SAML2_Response();
diff --git a/modules/saml/lib/IdP/SAML2.php b/modules/saml/lib/IdP/SAML2.php
index a4a7266008e3463c60786227dac63eb470092f4c..68b285fb0cb178604978c4fdedbe373787ce8418 100644
--- a/modules/saml/lib/IdP/SAML2.php
+++ b/modules/saml/lib/IdP/SAML2.php
@@ -37,7 +37,6 @@ class sspmod_saml_IdP_SAML2 {
 		$idpMetadata = $idp->getConfig();
 
 		$assertion = self::buildAssertion($idpMetadata, $spMetadata, $state);
-		$assertion->setInResponseTo($requestId);
 		
 		if (isset($state['saml:AuthenticatingAuthority'])) {
 			$assertion->setAuthenticatingAuthority($state['saml:AuthenticatingAuthority']);
@@ -554,7 +553,6 @@ class sspmod_saml_IdP_SAML2 {
 		}
 
 		$a->setIssuer($idpMetadata->getString('entityid'));
-		$a->setDestination($state['saml:ConsumerURL']);
 		$a->setValidAudiences(array($spMetadata->getString('entityid')));
 
 		$a->setNotBefore(time() - 30);
@@ -576,6 +574,14 @@ class sspmod_saml_IdP_SAML2 {
 
 		$a->setSessionIndex(SimpleSAML_Utilities::generateID());
 
+		$sc = new SAML2_XML_saml_SubjectConfirmation();
+		$sc->Method = SAML2_Const::CM_BEARER;
+		$sc->SubjectConfirmationData = new SAML2_XML_saml_SubjectConfirmationData();
+		$sc->SubjectConfirmationData->NotOnOrAfter = time() + $assertionLifetime;
+		$sc->SubjectConfirmationData->Recipient = $state['saml:ConsumerURL'];
+		$sc->SubjectConfirmationData->InResponseTo = $state['saml:RequestId'];
+		$a->setSubjectConfirmation(array($sc));
+
 		/* Add attributes. */
 
 		if ($spMetadata->getBoolean('simplesaml.attributes', TRUE)) {
diff --git a/modules/saml/lib/Message.php b/modules/saml/lib/Message.php
index 8178b6c4d147547f2363c54be509e2ae2a59a029..88f9d2455647588a0be14c9804946b57ac882a86 100644
--- a/modules/saml/lib/Message.php
+++ b/modules/saml/lib/Message.php
@@ -487,16 +487,6 @@ class sspmod_saml_Message {
 		/* At least one valid signature found. */
 
 
-		/* Make sure that some fields in the assertion matches the same fields in the message. */
-
-		$asrtInResponseTo = $assertion->getInResponseTo();
-		$msgInResponseTo = $response->getInResponseTo();
-		if ($asrtInResponseTo !== NULL && $msgInResponseTo !== NULL) {
-			if ($asrtInResponseTo !== $msgInResponseTo) {
-				throw new SimpleSAML_Error_Exception('InResponseTo in assertion did not match InResponseTo in message.');
-			}
-		}
-
 		/* Validate Response-element destination. */
 
 		$currentURL = SimpleSAML_Utilities::selfURLNoQuery();
@@ -524,12 +514,6 @@ class sspmod_saml_Message {
 			throw new SimpleSAML_Error_Exception('Received an assertion with a session that has expired. Check clock synchronization on IdP and SP.');
 		}
 
-		$destination = $assertion->getDestination();
-		if ($destination !== $currentURL) {
-			throw new Exception('Recipient in assertion doesn\'t match the current URL. Recipient is "' .
-				$destination . '", current URL is "' . $currentURL . '".');
-		}
-
 		$validAudiences = $assertion->getValidAudiences();
 		if ($validAudiences !== NULL) {
 			$spEntityId = $spMetadata->getString('entityid');
@@ -539,6 +523,39 @@ class sspmod_saml_Message {
 			}
 		}
 
+		$found = FALSE;
+		$lastError = 'No SubjectConfirmation element in Subject.';
+		foreach ($assertion->getSubjectConfirmation() as $sc) {
+			if ($sc->Method !== SAML2_Const::CM_BEARER) {
+				$lastError = 'Invalid Method on SubjectConfirmation: ' . var_export($sc->Method, TRUE);
+				continue;
+			}
+			$scd = $sc->SubjectConfirmationData;
+			if ($scd->NotBefore && $scd->NotBefore > time() + 60) {
+				$lastError = 'NotBefore in SubjectConfirmationData is in the future: ' . $scd->NotBefore;
+				continue;
+			}
+			if ($scd->NotOnOrAfter && $scd->NotOnOrAfter <= time() - 60) {
+				$lastError = 'NotOnOrAfter in SubjectConfirmationData is in the past: ' . $scd->NotOnOrAfter;
+				continue;
+			}
+			if ($scd->Recipient !== NULL && $scd->Recipient !== $currentURL) {
+				$lastError = 'Recipient in SubjectConfirmationData does not match the current URL. Recipient is ' .
+					var_export($scd->Recipient, TRUE) . ', current URL is ' . var_export($currentURL, TRUE) . '.';
+				continue;
+			}
+			if ($scd->InResponseTo !== NULL && $response->getInResponseTo() !== NULL && $scd->InResponseTo !== $response->getInResponseTo()) {
+				$lastError = 'InResponseTo in SubjectConfirmationData does not match the Response. Response has ' .
+					var_export($response->getInResponseTo(), TRUE) . ', SubjectConfirmationData has ' . var_export($scd->InResponseTo, TRUE) . '.';
+				continue;
+			}
+			$found = TRUE;
+			break;
+		}
+		if (!$found) {
+			throw new SimpleSAML_Error_Exception('Error validating SubjectConfirmation in Assertion: ' . $lastError);
+		}
+
 		/* As far as we can tell, the assertion is valid. */