Skip to content

Commit d38c890

Browse files
authored
Extensibility tests: Issuer - SAML and SAML2 (#3026)
* Rename JWT issuer extensibility tests to better align on the solution explorer. Simplified creation of stack frames for comparison (cherry picked from commit 4ed421d) * Handle potential exceptions thrown by the issuer validator in SAML and SAML2 (cherry picked from commit 9188432) * Added extensibility tests for issuer validation on SAML and SAML2 (cherry picked from commit 91a8b1d) * Updated validation failure type position in tests
1 parent 9463f20 commit d38c890

File tree

5 files changed

+637
-79
lines changed

5 files changed

+637
-79
lines changed

src/Microsoft.IdentityModel.Tokens.Saml/Saml/SamlSecurityTokenHandler.ValidateToken.Internal.cs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,17 +63,29 @@ internal async Task<ValidationResult<ValidatedToken>> ValidateTokenAsync(
6363
if (!conditionsResult.IsValid)
6464
return conditionsResult.UnwrapError().AddCurrentStackFrame();
6565

66-
ValidationResult<ValidatedIssuer> issuerValidationResult = await validationParameters.IssuerValidatorAsync(
67-
samlToken.Issuer,
68-
samlToken,
69-
validationParameters,
70-
callContext,
71-
cancellationToken).ConfigureAwait(false);
66+
try
67+
{
68+
ValidationResult<ValidatedIssuer> issuerValidationResult = await validationParameters.IssuerValidatorAsync(
69+
samlToken.Issuer,
70+
samlToken,
71+
validationParameters,
72+
callContext,
73+
cancellationToken).ConfigureAwait(false);
7274

73-
if (!issuerValidationResult.IsValid)
75+
if (!issuerValidationResult.IsValid)
76+
return issuerValidationResult.UnwrapError().AddCurrentStackFrame();
77+
}
78+
#pragma warning disable CA1031 // Do not catch general exception types
79+
catch (Exception ex)
80+
#pragma warning restore CA1031 // Do not catch general exception types
7481
{
75-
StackFrames.IssuerValidationFailed ??= new StackFrame(true);
76-
return issuerValidationResult.UnwrapError().AddStackFrame(StackFrames.IssuerValidationFailed);
82+
return new IssuerValidationError(
83+
new MessageDetail(Tokens.LogMessages.IDX10269),
84+
ValidationFailureType.IssuerValidatorThrew,
85+
typeof(SecurityTokenInvalidIssuerException),
86+
ValidationError.GetCurrentStackFrame(),
87+
samlToken.Issuer,
88+
ex);
7789
}
7890

7991
if (samlToken.Assertion.Conditions is not null)

src/Microsoft.IdentityModel.Tokens.Saml/Saml2/Saml2SecurityTokenHandler.ValidateToken.Internal.cs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,17 +67,29 @@ internal async Task<ValidationResult<ValidatedToken>> ValidateTokenAsync(
6767
if (!conditionsResult.IsValid)
6868
return conditionsResult.UnwrapError().AddCurrentStackFrame();
6969

70-
ValidationResult<ValidatedIssuer> validatedIssuerResult = await validationParameters.IssuerValidatorAsync(
71-
samlToken.Issuer,
72-
samlToken,
73-
validationParameters,
74-
callContext,
75-
cancellationToken).ConfigureAwait(false);
70+
try
71+
{
72+
ValidationResult<ValidatedIssuer> issuerValidationResult = await validationParameters.IssuerValidatorAsync(
73+
samlToken.Issuer,
74+
samlToken,
75+
validationParameters,
76+
callContext,
77+
cancellationToken).ConfigureAwait(false);
7678

77-
if (!validatedIssuerResult.IsValid)
79+
if (!issuerValidationResult.IsValid)
80+
return issuerValidationResult.UnwrapError().AddCurrentStackFrame();
81+
}
82+
#pragma warning disable CA1031 // Do not catch general exception types
83+
catch (Exception ex)
84+
#pragma warning restore CA1031 // Do not catch general exception types
7885
{
79-
StackFrames.IssuerValidationFailed ??= new StackFrame(true);
80-
return validatedIssuerResult.UnwrapError().AddStackFrame(StackFrames.IssuerValidationFailed);
86+
return new IssuerValidationError(
87+
new MessageDetail(Tokens.LogMessages.IDX10269),
88+
ValidationFailureType.IssuerValidatorThrew,
89+
typeof(SecurityTokenInvalidIssuerException),
90+
ValidationError.GetCurrentStackFrame(),
91+
samlToken.Issuer,
92+
ex);
8193
}
8294

8395
if (samlToken.Assertion.Conditions is not null)
Lines changed: 39 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
// Licensed under the MIT License.
33

44
using System;
5-
using System.Collections.Generic;
65
using System.Diagnostics;
76
using System.Threading;
87
using System.Threading.Tasks;
98
using Microsoft.IdentityModel.JsonWebTokens.Tests;
9+
using Microsoft.IdentityModel.Logging;
1010
using Microsoft.IdentityModel.TestUtils;
1111
using Microsoft.IdentityModel.Tokens;
1212
using Microsoft.IdentityModel.Tokens.Json.Tests;
@@ -22,8 +22,8 @@ public async Task ValidateTokenAsync_IssuerValidator_Extensibility(IssuerExtensi
2222
{
2323
var context = TestUtilities.WriteHeader($"{this}.{nameof(ValidateTokenAsync_IssuerValidator_Extensibility)}", theoryData);
2424
context.IgnoreType = false;
25-
for (int i = 1; i < theoryData.StackFrames.Count; i++)
26-
theoryData.IssuerValidationError!.AddStackFrame(theoryData.StackFrames[i]);
25+
for (int i = 0; i < theoryData.ExtraStackFrames; i++)
26+
theoryData.IssuerValidationError!.AddStackFrame(new StackFrame(false));
2727

2828
try
2929
{
@@ -69,11 +69,7 @@ public static TheoryData<IssuerExtensibilityTheoryData> Issuer_ExtensibilityTest
6969
"CustomIssuerValidatorDelegate",
7070
issuerGuid,
7171
CustomIssuerValidationDelegates.CustomIssuerValidatorDelegateAsync,
72-
[
73-
new StackFrame("CustomIssuerValidationDelegates", 88),
74-
new StackFrame(false),
75-
new StackFrame(false)
76-
])
72+
extraStackFrames: 2)
7773
{
7874
ExpectedException = new ExpectedException(
7975
typeof(SecurityTokenInvalidIssuerException),
@@ -83,7 +79,7 @@ public static TheoryData<IssuerExtensibilityTheoryData> Issuer_ExtensibilityTest
8379
nameof(CustomIssuerValidationDelegates.CustomIssuerValidatorDelegateAsync), null),
8480
ValidationFailureType.IssuerValidationFailed,
8581
typeof(SecurityTokenInvalidIssuerException),
86-
new StackFrame("CustomIssuerValidationDelegates", 88),
82+
new StackFrame("CustomIssuerValidationDelegates.cs", 88),
8783
issuerGuid)
8884
});
8985

@@ -92,11 +88,7 @@ public static TheoryData<IssuerExtensibilityTheoryData> Issuer_ExtensibilityTest
9288
"CustomIssuerValidatorCustomExceptionDelegate",
9389
issuerGuid,
9490
CustomIssuerValidationDelegates.CustomIssuerValidatorCustomExceptionDelegateAsync,
95-
[
96-
new StackFrame("CustomIssuerValidationDelegates", 107),
97-
new StackFrame(false),
98-
new StackFrame(false)
99-
])
91+
extraStackFrames: 2)
10092
{
10193
ExpectedException = new ExpectedException(
10294
typeof(CustomSecurityTokenInvalidIssuerException),
@@ -106,7 +98,7 @@ public static TheoryData<IssuerExtensibilityTheoryData> Issuer_ExtensibilityTest
10698
nameof(CustomIssuerValidationDelegates.CustomIssuerValidatorCustomExceptionDelegateAsync), null),
10799
ValidationFailureType.IssuerValidationFailed,
108100
typeof(CustomSecurityTokenInvalidIssuerException),
109-
new StackFrame("CustomIssuerValidationDelegates", 107),
101+
new StackFrame("CustomIssuerValidationDelegates.cs", 107),
110102
issuerGuid),
111103
});
112104

