From d09ac7b4d1330b8d6c1065edacea7a33af0bc4c9 Mon Sep 17 00:00:00 2001
From: Olav Morken <olav.morken@uninett.no>
Date: Mon, 2 Sep 2013 12:20:14 +0000
Subject: [PATCH] Add support for sending AttributeConsumingService and
 AssertionConsumerServiceIndex.

This patch adds support for sending the AttributeConsumingService and
AssertionConsumerServiceIndex attributes in the authentication request.

Thanks to Dale Clarke for providing this patch!

git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@3266 44740490-163a-0410-bde0-09ae8108e29a
---
 lib/SAML2/AuthnRequest.php   | 55 ++++++++++++++++++++++++++++++------
 modules/saml/lib/Message.php |  3 ++
 2 files changed, 50 insertions(+), 8 deletions(-)

diff --git a/lib/SAML2/AuthnRequest.php b/lib/SAML2/AuthnRequest.php
index 8d57760b1..b536dce24 100644
--- a/lib/SAML2/AuthnRequest.php
+++ b/lib/SAML2/AuthnRequest.php
@@ -51,7 +51,7 @@ class SAML2_AuthnRequest extends SAML2_Request {
 	*/
 
 	private $RequesterID = array();
-	
+
 	/**
 	 * The URL of the asertion consumer service where the response should be delivered.
 	 *
@@ -68,6 +68,13 @@ class SAML2_AuthnRequest extends SAML2_Request {
 	private $protocolBinding;
 
 
+	/**
+	 * The index of the AttributeConsumingService.
+	 *
+	 * @var int|NULL
+	 */
+	private $attributeConsumingServiceIndex;
+
 	/**
 	 * The index of the AssertionConsumerService.
 	 *
@@ -121,6 +128,10 @@ class SAML2_AuthnRequest extends SAML2_Request {
 			$this->protocolBinding = $xml->getAttribute('ProtocolBinding');
 		}
 
+		if ($xml->hasAttribute('AttributeConsumingServiceIndex')) {
+			$this->attributeConsumingServiceIndex = (int)$xml->getAttribute('AttributeConsumingServiceIndex');
+		}
+
 		if ($xml->hasAttribute('AssertionConsumerServiceIndex')) {
 			$this->assertionConsumerServiceIndex = (int)$xml->getAttribute('AssertionConsumerServiceIndex');
 		}
@@ -164,7 +175,7 @@ class SAML2_AuthnRequest extends SAML2_Request {
 		$scoping = SAML2_Utils::xpQuery($xml, './saml_protocol:Scoping');
 		if (!empty($scoping)) {
 			$scoping =$scoping[0];
-			
+
 			if ($scoping->hasAttribute('ProxyCount')) {
 				$this->ProxyCount = (int)$scoping->getAttribute('ProxyCount');
 			}
@@ -176,7 +187,7 @@ class SAML2_AuthnRequest extends SAML2_Request {
 				}
 				$this->IDPList[] = $idpEntry->getAttribute('ProviderID');
 			}
-		
+
 			$requesterIDs = SAML2_Utils::xpQuery($scoping, './saml_protocol:RequesterID');
 			foreach ($requesterIDs as $requesterID) {
 				$this->RequesterID[] = trim($requesterID->textContent);
@@ -343,6 +354,27 @@ class SAML2_AuthnRequest extends SAML2_Request {
 		$this->protocolBinding = $protocolBinding;
 	}
 
+	/**
+	 * Retrieve the value of the AttributeConsumingServiceIndex attribute.
+	 *
+	 * @return int|NULL  The AttributeConsumingServiceIndex attribute.
+	 */
+	public function getAttributeConsumingServiceIndex() {
+		return $this->attributeConsumingServiceIndex;
+	}
+
+
+	/**
+	 * Set the value of the AttributeConsumingServiceIndex attribute.
+	 *
+	 * @param int|NULL $attributeConsumingServiceIndex  The AttributeConsumingServiceIndex attribute.
+	 */
+	public function setAttributeConsumingServiceIndex($attributeConsumingServiceIndex) {
+		assert('is_int($attributeConsumingServiceIndex) || is_null($attributeConsumingServiceIndex)');
+
+		$this->attributeConsumingServiceIndex = $attributeConsumingServiceIndex;
+	}
+
 
 	/**
 	 * Retrieve the value of the AssertionConsumerServiceIndex attribute.
@@ -357,7 +389,7 @@ class SAML2_AuthnRequest extends SAML2_Request {
 	/**
 	 * Set the value of the AssertionConsumerServiceIndex attribute.
 	 *
-	 * @param string|NULL $assertionConsumerServiceIndex  The AssertionConsumerServiceIndex attribute.
+	 * @param int|NULL $assertionConsumerServiceIndex  The AssertionConsumerServiceIndex attribute.
 	 */
 	public function setAssertionConsumerServiceIndex($assertionConsumerServiceIndex) {
 		assert('is_int($assertionConsumerServiceIndex) || is_null($assertionConsumerServiceIndex)');
@@ -427,12 +459,19 @@ class SAML2_AuthnRequest extends SAML2_Request {
 			$root->setAttribute('IsPassive', 'true');
 		}
 
-		if ($this->assertionConsumerServiceURL !== NULL) {
-			$root->setAttribute('AssertionConsumerServiceURL', $this->assertionConsumerServiceURL);
+		if ($this->assertionConsumerServiceIndex !== NULL) {
+			$root->setAttribute('AssertionConsumerServiceIndex', $this->assertionConsumerServiceIndex);
+		} else {
+			if ($this->assertionConsumerServiceURL !== NULL) {
+				$root->setAttribute('AssertionConsumerServiceURL', $this->assertionConsumerServiceURL);
+			}
+			if ($this->protocolBinding !== NULL) {
+				$root->setAttribute('ProtocolBinding', $this->protocolBinding);
+			}
 		}
 
-		if ($this->protocolBinding !== NULL) {
-			$root->setAttribute('ProtocolBinding', $this->protocolBinding);
+		if ($this->attributeConsumingServiceIndex !== NULL) {
+			$root->setAttribute('AttributeConsumingServiceIndex', $this->attributeConsumingServiceIndex);
 		}
 
 		if (!empty($this->nameIdPolicy)) {
diff --git a/modules/saml/lib/Message.php b/modules/saml/lib/Message.php
index 68c2edefc..4ffcfcacc 100644
--- a/modules/saml/lib/Message.php
+++ b/modules/saml/lib/Message.php
@@ -415,6 +415,9 @@ class sspmod_saml_Message {
 
 		$ar->setIssuer($spMetadata->getString('entityid'));
 
+		$ar->setAssertionConsumerServiceIndex($spMetadata->getInteger('AssertionConsumerServiceIndex', NULL));
+		$ar->setAttributeConsumingServiceIndex($spMetadata->getInteger('AttributeConsumingServiceIndex', NULL));
+
 		if ($spMetadata->hasValue('AuthnContextClassRef')) {
 			$accr = $spMetadata->getArrayizeString('AuthnContextClassRef');
 			$ar->setRequestedAuthnContext(array('AuthnContextClassRef' => $accr));
-- 
GitLab