Skip to content

Commit c412ae5

Browse files
committed
Assert that assertions containing an AuthnStatement also contain a subject
1 parent 7c05908 commit c412ae5

File tree

6 files changed

+116
-65
lines changed

6 files changed

+116
-65
lines changed

src/XML/saml/Assertion.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
use function array_merge;
3232
use function array_pop;
3333
use function array_values;
34+
use function count;
3435
use function strval;
3536

3637
/**
@@ -84,9 +85,22 @@ public function __construct(
8485
Assert::true(
8586
$subject || !empty($statements),
8687
"Either a <saml:Subject> or some statement must be present in a <saml:Assertion>",
88+
ProtocolViolationException::class,
8789
);
8890
Assert::maxCount($statements, C::UNBOUNDED_LIMIT);
8991
Assert::allIsInstanceOf($statements, AbstractStatementType::class);
92+
93+
$authnStatements = array_values(array_filter($statements, function ($statement) {
94+
return $statement instanceof AuthnStatement;
95+
}));
96+
97+
if (count($authnStatements) > 0) {
98+
Assert::notNull(
99+
$subject,
100+
"Assertions containing an <AuthnStatement> element MUST contain a <Subject> element.",
101+
ProtocolViolationException::class,
102+
);
103+
}
90104
}
91105

92106

tests/SAML2/Assertion/Validation/ConstraintValidator/NotBeforeTest.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
use SimpleSAML\SAML2\XML\saml\AuthnStatement;
2222
use SimpleSAML\SAML2\XML\saml\Conditions;
2323
use SimpleSAML\SAML2\XML\saml\Issuer;
24+
use SimpleSAML\SAML2\XML\saml\NameID;
25+
use SimpleSAML\SAML2\XML\saml\Subject;
2426
use SimpleSAML\Test\SAML2\Constants as C;
2527
use SimpleSAML\XML\Type\IDValue;
2628

@@ -36,6 +38,9 @@ final class NotBeforeTest extends TestCase
3638
/** @var \SimpleSAML\SAML2\XML\saml\Issuer */
3739
private static Issuer $issuer;
3840

41+
/** @var \SimpleSAML\SAML2\XML\saml\Subject */
42+
private static Subject $subject;
43+
3944
/** @var \SimpleSAML\SAML2\XML\saml\AuthnStatement */
4045
private static AuthnStatement $authnStatement;
4146

@@ -62,6 +67,14 @@ public static function setUpBeforeClass(): void
6267
),
6368
SAMLDateTimeValue::fromDateTime(self::$clock->now()),
6469
);
70+
71+
// Create Subject
72+
self::$subject = new Subject(
73+
new NameID(
74+
value: SAMLStringValue::fromString("just_a_basic_identifier"),
75+
Format: SAMLAnyURIValue::fromString(C::NAMEID_TRANSIENT),
76+
),
77+
);
6578
}
6679

6780