@@ -115,21 +107,20 @@ public static TheoryData<IssuerExtensibilityTheoryData> Issuer_ExtensibilityTest
115107
"CustomIssuerValidatorUnknownExceptionDelegate",
116108
issuerGuid,
117109
CustomIssuerValidationDelegates.CustomIssuerValidatorUnknownExceptionDelegateAsync,
118-
[
119-
new StackFrame("CustomIssuerValidationDelegates", 139),
120-
new StackFrame(false),
121-
new StackFrame(false)
122-
])
110+
extraStackFrames: 2)
123111
{
124-
ExpectedException = new ExpectedException(
125-
typeof(SecurityTokenException),
126-
nameof(CustomIssuerValidationDelegates.CustomIssuerValidatorUnknownExceptionDelegateAsync)),
112+
// CustomIssuerValidationError does not handle the exception type 'NotSupportedException'
113+
ExpectedException = ExpectedException.SecurityTokenException(
114+
LogHelper.FormatInvariant(
115+
Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'.";
116+
typeof(NotSupportedException),
117+
nameof(CustomIssuerValidationDelegates.CustomIssuerValidatorUnknownExceptionDelegateAsync))),
127118
IssuerValidationError = new CustomIssuerValidationError(
128119
new MessageDetail(
129120
nameof(CustomIssuerValidationDelegates.CustomIssuerValidatorUnknownExceptionDelegateAsync), null),
130121
ValidationFailureType.IssuerValidationFailed,
131122
typeof(NotSupportedException),
132-
new StackFrame("CustomIssuerValidationDelegates", 139),
123+
new StackFrame("CustomIssuerValidationDelegates.cs", 139),
133124
issuerGuid),
134125
});
135126

