Skip to content

Commit d23aad0

Browse files
committed
allowRepeatAttributeName settings added in order to support AttributeStatements with Attribute elements with the same name
1 parent cfd0005 commit d23aad0

5 files changed

Lines changed: 36 additions & 5 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,10 @@ $advancedSettings = array(
488488
// will be accepted.
489489
'destinationStrictlyMatches' => false,
490490

491+
// If true, the toolkit will not raised an error when the Statement Element
492+
// contain atribute elements with name duplicated
493+
'allowRepeatAttributeName' => false,
494+
491495
// If true, SAMLResponses with an InResponseTo value will be rejectd if not
492496
// AuthNRequest ID provided to the validation method.
493497
'rejectUnsolicitedResponsesWithInResponseTo' => false,

advanced_settings_example.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@
9191
// will be accepted.
9292
'destinationStrictlyMatches' => false,
9393

94+
// If true, the toolkit will not raised an error when the Statement Element
95+
// contain atribute elements with name duplicated
96+
'allowRepeatAttributeName' => false,
97+
9498
// If true, SAMLResponses with an InResponseTo value will be rejectd if not
9599
// AuthNRequest ID provided to the validation method.
96100
'rejectUnsolicitedResponsesWithInResponseTo' => false,

src/Saml2/Response.php

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,9 @@ private function _getAttributesByKeyName($keyName = "Name")
804804
{
805805
$attributes = array();
806806
$entries = $this->_queryAssertion('/saml:AttributeStatement/saml:Attribute');
807+
808+
$security = $this->_settings->getSecurityData();
809+
$allowRepeatAttributeName = $security['allowRepeatAttributeName'];
807810
/** @var $entry DOMNode */
808811
foreach ($entries as $entry) {
809812
$attributeKeyNode = $entry->attributes->getNamedItem($keyName);
@@ -812,10 +815,12 @@ private function _getAttributesByKeyName($keyName = "Name")
812815
}
813816
$attributeKeyName = $attributeKeyNode->nodeValue;
814817
if (in_array($attributeKeyName, array_keys($attributes))) {
815-
throw new ValidationError(
816-
"Found an Attribute element with duplicated ".$keyName,
817-
ValidationError::DUPLICATED_ATTRIBUTE_NAME_FOUND
818-
);
818+
if (!$allowRepeatAttributeName) {
819+
throw new ValidationError(
820+
"Found an Attribute element with duplicated ".$keyName,
821+
ValidationError::DUPLICATED_ATTRIBUTE_NAME_FOUND
822+
);
823+
}
819824
}
820825
$attributeValues = array();
821826
foreach ($entry->childNodes as $childNode) {
@@ -824,7 +829,12 @@ private function _getAttributesByKeyName($keyName = "Name")
824829
$attributeValues[] = $childNode->nodeValue;
825830
}
826831
}
827-
$attributes[$attributeKeyName] = $attributeValues;
832+
833+
if (in_array($attributeKeyName, array_keys($attributes))) {
834+
$attributes[$attributeKeyName] = array_merge($attributes[$attributeKeyName], $attributeValues);
835+
} else {
836+
$attributes[$attributeKeyName] = $attributeValues;
837+
}
828838
}
829839
return $attributes;
830840
}

src/Saml2/Settings.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,11 @@ private function _addDefaultValues()
397397
$this->_security['destinationStrictlyMatches'] = false;
398398
}
399399

400+
// Allow duplicated Attribute Names
401+
if (!isset($this->_security['allowRepeatAttributeName'])) {
402+
$this->_security['allowRepeatAttributeName'] = false;
403+
}
404+
400405
// InResponseTo
401406
if (!isset($this->_security['rejectUnsolicitedResponsesWithInResponseTo'])) {
402407
$this->_security['rejectUnsolicitedResponsesWithInResponseTo'] = false;

tests/src/OneLogin/Saml2/ResponseTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,14 @@ public function testGetAttributes()
631631
} catch (ValidationError $e) {
632632
$this->assertContains('Found an Attribute element with duplicated Name', $e->getMessage());
633633
}
634+
635+
$settingsDir = TEST_ROOT .'/settings/';
636+
include $settingsDir.'settings1.php';
637+
$settingsInfo['security']['allowRepeatAttributeName'] = true;
638+
$settings2 = new Settings($settingsInfo);
639+
$response5 = new Response($settings2, $xml4);
640+
$attrs = $response5->getAttributes();
641+
$this->assertEquals([0 => "test", 1 => "test2"], $attrs['uid']);
634642
}
635643

636644
/**

0 commit comments

Comments
 (0)