Skip to content

Commit 2e09cf9

Browse files
authored
Merge branch 'dev' into trwalke/ConsolidateTestStatics
2 parents 0f819a1 + 0b72d1f commit 2e09cf9

File tree

9 files changed

+227
-300
lines changed

9 files changed

+227
-300
lines changed

.github/workflows/dotnetcore.yml

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
name: .NET Core
22

3+
permissions:
4+
contents: read
5+
pull-requests: write
6+
37
on:
48
push:
59
branches:
@@ -30,20 +34,43 @@ jobs:
3034
uses: actions/[email protected]
3135
with:
3236
dotnet-version: 6.0.x
33-
3437
- name: Setup .NET 8.0.x
3538
uses: actions/[email protected]
3639
with:
3740
dotnet-version: 8.0.x
38-
3941
- name: Setup .NET 9.0.x
4042
uses: actions/[email protected]
4143
with:
4244
dotnet-version: 9.0.100-rc.2.24474.11
4345

4446
- name: Run the tests
45-
run: dotnet test Wilson.sln
47+
run: dotnet test Wilson.sln --collect:"XPlat Code Coverage" --settings:./build/CodeCoverage.runsettings
48+
49+
- name: Create code coverage report
50+
run: |
51+
dotnet tool install -g dotnet-reportgenerator-globaltool
52+
reportgenerator -reports:./**/coverage.cobertura.xml -targetdir:CodeCoverage -reporttypes:'MarkdownSummaryGithub;Cobertura'
53+
54+
- name: Write Coverage to Job Summary
55+
shell: bash
56+
run: |
57+
cat CodeCoverage/SummaryGithub.md >> $GITHUB_STEP_SUMMARY
58+
echo "COMMENT_CONTENT_ENV_VAR<<EOF" >> $GITHUB_ENV
59+
echo $(cat CodeCoverage/SummaryGithub.md) >> $GITHUB_ENV
60+
echo "EOF" >> $GITHUB_ENV
61+
62+
- name: Comment Coverage in PR
63+
uses: actions/github-script@v7
64+
id: comment
65+
with:
66+
script: |
67+
github.rest.issues.createComment({
68+
issue_number: context.issue.number,
69+
owner: context.repo.owner,
70+
repo: context.repo.repo,
71+
body: process.env.COMMENT_CONTENT_ENV_VAR
72+
})
4673
4774
# Run baseline package validation
4875
- name: Pack
49-
run: dotnet pack Product.proj --no-restore --no-build
76+
run: dotnet pack Product.proj --no-restore --no-build

build/CodeCoverage.runsettings

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ Included items must then not match any entries in the exclude list to remain inc
4040
<ModulePath>.*\microsoft.identitymodel.xml.dll</ModulePath>
4141
<ModulePath>.*\system.identitymodel.tokens.jwt.dll</ModulePath>
4242
</Include>
43+
<Exclude>
44+
<ModulePath>.*\\test\\.*</ModulePath>
45+
<ModulePath>.*Test\.dll</ModulePath>
46+
</Exclude>
4347
</ModulePaths>
4448
<Attributes>
4549
<Exclude>

build/commonTest.props

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@
3939
</ItemGroup>
4040

4141
<ItemGroup>
42+
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorVersion)">
43+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
44+
<PrivateAssets>all</PrivateAssets>
45+
</PackageReference>
4246
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="$(BannedApiAnalyzersVersion)">
4347
<PrivateAssets>all</PrivateAssets>
4448
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>

build/dependenciesTest.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<Project>
22
<PropertyGroup>
3+
<CoverletCollectorVersion>6.0.2</CoverletCollectorVersion>
34
<BannedApiAnalyzersVersion>3.3.4</BannedApiAnalyzersVersion>
45
<DotNetCoreAppRuntimeVersion>2.1.30</DotNetCoreAppRuntimeVersion>
56
<MicrosoftAzureKeyVaultCryptographyVersion>3.0.5</MicrosoftAzureKeyVaultCryptographyVersion>