@@ -138,11 +129,7 @@ public static TheoryData<IssuerExtensibilityTheoryData> Issuer_ExtensibilityTest
138129
"CustomIssuerValidatorCustomExceptionCustomFailureTypeDelegate",
139130
issuerGuid,
140131
CustomIssuerValidationDelegates.CustomIssuerValidatorCustomExceptionCustomFailureTypeDelegateAsync,
141-
[
142-
new StackFrame("CustomIssuerValidationDelegates", 123),
143-
new StackFrame(false),
144-
new StackFrame(false)
145-
])
132+
extraStackFrames: 2)
146133
{
147134
ExpectedException = new ExpectedException(
148135
typeof(CustomSecurityTokenInvalidIssuerException),
@@ -152,7 +139,7 @@ public static TheoryData<IssuerExtensibilityTheoryData> Issuer_ExtensibilityTest
152139
nameof(CustomIssuerValidationDelegates.CustomIssuerValidatorCustomExceptionCustomFailureTypeDelegateAsync), null),
153140
CustomIssuerValidationError.CustomIssuerValidationFailureType,
154141
typeof(CustomSecurityTokenInvalidIssuerException),
155-
new StackFrame("CustomIssuerValidationDelegates", 123),
142+
new StackFrame("CustomIssuerValidationDelegates.cs", 123),
156143
issuerGuid,
157144
null),
158145
});
@@ -165,11 +152,7 @@ public static TheoryData<IssuerExtensibilityTheoryData> Issuer_ExtensibilityTest
165152
"IssuerValidatorDelegate",
166153
issuerGuid,
167154
CustomIssuerValidationDelegates.IssuerValidatorDelegateAsync,
168-
[
169-
new StackFrame("CustomIssuerValidationDelegates", 169),
170-
new StackFrame(false),
171-
new StackFrame(false)
172-
])
155+
extraStackFrames: 2)
173156
{
174157
ExpectedException = new ExpectedException(
175158
typeof(SecurityTokenInvalidIssuerException),
@@ -179,7 +162,7 @@ public static TheoryData<IssuerExtensibilityTheoryData> Issuer_ExtensibilityTest
179162
nameof(CustomIssuerValidationDelegates.IssuerValidatorDelegateAsync), null),
180163
ValidationFailureType.IssuerValidationFailed,
181164
typeof(SecurityTokenInvalidIssuerException),
182-
new StackFrame("CustomIssuerValidationDelegates", 169),
165+
new StackFrame("CustomIssuerValidationDelegates.cs", 169),
183166
issuerGuid)
184167
});
185168

@@ -188,21 +171,20 @@ public static TheoryData<IssuerExtensibilityTheoryData> Issuer_ExtensibilityTest
188171
"IssuerValidatorCustomIssuerExceptionTypeDelegate",
189172
issuerGuid,
190173
CustomIssuerValidationDelegates.IssuerValidatorCustomIssuerExceptionTypeDelegateAsync,
191-
[
192-
new StackFrame("CustomIssuerValidationDelegates", 196),
193-
new StackFrame(false),
194-
new StackFrame(false)
195-
])
174+
extraStackFrames: 2)
196175
{
197-
ExpectedException = new ExpectedException(
198-
typeof(SecurityTokenException),
199-
nameof(CustomIssuerValidationDelegates.IssuerValidatorCustomIssuerExceptionTypeDelegateAsync)),
176+
// IssuerValidationError does not handle the exception type 'CustomSecurityTokenInvalidIssuerException'
177+
ExpectedException = ExpectedException.SecurityTokenException(
178+
LogHelper.FormatInvariant(
179+
Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'.";
180+
typeof(CustomSecurityTokenInvalidIssuerException),
181+
nameof(CustomIssuerValidationDelegates.IssuerValidatorCustomIssuerExceptionTypeDelegateAsync))),
200182
IssuerValidationError = new IssuerValidationError(
201183
new MessageDetail(
202184
nameof(CustomIssuerValidationDelegates.IssuerValidatorCustomIssuerExceptionTypeDelegateAsync), null),
203185
ValidationFailureType.IssuerValidationFailed,
204186
typeof(CustomSecurityTokenInvalidIssuerException),
205-
new StackFrame("CustomIssuerValidationDelegates", 196),
187+
new StackFrame("CustomIssuerValidationDelegates.cs", 196),
206188
issuerGuid)
207189
});
208190