@@ -80,6 +93,7 @@ public function testTimestampInTheFutureBeyondGraceperiodIsNotValid(): void
8093
// Create an assertion
8194
$assertion = new Assertion(
8295
id: IDValue::fromString('abc123'),
96+
subject: self::$subject,
8397
issuer: self::$issuer,
8498
issueInstant: SAMLDateTimeValue::fromDateTime(self::$clock->now()),
8599
conditions: $conditions,
@@ -111,6 +125,7 @@ public function testTimeWithinGraceperiodIsValid(): void
111125
// Create an assertion
112126
$assertion = new Assertion(
113127
id: IDValue::fromString('abc123'),
128+
subject: self::$subject,
114129
issuer: self::$issuer,
115130
issueInstant: SAMLDateTimeValue::fromDateTime(self::$clock->now()),
116131
conditions: $conditions,
@@ -139,6 +154,7 @@ public function testCurrentTimeIsValid(): void
139154
// Create an assertion
140155
$assertion = new Assertion(
141156
id: IDValue::fromString('abc123'),
157+
subject: self::$subject,
142158
issuer: self::$issuer,
143159
issueInstant: SAMLDateTimeValue::fromDateTime(self::$clock->now()),
144160
conditions: $conditions,

tests/SAML2/Assertion/Validation/ConstraintValidator/NotOnOrAfterTest.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
use SimpleSAML\SAML2\XML\saml\AuthnStatement;
2222
use SimpleSAML\SAML2\XML\saml\Conditions;
2323
use SimpleSAML\SAML2\XML\saml\Issuer;
24+
use SimpleSAML\SAML2\XML\saml\NameID;
25+
use SimpleSAML\SAML2\XML\saml\Subject;
2426
use SimpleSAML\Test\SAML2\Constants as C;
2527
use SimpleSAML\XML\Type\IDValue;
2628

@@ -36,6 +38,9 @@ final class NotOnOrAfterTest extends TestCase
3638
/** @var \SimpleSAML\SAML2\XML\saml\Issuer */
3739
private static Issuer $issuer;
3840

41+
/** @var \SimpleSAML\SAML2\XML\saml\Subject */
42+
private static Subject $subject;
43+
3944
/** @var \SimpleSAML\SAML2\XML\saml\AuthnStatement */
4045
private static AuthnStatement $authnStatement;
4146

@@ -51,6 +56,14 @@ public static function setUpBeforeClass(): void
5156
SAMLStringValue::fromString('urn:x-simplesamlphp:issuer'),
5257
);
5358

59+
// Create Subject
60+
self::$subject = new Subject(
61+
new NameID(
62+
value: SAMLStringValue::fromString("just_a_basic_identifier"),
63+
Format: SAMLAnyURIValue::fromString(C::NAMEID_TRANSIENT),
64+
),
65+
);
66+
5467
// Create the statements
5568
self::$authnStatement = new AuthnStatement(
5669
new AuthnContext(
@@ -81,6 +94,7 @@ public function testTimestampInThePastBeforeGraceperiodIsNotValid(): void
8194
// Create an assertion
8295
$assertion = new Assertion(
8396
id: IDValue::fromString('abc123'),
97+
subject: self::$subject,
8498
issuer: self::$issuer,
8599
issueInstant: SAMLDateTimeValue::fromDateTime(self::$clock->now()),
86100
conditions: $conditions,
@@ -113,6 +127,7 @@ public function testTimeWithinGraceperiodIsValid(): void
113127
// Create an assertion
114128
$assertion = new Assertion(
115129
id: IDValue::fromString('abc123'),
130+
subject: self::$subject,
116131
issuer: self::$issuer,
117132
issueInstant: SAMLDateTimeValue::fromDateTime(self::$clock->now()),
118133
conditions: $conditions,
@@ -142,6 +157,7 @@ public function testCurrentTimeIsValid(): void
142157
// Create an assertion
143158
$assertion = new Assertion(
144159
id: IDValue::fromString('abc123'),
160+
subject: self::$subject,
145161
issuer: self::$issuer,
146162
issueInstant: SAMLDateTimeValue::fromDateTime(self::$clock->now()),
147163
conditions: $conditions,

tests/SAML2/Assertion/Validation/ConstraintValidator/SessionNotOnOrAfterTest.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
use SimpleSAML\SAML2\XML\saml\AuthnContextClassRef;
2121
use SimpleSAML\SAML2\XML\saml\AuthnStatement;
2222
use SimpleSAML\SAML2\XML\saml\Issuer;
23+
use SimpleSAML\SAML2\XML\saml\NameID;
24+
use SimpleSAML\SAML2\XML\saml\Subject;
2325
use SimpleSAML\Test\SAML2\Constants as C;
2426
use SimpleSAML\XML\Type\IDValue;
2527

@@ -35,6 +37,9 @@ final class SessionNotOnOrAfterTest extends TestCase
3537
/** @var \SimpleSAML\SAML2\XML\saml\Issuer */
3638
private static Issuer $issuer;
3739

40+
/** @var \SimpleSAML\SAML2\XML\saml\Subject */
41+
private static Subject $subject;
42+
3843

3944
/**
4045
*/
@@ -46,6 +51,14 @@ public static function setUpBeforeClass(): void
4651
self::$issuer = new Issuer(
4752
SAMLStringValue::fromString('urn:x-simplesamlphp:issuer'),
4853
);
54+
55+
// Create Subject
56+
self::$subject = new Subject(
57+
new NameID(
58+
value: SAMLStringValue::fromString("just_a_basic_identifier"),
59+
Format: SAMLAnyURIValue::fromString(C::NAMEID_TRANSIENT),
60+
),
61+
);
4962
}
5063

5164

@@ -72,6 +85,7 @@ public function timestampInThePastBeforeGraceperiodIsNotValid(): void
7285
// Create an assertion
7386
$assertion = new Assertion(
7487
issuer: self::$issuer,
88+
subject: self::$subject,
7589
issueInstant: SAMLDateTimeValue::fromDateTime(self::$clock->now()),
7690
id: IDValue::fromString('abc123'),
7791
statements: [$authnStatement],
@@ -110,6 +124,7 @@ public function timeWithinGraceperiodIsValid(): void
110124
// Create an assertion
111125
$assertion = new Assertion(
112126
id: IDValue::fromString('abc123'),
127+
subject: $subject,
113128
issuer: self::$issuer,
114129
issueInstant: SAMLDateTimeValue::fromDateTime(self::$clock->now()),
115130
statements: [$authnStatement],
@@ -145,6 +160,7 @@ public function testCurrentTimeIsValid(): void
145160
// Create an assertion
146161
$assertion = new Assertion(
147162
id: IDValue::fromString('abc123'),
163+
subject: self::$subject,
148164
issuer: self::$issuer,
149165
issueInstant: SAMLDateTimeValue::fromDateTime(self::$clock->now()),
150166
statements: [$authnStatement],

tests/SAML2/Assertion/Validation/ConstraintValidator/SpIsValidAudienceTest.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
use SimpleSAML\SAML2\XML\saml\AuthnStatement;
2626
use SimpleSAML\SAML2\XML\saml\Conditions;
2727
use SimpleSAML\SAML2\XML\saml\Issuer;
28+
use SimpleSAML\SAML2\XML\saml\NameID;
29+
use SimpleSAML\SAML2\XML\saml\Subject;
2830
use SimpleSAML\Test\SAML2\Constants as C;
2931
use SimpleSAML\XML\Type\IDValue;
3032

@@ -46,6 +48,9 @@ final class SpIsValidAudienceTest extends MockeryTestCase
4648
/** @var \SimpleSAML\SAML2\XML\saml\Issuer */
4749
private static Issuer $issuer;
4850

51+
/** @var \SimpleSAML\SAML2\XML\saml\Subject */
52+
private static Subject $subject;
53+
4954
/** @var \Mockery\MockInterface */
5055
private MockInterface $serviceProvider;
5156

@@ -64,6 +69,14 @@ public static function setUpBeforeClass(): void
6469
SAMLStringValue::fromString(C::ENTITY_IDP),
6570
);
6671

72+
// Create Subject
73+
self::$subject = new Subject(
74+
new NameID(
75+
value: SAMLStringValue::fromString("just_a_basic_identifier"),
76+
Format: SAMLAnyURIValue::fromString(C::NAMEID_TRANSIENT),
77+
),
78+
);
79+
6780
// Create the conditions
6881
self::$conditions = new Conditions(
6982
null,
@@ -107,6 +120,7 @@ public function testWhenNoValidAudiencesAreGivenTheAssertionIsValid(): void
107120
// Create an assertion
108121
$assertion = new Assertion(
109122
id: IDValue::fromString('abc123'),
123+
subject: self::$subject,
110124
issuer: self::$issuer,
111125
issueInstant: SAMLDateTimeValue::fromDateTime(self::$clock->now()),
112126
statements: [self::$authnStatement],
@@ -132,6 +146,7 @@ public function testIfTheSpEntityIdIsNotInTheValidAudiencesTheAssertionIsInvalid
132146
// Create an assertion
133147
$assertion = new Assertion(
134148
id: IDValue::fromString('abc123'),
149+
subject: self::$subject,
135150
issuer: self::$issuer,
136151
issueInstant: SAMLDateTimeValue::fromDateTime(self::$clock->now()),
137152
conditions: self::$conditions,
@@ -159,6 +174,7 @@ public function testTheAssertionIsValidWhenTheCurrentSpEntityIdIsAValidAudience(
159174
// Create an assertion
160175
$assertion = new Assertion(
161176
id: IDValue::fromString('abc123'),
177+
subject: self::$subject,
162178
issuer: self::$issuer,
163179
issueInstant: SAMLDateTimeValue::fromDateTime(self::$clock->now()),
164180
conditions: self::$conditions,

0 commit comments

Comments
 (0)