test/Microsoft.IdentityModel.AotCompatibility.Tests/AotCompatibilityTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public AotCompatibilityTests(ITestOutputHelper testOutputHelper)
3232
///
3333
/// You can also 'dotnet publish' the 'Microsoft.IdentityModel.AotCompatibility.TestApp.csproj' as well to get the errors.
3434
/// </summary>
35-
[Fact(Skip = "need to adjust timeout")]
35+
[Fact]
3636
public void EnsureAotCompatibility()
3737
{
3838
string testAppPath = Path.Combine("..", "..", "..", "..", "Microsoft.IdentityModel.AotCompatibility.TestApp");
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#nullable enable
5+
#if NET472 || NET6_0_OR_GREATER
6+
using System;
7+
using Newtonsoft.Json.Linq;
8+
#endif
9+
using System.Collections.Generic;
10+
using System.Threading.Tasks;
11+
using Microsoft.IdentityModel.TestUtils;
12+
using Microsoft.IdentityModel.Tokens;
13+
using Xunit;
14+
15+
namespace Microsoft.IdentityModel.JsonWebTokens.Tests
16+
{
17+
public partial class JsonWebTokenHandlerValidateTokenAsyncTests
18+
{
19+
[Theory, MemberData(nameof(ValidateTokenAsync_DecryptionTestCases), DisableDiscoveryEnumeration = true)]
20+
public async Task ValidateTokenAsync_Decryption(ValidateTokenAsyncDecryptionTheoryData theoryData)
21+
{
22+
var context = TestUtilities.WriteHeader($"{this}.ValidateTokenAsync_Decryption", theoryData);
23+
24+
string jwtString = CreateEncryptedToken(theoryData.EncryptingCredentials, theoryData.AdditionalHeaderClaims);
25+
26+
await ValidateAndCompareResults(jwtString, theoryData, context);
27+
28+
TestUtilities.AssertFailIfErrors(context);
29+
}
30+
31+
public static TheoryData<ValidateTokenAsyncDecryptionTheoryData> ValidateTokenAsync_DecryptionTestCases
32+
{
33+
get
34+
{
35+
var theoryData = new TheoryData<ValidateTokenAsyncDecryptionTheoryData>();
36+
37+
theoryData.Add(new ValidateTokenAsyncDecryptionTheoryData("Valid_JWE_Aes128Cbc_HmacSha256")
38+
{
39+
EncryptingCredentials = new EncryptingCredentials(
40+
KeyingMaterial.DefaultX509Key_2048,
41+
SecurityAlgorithms.RsaPKCS1,
42+
SecurityAlgorithms.Aes128CbcHmacSha256),
43+
TokenValidationParameters = CreateTokenValidationParameters(KeyingMaterial.DefaultX509Key_2048),
44+
ValidationParameters = CreateValidationParameters(KeyingMaterial.DefaultX509Key_2048),
45+
});
46+
47+
#if NET472 || NET6_0_OR_GREATER
48+
theoryData.Add(new ValidateTokenAsyncDecryptionTheoryData("Valid_JWE_EcdhEs")
49+
{
50+
EncryptingCredentials = new EncryptingCredentials(
51+
new ECDsaSecurityKey(KeyingMaterial.JsonWebKeyP521, true),
52+
SecurityAlgorithms.EcdhEsA256kw,
53+
SecurityAlgorithms.Aes128CbcHmacSha256)
54+
{
55+
KeyExchangePublicKey = KeyingMaterial.JsonWebKeyP521_Public
56+
},
57+
AdditionalHeaderClaims = AdditionalEcdhEsHeaderParameters(KeyingMaterial.JsonWebKeyP521_Public),
58+
TokenValidationParameters = CreateTokenValidationParameters(new ECDsaSecurityKey(KeyingMaterial.JsonWebKeyP521, true)),
59+
ValidationParameters = CreateValidationParameters(new ECDsaSecurityKey(KeyingMaterial.JsonWebKeyP521, true)),
60+
});
61+
#endif
62+
63+
theoryData.Add(new ValidateTokenAsyncDecryptionTheoryData("Invalid_JWE_NoDecryptionKeys")
64+
{
65+
EncryptingCredentials = new EncryptingCredentials(
66+
KeyingMaterial.DefaultX509Key_2048,
67+
SecurityAlgorithms.RsaPKCS1,
68+
SecurityAlgorithms.Aes128CbcHmacSha256),
69+
TokenValidationParameters = CreateTokenValidationParameters(),
70+
ValidationParameters = CreateValidationParameters(),
71+
ExpectedIsValid = false,
72+
ExpectedException = ExpectedException.SecurityTokenDecryptionFailedException("IDX10609:"),
73+
});
74+
75+
theoryData.Add(new ValidateTokenAsyncDecryptionTheoryData("Invalid_JWE_WrongDecryptionKey")
76+
{
77+
EncryptingCredentials = new EncryptingCredentials(
78+
KeyingMaterial.DefaultX509Key_2048,
79+
SecurityAlgorithms.RsaPKCS1,
80+
SecurityAlgorithms.Aes128CbcHmacSha256),
81+
TokenValidationParameters = CreateTokenValidationParameters(KeyingMaterial.DefaultRsaSecurityKey1),
82+
ValidationParameters = CreateValidationParameters(KeyingMaterial.DefaultRsaSecurityKey1),
83+
ExpectedIsValid = false,
84+
ExpectedException = ExpectedException.SecurityTokenKeyWrapException("IDX10618:"),
85+
// Avoid comparing the full exception message as the stack traces for the inner exceptions are different.
86+
ExpectedExceptionValidationParameters = ExpectedException.SecurityTokenKeyWrapException("IDX10618:"),
87+
});
88+
89+
return theoryData;
90+
91+
static TokenValidationParameters CreateTokenValidationParameters(
92+
SecurityKey? tokenDecryptionKey = null, bool tryAllKeys = false)
93+
{
94+
// Skip all validations. We just want to decrypt the JWE.
95+
var tokenValidationParameters = new TokenValidationParameters
96+
{
97+
ValidateAudience = false,
98+
ValidateIssuer = false,
99+
ValidateLifetime = false,
100+
ValidateTokenReplay = false,
101+
ValidateIssuerSigningKey = false,
102+
RequireSignedTokens = false,
103+
TokenDecryptionKey = tokenDecryptionKey,
104+
};
105+
106+
return tokenValidationParameters;
107+
}
108+
109+
static ValidationParameters CreateValidationParameters(SecurityKey? tokenDecryptionKey = null)
110+
{
111+
ValidationParameters validationParameters = new ValidationParameters();
112+
113+
if (tokenDecryptionKey is not null)
114+
validationParameters.TokenDecryptionKeys = [tokenDecryptionKey];
115+
116+
117+
// Skip all validations. We just want to decrypt the JWE
118+
validationParameters.AlgorithmValidator = SkipValidationDelegates.SkipAlgorithmValidation;
119+
validationParameters.AudienceValidator = SkipValidationDelegates.SkipAudienceValidation;
120+
validationParameters.IssuerSigningKeyValidator = SkipValidationDelegates.SkipIssuerSigningKeyValidation;
121+
validationParameters.IssuerValidatorAsync = SkipValidationDelegates.SkipIssuerValidation;
122+
validationParameters.LifetimeValidator = SkipValidationDelegates.SkipLifetimeValidation;
123+
validationParameters.SignatureValidator = SkipValidationDelegates.SkipSignatureValidation;
124+
validationParameters.TokenReplayValidator = SkipValidationDelegates.SkipTokenReplayValidation;
125+
validationParameters.TokenTypeValidator = SkipValidationDelegates.SkipTokenTypeValidation;
126+
127+
return validationParameters;
128+
}
129+
130+
131+
#if NET472 || NET6_0_OR_GREATER
132+
static Dictionary<string, object> AdditionalEcdhEsHeaderParameters(JsonWebKey publicKeySender)
133+
{
134+
// Create the Ephemeral Public Key (Epk) header parameter as a JWK.
135+
var epkJObject = new JObject();
136+
epkJObject.Add(JsonWebKeyParameterNames.Kty, publicKeySender.Kty);
137+
epkJObject.Add(JsonWebKeyParameterNames.Crv, publicKeySender.Crv);
138+
epkJObject.Add(JsonWebKeyParameterNames.X, publicKeySender.X);
139+
epkJObject.Add(JsonWebKeyParameterNames.Y, publicKeySender.Y);
140+
141+
// Set the Ephemeral Public Key (Epk) header parameter, along with the
142+
// Agreement PartyUInfo (Apu) and Agreement PartyVInfo (Apv) header parameters
143+
// to ensure that the ECDH-ES key agreement is successful.
144+
Dictionary<string, object> additionalHeaderParams = new Dictionary<string, object>()
145+
{
146+
{ JsonWebTokens.JwtHeaderParameterNames.Apu, Guid.NewGuid().ToString() },
147+
{ JsonWebTokens.JwtHeaderParameterNames.Apv, Guid.NewGuid().ToString() },
148+
{ JsonWebTokens.JwtHeaderParameterNames.Epk, epkJObject.ToString(Newtonsoft.Json.Formatting.None) }
149+
};
150+
151+
return additionalHeaderParams;
152+
}
153+
#endif
154+
}
155+
}
156+
157+
public class ValidateTokenAsyncDecryptionTheoryData : ValidateTokenAsyncBaseTheoryData
158+
{
159+
public ValidateTokenAsyncDecryptionTheoryData(string testId) : base(testId) { }
160+
161+
public EncryptingCredentials? EncryptingCredentials { get; set; }
162+
163+
public Dictionary<string, object>? AdditionalHeaderClaims { get; set; } = null;
164+
}
165+
166+
private static string CreateEncryptedToken(
167+
EncryptingCredentials? encryptingCredentials,
168+
Dictionary<string, object>? additionalHeaderClaims = null)
169+
{
170+
JsonWebTokenHandler jsonWebTokenHandler = new JsonWebTokenHandler();
171+
172+
SecurityTokenDescriptor securityTokenDescriptor = new SecurityTokenDescriptor
173+
{
174+
Subject = Default.ClaimsIdentity,
175+
EncryptingCredentials = encryptingCredentials,
176+
AdditionalHeaderClaims = additionalHeaderClaims,
177+
};
178+
179+
return jsonWebTokenHandler.CreateToken(securityTokenDescriptor);
180+
}
181+
}
182+
}
183+
#nullable restore

0 commit comments

Comments
 (0)