diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a6289e3..01508e3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - dotnet-version: [ '8.0.x' ] + dotnet-version: [ '10.0.x' ] steps: - uses: actions/checkout@v4 @@ -42,7 +42,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - dotnet-version: [ '8.0.x' ] + dotnet-version: [ '10.0.x' ] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/pack-and-push.yml b/.github/workflows/pack-and-push.yml index 351b1e7..c016ca5 100644 --- a/.github/workflows/pack-and-push.yml +++ b/.github/workflows/pack-and-push.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - dotnet-version: [ '8.0.x' ] + dotnet-version: [ '10.0.x' ] steps: - uses: actions/checkout@v4 diff --git a/logo-75.png b/logo-75.png index 46972ef..095daf3 100644 Binary files a/logo-75.png and b/logo-75.png differ diff --git a/logo.png b/logo.png index 65aaf66..96cfa5f 100644 Binary files a/logo.png and b/logo.png differ diff --git a/src/JWTGuard.SampleApi/JWTGuard.SampleApi.csproj b/src/JWTGuard.SampleApi/JWTGuard.SampleApi.csproj index 92b8c8f..d4eb826 100644 --- a/src/JWTGuard.SampleApi/JWTGuard.SampleApi.csproj +++ b/src/JWTGuard.SampleApi/JWTGuard.SampleApi.csproj @@ -1,17 +1,17 @@ - net8.0 + net10.0 enable enable - + - - - + + + diff --git a/src/JWTGuard.SampleApi/Program.cs b/src/JWTGuard.SampleApi/Program.cs index 75f80b3..a8c6895 100644 --- a/src/JWTGuard.SampleApi/Program.cs +++ b/src/JWTGuard.SampleApi/Program.cs @@ -39,7 +39,7 @@ IEnumerable AllowSpecialCases(string token, SecurityToken securityT var certPem = (x5c as List)![0] as string; SecurityKey? securityKey; - if (certPem.Contains("RSA PUBLIC", StringComparison.Ordinal)) + if (certPem is not null && certPem.Contains("RSA PUBLIC", StringComparison.Ordinal)) { var rsaSecurityKey = new RsaSecurityKey(RSA.Create()); rsaSecurityKey.Rsa.ImportFromPem(certPem); @@ -82,7 +82,7 @@ IEnumerable AllowSpecialCases(string token, SecurityToken securityT return [JsonWebKeyConverter.ConvertFromSecurityKey(securityKey)]; } - return Array.Empty(); + return []; } options.TokenValidationParameters = new() @@ -146,6 +146,4 @@ IEnumerable AllowSpecialCases(string token, SecurityToken securityT record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary) { public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); -} - -public partial class Program {} \ No newline at end of file +} \ No newline at end of file diff --git a/src/JWTGuard/Helpers/JwtBuilder.cs b/src/JWTGuard/Helpers/JwtBuilder.cs index cd51687..1568d55 100644 --- a/src/JWTGuard/Helpers/JwtBuilder.cs +++ b/src/JWTGuard/Helpers/JwtBuilder.cs @@ -3,8 +3,7 @@ using System.Text; using Duende.IdentityServer.Test; - -using IdentityModel; +using Duende.IdentityModel; using Microsoft.IdentityModel.JsonWebTokens; using Microsoft.IdentityModel.Tokens; diff --git a/src/JWTGuard/JWTGuard.csproj b/src/JWTGuard/JWTGuard.csproj index 0b7b44e..8cf14ba 100644 --- a/src/JWTGuard/JWTGuard.csproj +++ b/src/JWTGuard/JWTGuard.csproj @@ -1,7 +1,8 @@  - net8.0 + net10.0 + Exe enable enable true @@ -9,11 +10,11 @@ - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/JWTGuard/Tests/AudienceTests.cs b/src/JWTGuard/Tests/AudienceTests.cs index 96dd501..3755aa7 100644 --- a/src/JWTGuard/Tests/AudienceTests.cs +++ b/src/JWTGuard/Tests/AudienceTests.cs @@ -1,5 +1,4 @@ -using System.Net; -using System.Net.Http.Headers; +using System.Net.Http.Headers; using JWTGuard.Helpers; @@ -27,7 +26,7 @@ internal async Task Accessing_AuthorizedUrl_Is_Authorized_For_Allowed_Audiences( Client!.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwt); // Act - var response = await Client.GetAsync(TestSettings.CurrentTestSettings.TargetUrl); + var response = await Client.GetAsync(TestSettings.CurrentTestSettings.TargetUrl, TestContext.Current.CancellationToken); // Assert TestSettings.CurrentTestSettings.AssertAuthorizedResponse(response); @@ -48,7 +47,7 @@ internal async Task Accessing_AuthorizedUrl_Is_Unauthorized_For_Disallowed_Audie Client!.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwt); // Act - var response = await Client.GetAsync(TestSettings.CurrentTestSettings.TargetUrl); + var response = await Client.GetAsync(TestSettings.CurrentTestSettings.TargetUrl, TestContext.Current.CancellationToken); // Assert TestSettings.CurrentTestSettings.AssertUnauthorizedResponse(response); @@ -67,7 +66,7 @@ private Task GetJwtAsync(string audience) public static TheoryData GetAllowedAudiences() { return TestSettings.CurrentTestSettings.AllowedAudiences.Count == 0 - ? new TheoryData([null]) + ? new TheoryData((string?)null) : new TheoryData(TestSettings.CurrentTestSettings.AllowedAudiences); } @@ -77,7 +76,7 @@ private Task GetJwtAsync(string audience) public static TheoryData GetDisallowedAudiences() { return TestSettings.CurrentTestSettings.DisallowedAudiences.Count == 0 - ? new TheoryData([null]) + ? new TheoryData((string?)null) : new TheoryData(TestSettings.CurrentTestSettings.DisallowedAudiences); } } \ No newline at end of file diff --git a/src/JWTGuard/Tests/ExternalSignatureTests.cs b/src/JWTGuard/Tests/ExternalSignatureTests.cs index 659ec63..9cc1dfd 100644 --- a/src/JWTGuard/Tests/ExternalSignatureTests.cs +++ b/src/JWTGuard/Tests/ExternalSignatureTests.cs @@ -1,5 +1,4 @@ using System.Net.Http.Headers; -using System.Net; using System.Text; using Xunit; @@ -23,7 +22,7 @@ internal async Task Accessing_AuthorizedUrl_Is_Unauthorized_For_External_WebKey_ Client!.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwt); // Act - var response = await Client.GetAsync(TestSettings.CurrentTestSettings.TargetUrl); + var response = await Client.GetAsync(TestSettings.CurrentTestSettings.TargetUrl, TestContext.Current.CancellationToken); // Assert TestSettings.CurrentTestSettings.AssertUnauthorizedResponse(response); @@ -37,7 +36,7 @@ internal async Task Accessing_AuthorizedUrl_Is_Unauthorized_For_External_WebKey_ Client!.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwt); // Act - var response = await Client.GetAsync(TestSettings.CurrentTestSettings.TargetUrl); + var response = await Client.GetAsync(TestSettings.CurrentTestSettings.TargetUrl, TestContext.Current.CancellationToken); // Assert TestSettings.CurrentTestSettings.AssertUnauthorizedResponse(response); @@ -51,7 +50,7 @@ internal async Task Accessing_AuthorizedUrl_Is_Unauthorized_For_External_Certifi Client!.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwt); // Act - var response = await Client.GetAsync(TestSettings.CurrentTestSettings.TargetUrl); + var response = await Client.GetAsync(TestSettings.CurrentTestSettings.TargetUrl, TestContext.Current.CancellationToken); // Assert TestSettings.CurrentTestSettings.AssertUnauthorizedResponse(response); @@ -65,7 +64,7 @@ internal async Task Accessing_AuthorizedUrl_Is_Unauthorized_For_External_Certifi Client!.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwt); // Act - var response = await Client.GetAsync(TestSettings.CurrentTestSettings.TargetUrl); + var response = await Client.GetAsync(TestSettings.CurrentTestSettings.TargetUrl, TestContext.Current.CancellationToken); // Assert TestSettings.CurrentTestSettings.AssertUnauthorizedResponse(response); @@ -91,8 +90,8 @@ private string GetJwt(ExternalSignatureTestCase testCase) var encodedPayload = payload.Base64UrlEncode(); - var headerAndPayload = ""; - var signature = ""; + string headerAndPayload; + string signature; switch (testCase) { diff --git a/src/JWTGuard/Tests/IssuerTests.cs b/src/JWTGuard/Tests/IssuerTests.cs index 188474e..3de37b6 100644 --- a/src/JWTGuard/Tests/IssuerTests.cs +++ b/src/JWTGuard/Tests/IssuerTests.cs @@ -1,5 +1,4 @@ -using System.Net; -using System.Net.Http.Headers; +using System.Net.Http.Headers; using JWTGuard.Helpers; @@ -27,7 +26,7 @@ internal async Task Accessing_AuthorizedUrl_Is_Authorized_For_Allowed_Issuer(str Client!.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwt); // Act - var response = await Client.GetAsync(TestSettings.CurrentTestSettings.TargetUrl); + var response = await Client.GetAsync(TestSettings.CurrentTestSettings.TargetUrl, TestContext.Current.CancellationToken); // Assert TestSettings.CurrentTestSettings.AssertAuthorizedResponse(response); @@ -48,7 +47,7 @@ internal async Task Accessing_AuthorizedUrl_Is_Unauthorized_For_Disallowed_Issue Client!.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwt); // Act - var response = await Client.GetAsync(TestSettings.CurrentTestSettings.TargetUrl); + var response = await Client.GetAsync(TestSettings.CurrentTestSettings.TargetUrl, TestContext.Current.CancellationToken); // Assert TestSettings.CurrentTestSettings.AssertUnauthorizedResponse(response); @@ -67,7 +66,7 @@ private Task GetJwtAsync(string issuer) public static TheoryData GetAllowedIssuers() { return TestSettings.CurrentTestSettings.AllowedIssuers.Count == 0 - ? new TheoryData([null]) + ? new TheoryData((string?)null) : new TheoryData(TestSettings.CurrentTestSettings.AllowedIssuers); } @@ -77,7 +76,7 @@ private Task GetJwtAsync(string issuer) public static TheoryData GetDisallowedIssuers() { return TestSettings.CurrentTestSettings.DisallowedIssuers.Count == 0 - ? new TheoryData([null]) + ? new TheoryData((string?)null) : new TheoryData(TestSettings.CurrentTestSettings.DisallowedIssuers); } } \ No newline at end of file diff --git a/src/JWTGuard/Tests/JwtGuardTestBase.cs b/src/JWTGuard/Tests/JwtGuardTestBase.cs index 2a651f1..d0394b5 100644 --- a/src/JWTGuard/Tests/JwtGuardTestBase.cs +++ b/src/JWTGuard/Tests/JwtGuardTestBase.cs @@ -34,7 +34,7 @@ public abstract class JwtGuardTestBase(TargetApiWebApplicationFactory factory) : /// /// Initializes the base class for a test run. /// - public Task InitializeAsync() + public ValueTask InitializeAsync() { Client = Factory.CreateClient(new WebApplicationFactoryClientOptions { @@ -44,13 +44,13 @@ public Task InitializeAsync() _serviceScope = Factory.Services.CreateAsyncScope(); ServiceProvider = _serviceScope.ServiceProvider; - return Task.CompletedTask; + return ValueTask.CompletedTask; } /// /// Disposes the service scope and every service requested during the test run. /// - public async Task DisposeAsync() + public async ValueTask DisposeAsync() { await _serviceScope.DisposeAsync(); } diff --git a/src/JWTGuard/Tests/JwtTypeTests.cs b/src/JWTGuard/Tests/JwtTypeTests.cs index 56923a5..ba0d251 100644 --- a/src/JWTGuard/Tests/JwtTypeTests.cs +++ b/src/JWTGuard/Tests/JwtTypeTests.cs @@ -1,5 +1,4 @@ -using System.Net; -using System.Net.Http.Headers; +using System.Net.Http.Headers; using JWTGuard.Helpers; @@ -27,7 +26,7 @@ internal async Task Accessing_AuthorizedUrl_Is_Authorized_For_Valid_JWT_Types(st Client!.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwt); // Act - var response = await Client.GetAsync(TestSettings.CurrentTestSettings.TargetUrl); + var response = await Client.GetAsync(TestSettings.CurrentTestSettings.TargetUrl, TestContext.Current.CancellationToken); // Assert TestSettings.CurrentTestSettings.AssertAuthorizedResponse(response); @@ -48,7 +47,7 @@ internal async Task Accessing_AuthorizedUrl_Is_Unauthorized_For_Invalid_JWT_Type Client!.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwt); // Act - var response = await Client.GetAsync(TestSettings.CurrentTestSettings.TargetUrl); + var response = await Client.GetAsync(TestSettings.CurrentTestSettings.TargetUrl, TestContext.Current.CancellationToken); // Assert TestSettings.CurrentTestSettings.AssertUnauthorizedResponse(response); @@ -67,7 +66,7 @@ private Task GetJwtAsync(string tokenType) public static TheoryData GetValidJwtTypes() { return TestSettings.CurrentTestSettings.ValidTokenTypes.Count == 0 - ? new TheoryData([null]) + ? new TheoryData((string?)null) : new TheoryData(TestSettings.CurrentTestSettings.ValidTokenTypes); } @@ -77,7 +76,7 @@ private Task GetJwtAsync(string tokenType) public static TheoryData GetInvalidJwtTypes() { return TestSettings.CurrentTestSettings.InvalidTokenTypes.Count == 0 - ? new TheoryData([null]) + ? new TheoryData((string?)null) : new TheoryData(TestSettings.CurrentTestSettings.InvalidTokenTypes); } } \ No newline at end of file diff --git a/src/JWTGuard/Tests/SignatureAlgorithmTests.cs b/src/JWTGuard/Tests/SignatureAlgorithmTests.cs index 7e3d48c..596a307 100644 --- a/src/JWTGuard/Tests/SignatureAlgorithmTests.cs +++ b/src/JWTGuard/Tests/SignatureAlgorithmTests.cs @@ -1,5 +1,4 @@ -using System.Net; -using System.Net.Http.Headers; +using System.Net.Http.Headers; using JWTGuard.Helpers; @@ -27,7 +26,7 @@ internal async Task Accessing_AuthorizedUrl_Is_Authorized_For_Supported_Signatur Client!.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwt); // Act - var response = await Client.GetAsync(TestSettings.CurrentTestSettings.TargetUrl); + var response = await Client.GetAsync(TestSettings.CurrentTestSettings.TargetUrl, TestContext.Current.CancellationToken); // Assert TestSettings.CurrentTestSettings.AssertAuthorizedResponse(response); @@ -48,7 +47,7 @@ internal async Task Accessing_AuthorizedUrl_Is_Unauthorized_For_Unsupported_Sign Client!.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwt); // Act - var response = await Client.GetAsync(TestSettings.CurrentTestSettings.TargetUrl); + var response = await Client.GetAsync(TestSettings.CurrentTestSettings.TargetUrl, TestContext.Current.CancellationToken); // Assert TestSettings.CurrentTestSettings.AssertUnauthorizedResponse(response); @@ -67,7 +66,7 @@ private Task GetJwtAsync(string signatureAlgorithm) public static TheoryData GetAllowedAlgorithms() { return TestSettings.CurrentTestSettings.AllowedAlgorithms.Count == 0 - ? new TheoryData([null]) + ? new TheoryData((string?)null) : new TheoryData(TestSettings.CurrentTestSettings.AllowedAlgorithms); } @@ -77,7 +76,7 @@ private Task GetJwtAsync(string signatureAlgorithm) public static TheoryData GetDisallowedAlgorithms() { return TestSettings.CurrentTestSettings.DisallowedAlgorithms.Count == 0 - ? new TheoryData([null]) + ? new TheoryData((string?)null) : new TheoryData(TestSettings.CurrentTestSettings.DisallowedAlgorithms); } } \ No newline at end of file