@@ -211,21 +193,20 @@ public static TheoryData<IssuerExtensibilityTheoryData> Issuer_ExtensibilityTest
211193
"IssuerValidatorCustomExceptionTypeDelegate",
212194
issuerGuid,
213195
CustomIssuerValidationDelegates.IssuerValidatorCustomExceptionTypeDelegateAsync,
214-
[
215-
new StackFrame("CustomIssuerValidationDelegates", 210),
216-
new StackFrame(false),
217-
new StackFrame(false)
218-
])
196+
extraStackFrames: 2)
219197
{
220-
ExpectedException = new ExpectedException(
221-
typeof(SecurityTokenException),
222-
nameof(CustomIssuerValidationDelegates.IssuerValidatorCustomExceptionTypeDelegateAsync)),
198+
// IssuerValidationError does not handle the exception type 'CustomSecurityTokenException'
199+
ExpectedException = ExpectedException.SecurityTokenException(
200+
LogHelper.FormatInvariant(
201+
Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'.";
202+
typeof(CustomSecurityTokenException),
203+
nameof(CustomIssuerValidationDelegates.IssuerValidatorCustomExceptionTypeDelegateAsync))),
223204
IssuerValidationError = new IssuerValidationError(
224205
new MessageDetail(
225206
nameof(CustomIssuerValidationDelegates.IssuerValidatorCustomExceptionTypeDelegateAsync), null),
226207
ValidationFailureType.IssuerValidationFailed,
227208
typeof(CustomSecurityTokenException),
228-
new StackFrame("CustomIssuerValidationDelegates", 210),
209+
new StackFrame("CustomIssuerValidationDelegates.cs", 210),
229210
issuerGuid)
230211
});
231212

@@ -234,10 +215,7 @@ public static TheoryData<IssuerExtensibilityTheoryData> Issuer_ExtensibilityTest
234215
"IssuerValidatorThrows",
235216
issuerGuid,
236217
CustomIssuerValidationDelegates.IssuerValidatorThrows,
237-
[
238-
new StackFrame("JsonWebTokenHandler.ValidateToken.Internal.cs", 300),
239-
new StackFrame(false)
240-
])
218+
extraStackFrames: 1)
241219
{
242220
ExpectedException = new ExpectedException(
243221
typeof(SecurityTokenInvalidIssuerException),
@@ -261,7 +239,7 @@ public static TheoryData<IssuerExtensibilityTheoryData> Issuer_ExtensibilityTest
261239

262240
public class IssuerExtensibilityTheoryData : ValidateTokenAsyncBaseTheoryData
263241
{
264-
internal IssuerExtensibilityTheoryData(string testId, string issuer, IssuerValidationDelegateAsync issuerValidator, IList<StackFrame> stackFrames) : base(testId)
242+
internal IssuerExtensibilityTheoryData(string testId, string issuer, IssuerValidationDelegateAsync issuerValidator, int extraStackFrames) : base(testId)
265243
{
266244
JsonWebToken = JsonUtilities.CreateUnsignedJsonWebToken("iss", issuer);
267245
ValidationParameters = new ValidationParameters
@@ -276,7 +254,7 @@ internal IssuerExtensibilityTheoryData(string testId, string issuer, IssuerValid
276254
TokenTypeValidator = SkipValidationDelegates.SkipTokenTypeValidation
277255
};
278256

279-
StackFrames = stackFrames;
257+
ExtraStackFrames = extraStackFrames;
280258
}
281259

282260
public JsonWebToken JsonWebToken { get; }
@@ -289,7 +267,7 @@ internal IssuerExtensibilityTheoryData(string testId, string issuer, IssuerValid
289267

290268
internal IssuerValidationError? IssuerValidationError { get; set; }
291269

292-
internal IList<StackFrame> StackFrames { get; }
270+
internal int ExtraStackFrames { get; }
293271
}
294272
}
295273
}

0 commit comments

Comments
 (0)