From 91f00cbd8a4ada03312cd0b5a71a8ed63f502483 Mon Sep 17 00:00:00 2001 From: Brett Hazen <2651260+bhazen@users.noreply.github.com> Date: Tue, 9 Dec 2025 11:31:41 -0600 Subject: [PATCH 1/3] Updated to IdentityModel 8.0.0 --- Directory.Packages.props | 7 ++++--- ...AspNetCore.Authentication.JwtBearer.csproj | 2 +- ...Core.Authentication.JwtBearer.Tests.csproj | 6 +++--- .../src/APIs/DPoPApi/DPoP/DPoPExtensions.cs | 3 ++- .../APIs/DPoPApi/DPoP/DPoPProofValidator.cs | 5 +++-- .../src/ConsoleResourceIndicators/Program.cs | 10 +++++----- .../src/Constants/TokenResponseExtensions.cs | 6 +++--- .../Pages/Diagnostics/ViewModel.cs | 4 ++-- .../Pages/Diagnostics/ViewModel.cs | 4 ++-- .../Pages/Diagnostics/ViewModel.cs | 4 ++-- .../Pages/Diagnostics/ViewModel.cs | 4 ++-- .../hosts/main/Pages/Diagnostics/ViewModel.cs | 4 ++-- .../Configuration/CryptoHelper.cs | 3 ++- .../AuthenticationPropertiesExtensions.cs | 6 +++--- .../Extensions/JsonWebKeyExtensions.cs | 3 ++- .../ValidatedAuthorizeRequestExtensions.cs | 5 +++-- .../Extensions/X509CertificateExtensions.cs | 4 ++-- .../Models/Messages/ConsentRequest.cs | 3 ++- .../Default/DiscoveryResponseGenerator.cs | 19 ++++++++++--------- .../Default/ProtectedDataMessageStore.cs | 6 +++--- .../Default/DefaultDPoPProofValidator.cs | 5 +++-- .../Default/TokenRequestValidator.cs | 3 ++- .../Clients/ClientAssertionClient.cs | 3 ++- .../Clients/ClientCredentialsClient.cs | 3 ++- .../Clients/CustomTokenResponseClients.cs | 4 ++-- .../Clients/ExtensionGrantClient.cs | 3 ++- .../Clients/ResourceOwnerClient.cs | 4 ++-- .../Clients/UserInfoClient.cs | 4 ++-- .../Conformance/Pkce/PkceTests.cs | 3 ++- .../Endpoints/EndSession/EndSessionTests.cs | 7 ++++--- .../Endpoints/Token/RefreshTokenTests.cs | 10 +++++----- .../Extensibility/CustomClaimsServiceTests.cs | 4 ++-- .../CustomProfileServiceTests.cs | 4 ++-- .../CustomTokenCreationServiceTests.cs | 4 ++-- .../LocalApiAuthenticationTests.cs | 9 +++++---- .../DefaultBackChannelLogoutServiceTests.cs | 4 ++-- .../Validation/DPoPProofValidatorTests.cs | 3 ++- .../Validation/IdentityTokenValidation.cs | 3 ++- .../TokenRequestValidation_PKCE.cs | 3 ++- 39 files changed, 105 insertions(+), 86 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index f27ace590..f356bb535 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -7,11 +7,12 @@ - + - + - + + diff --git a/aspnetcore-authentication-jwtbearer/src/AspNetCore.Authentication.JwtBearer/AspNetCore.Authentication.JwtBearer.csproj b/aspnetcore-authentication-jwtbearer/src/AspNetCore.Authentication.JwtBearer/AspNetCore.Authentication.JwtBearer.csproj index 312a65744..090e57444 100644 --- a/aspnetcore-authentication-jwtbearer/src/AspNetCore.Authentication.JwtBearer/AspNetCore.Authentication.JwtBearer.csproj +++ b/aspnetcore-authentication-jwtbearer/src/AspNetCore.Authentication.JwtBearer/AspNetCore.Authentication.JwtBearer.csproj @@ -8,7 +8,7 @@ - + diff --git a/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/AspNetCore.Authentication.JwtBearer.Tests.csproj b/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/AspNetCore.Authentication.JwtBearer.Tests.csproj index 7510e9702..41787aaa5 100644 --- a/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/AspNetCore.Authentication.JwtBearer.Tests.csproj +++ b/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/AspNetCore.Authentication.JwtBearer.Tests.csproj @@ -10,8 +10,8 @@ - - + + @@ -26,4 +26,4 @@ - \ No newline at end of file + diff --git a/identity-server/clients/src/APIs/DPoPApi/DPoP/DPoPExtensions.cs b/identity-server/clients/src/APIs/DPoPApi/DPoP/DPoPExtensions.cs index 74704eabc..242041a7d 100644 --- a/identity-server/clients/src/APIs/DPoPApi/DPoP/DPoPExtensions.cs +++ b/identity-server/clients/src/APIs/DPoPApi/DPoP/DPoPExtensions.cs @@ -1,6 +1,7 @@ // Copyright (c) Duende Software. All rights reserved. // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Text.Json; using Duende.IdentityModel; using Microsoft.AspNetCore.Authentication; @@ -66,7 +67,7 @@ internal static class DPoPExtensions /// public static string CreateThumbprint(this JsonWebKey jwk) { - var jkt = Base64Url.Encode(jwk.ComputeJwkThumbprint()); + var jkt = Base64Url.EncodeToString(jwk.ComputeJwkThumbprint()); return jkt; } } diff --git a/identity-server/clients/src/APIs/DPoPApi/DPoP/DPoPProofValidator.cs b/identity-server/clients/src/APIs/DPoPApi/DPoP/DPoPProofValidator.cs index 7efdaa3cb..33531797d 100644 --- a/identity-server/clients/src/APIs/DPoPApi/DPoP/DPoPProofValidator.cs +++ b/identity-server/clients/src/APIs/DPoPApi/DPoP/DPoPProofValidator.cs @@ -1,6 +1,7 @@ // Copyright (c) Duende Software. All rights reserved. // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Security.Cryptography; using System.Text; using System.Text.Json; @@ -226,7 +227,7 @@ public class DPoPProofValidator var bytes = Encoding.UTF8.GetBytes(context.AccessToken); var hash = sha.ComputeHash(bytes); - var accessTokenHash = Base64Url.Encode(hash); + var accessTokenHash = Base64Url.EncodeToString(hash); if (accessTokenHash != result.AccessTokenHash) { result.IsError = true; @@ -328,7 +329,7 @@ public class DPoPProofValidator skew = dpopOptions.ServerClockSkew; } - // we do x2 here because clock might be might be before or after, so we're making cache duration + // we do x2 here because clock might be might be before or after, so we're making cache duration // longer than the likelyhood of proof token expiration, which is done before replay skew *= 2; var cacheDuration = dpopOptions.ProofTokenValidityDuration + skew; diff --git a/identity-server/clients/src/ConsoleResourceIndicators/Program.cs b/identity-server/clients/src/ConsoleResourceIndicators/Program.cs index c3e54c5a2..ac736a9e1 100644 --- a/identity-server/clients/src/ConsoleResourceIndicators/Program.cs +++ b/identity-server/clients/src/ConsoleResourceIndicators/Program.cs @@ -1,10 +1,10 @@ // Copyright (c) Duende Software. All rights reserved. // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Text; using Clients; using ConsoleResourceIndicators; -using Duende.IdentityModel; using Duende.IdentityModel.Client; using Duende.IdentityModel.OidcClient; using Microsoft.Extensions.Hosting; @@ -103,8 +103,8 @@ async Task FrontChannel(string scope, IEnumerable resource) Console.WriteLine(); Console.WriteLine("Standard access token:"); - Console.WriteLine(Encoding.UTF8.GetString(Base64Url.Decode(header)).PrettyPrintJson()); - Console.WriteLine(Encoding.UTF8.GetString(Base64Url.Decode(payload)).PrettyPrintJson()); + Console.WriteLine(Encoding.UTF8.GetString(Base64Url.DecodeFromChars(header)).PrettyPrintJson()); + Console.WriteLine(Encoding.UTF8.GetString(Base64Url.DecodeFromChars(payload)).PrettyPrintJson()); if (result.RefreshToken == null) { @@ -155,8 +155,8 @@ async Task Refresh(string refreshToken, string resource) var header = parts[0]; var payload = parts[1]; - Console.WriteLine(Encoding.UTF8.GetString(Base64Url.Decode(header)).PrettyPrintJson()); - Console.WriteLine(Encoding.UTF8.GetString(Base64Url.Decode(payload)).PrettyPrintJson()); + Console.WriteLine(Encoding.UTF8.GetString(Base64Url.DecodeFromChars(header)).PrettyPrintJson()); + Console.WriteLine(Encoding.UTF8.GetString(Base64Url.DecodeFromChars(payload)).PrettyPrintJson()); } internal class Test diff --git a/identity-server/clients/src/Constants/TokenResponseExtensions.cs b/identity-server/clients/src/Constants/TokenResponseExtensions.cs index 453bbae46..c36d85f14 100644 --- a/identity-server/clients/src/Constants/TokenResponseExtensions.cs +++ b/identity-server/clients/src/Constants/TokenResponseExtensions.cs @@ -1,9 +1,9 @@ // Copyright (c) Duende Software. All rights reserved. // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Text; using System.Text.Json; -using Duende.IdentityModel; using Duende.IdentityModel.Client; namespace Clients; @@ -25,8 +25,8 @@ public static class TokenResponseExtensions var header = parts[0]; var payload = parts[1]; - Console.WriteLine(PrettyPrintJson(Encoding.UTF8.GetString(Base64Url.Decode(header)))); - Console.WriteLine(PrettyPrintJson(Encoding.UTF8.GetString(Base64Url.Decode(payload)))); + Console.WriteLine(PrettyPrintJson(Encoding.UTF8.GetString(Base64Url.DecodeFromChars(header)))); + Console.WriteLine(PrettyPrintJson(Encoding.UTF8.GetString(Base64Url.DecodeFromChars(payload)))); } } else diff --git a/identity-server/hosts/AspNetIdentity/Pages/Diagnostics/ViewModel.cs b/identity-server/hosts/AspNetIdentity/Pages/Diagnostics/ViewModel.cs index e7413fb3a..14dc19bbf 100644 --- a/identity-server/hosts/AspNetIdentity/Pages/Diagnostics/ViewModel.cs +++ b/identity-server/hosts/AspNetIdentity/Pages/Diagnostics/ViewModel.cs @@ -1,9 +1,9 @@ // Copyright (c) Duende Software. All rights reserved. // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Text; using System.Text.Json; -using Duende.IdentityModel; using Microsoft.AspNetCore.Authentication; namespace IdentityServerHost.Pages.Diagnostics; @@ -18,7 +18,7 @@ public class ViewModel { if (encoded != null) { - var bytes = Base64Url.Decode(encoded); + var bytes = Base64Url.DecodeFromChars(encoded); var value = Encoding.UTF8.GetString(bytes); Clients = JsonSerializer.Deserialize(value) ?? Enumerable.Empty(); return; diff --git a/identity-server/hosts/Configuration/Pages/Diagnostics/ViewModel.cs b/identity-server/hosts/Configuration/Pages/Diagnostics/ViewModel.cs index e7413fb3a..14dc19bbf 100644 --- a/identity-server/hosts/Configuration/Pages/Diagnostics/ViewModel.cs +++ b/identity-server/hosts/Configuration/Pages/Diagnostics/ViewModel.cs @@ -1,9 +1,9 @@ // Copyright (c) Duende Software. All rights reserved. // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Text; using System.Text.Json; -using Duende.IdentityModel; using Microsoft.AspNetCore.Authentication; namespace IdentityServerHost.Pages.Diagnostics; @@ -18,7 +18,7 @@ public class ViewModel { if (encoded != null) { - var bytes = Base64Url.Decode(encoded); + var bytes = Base64Url.DecodeFromChars(encoded); var value = Encoding.UTF8.GetString(bytes); Clients = JsonSerializer.Deserialize(value) ?? Enumerable.Empty(); return; diff --git a/identity-server/hosts/EntityFramework-dotnet9/Pages/Diagnostics/ViewModel.cs b/identity-server/hosts/EntityFramework-dotnet9/Pages/Diagnostics/ViewModel.cs index e7413fb3a..14dc19bbf 100644 --- a/identity-server/hosts/EntityFramework-dotnet9/Pages/Diagnostics/ViewModel.cs +++ b/identity-server/hosts/EntityFramework-dotnet9/Pages/Diagnostics/ViewModel.cs @@ -1,9 +1,9 @@ // Copyright (c) Duende Software. All rights reserved. // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Text; using System.Text.Json; -using Duende.IdentityModel; using Microsoft.AspNetCore.Authentication; namespace IdentityServerHost.Pages.Diagnostics; @@ -18,7 +18,7 @@ public class ViewModel { if (encoded != null) { - var bytes = Base64Url.Decode(encoded); + var bytes = Base64Url.DecodeFromChars(encoded); var value = Encoding.UTF8.GetString(bytes); Clients = JsonSerializer.Deserialize(value) ?? Enumerable.Empty(); return; diff --git a/identity-server/hosts/EntityFramework/Pages/Diagnostics/ViewModel.cs b/identity-server/hosts/EntityFramework/Pages/Diagnostics/ViewModel.cs index e7413fb3a..14dc19bbf 100644 --- a/identity-server/hosts/EntityFramework/Pages/Diagnostics/ViewModel.cs +++ b/identity-server/hosts/EntityFramework/Pages/Diagnostics/ViewModel.cs @@ -1,9 +1,9 @@ // Copyright (c) Duende Software. All rights reserved. // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Text; using System.Text.Json; -using Duende.IdentityModel; using Microsoft.AspNetCore.Authentication; namespace IdentityServerHost.Pages.Diagnostics; @@ -18,7 +18,7 @@ public class ViewModel { if (encoded != null) { - var bytes = Base64Url.Decode(encoded); + var bytes = Base64Url.DecodeFromChars(encoded); var value = Encoding.UTF8.GetString(bytes); Clients = JsonSerializer.Deserialize(value) ?? Enumerable.Empty(); return; diff --git a/identity-server/hosts/main/Pages/Diagnostics/ViewModel.cs b/identity-server/hosts/main/Pages/Diagnostics/ViewModel.cs index e7413fb3a..14dc19bbf 100644 --- a/identity-server/hosts/main/Pages/Diagnostics/ViewModel.cs +++ b/identity-server/hosts/main/Pages/Diagnostics/ViewModel.cs @@ -1,9 +1,9 @@ // Copyright (c) Duende Software. All rights reserved. // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Text; using System.Text.Json; -using Duende.IdentityModel; using Microsoft.AspNetCore.Authentication; namespace IdentityServerHost.Pages.Diagnostics; @@ -18,7 +18,7 @@ public class ViewModel { if (encoded != null) { - var bytes = Base64Url.Decode(encoded); + var bytes = Base64Url.DecodeFromChars(encoded); var value = Encoding.UTF8.GetString(bytes); Clients = JsonSerializer.Deserialize(value) ?? Enumerable.Empty(); return; diff --git a/identity-server/src/IdentityServer/Configuration/CryptoHelper.cs b/identity-server/src/IdentityServer/Configuration/CryptoHelper.cs index 3a74fac1a..acee5bff6 100644 --- a/identity-server/src/IdentityServer/Configuration/CryptoHelper.cs +++ b/identity-server/src/IdentityServer/Configuration/CryptoHelper.cs @@ -4,6 +4,7 @@ #nullable enable +using System.Buffers.Text; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Text; @@ -70,7 +71,7 @@ public static class CryptoHelper var leftPart = new byte[size]; Array.Copy(hash, leftPart, size); - return Base64Url.Encode(leftPart); + return Base64Url.EncodeToString(leftPart); } /// diff --git a/identity-server/src/IdentityServer/Extensions/AuthenticationPropertiesExtensions.cs b/identity-server/src/IdentityServer/Extensions/AuthenticationPropertiesExtensions.cs index f9a90be67..1cd60d896 100644 --- a/identity-server/src/IdentityServer/Extensions/AuthenticationPropertiesExtensions.cs +++ b/identity-server/src/IdentityServer/Extensions/AuthenticationPropertiesExtensions.cs @@ -2,8 +2,8 @@ // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Text; -using Duende.IdentityModel; using Microsoft.AspNetCore.Authentication; namespace Duende.IdentityServer.Extensions; @@ -91,7 +91,7 @@ public static class AuthenticationPropertiesExtensions { if (value.IsPresent()) { - var bytes = Base64Url.Decode(value); + var bytes = Base64Url.DecodeFromChars(value); value = Encoding.UTF8.GetString(bytes); return ObjectSerializer.FromString(value); } @@ -105,7 +105,7 @@ public static class AuthenticationPropertiesExtensions { var value = ObjectSerializer.ToString(list); var bytes = Encoding.UTF8.GetBytes(value); - value = Base64Url.Encode(bytes); + value = Base64Url.EncodeToString(bytes); return value; } diff --git a/identity-server/src/IdentityServer/Extensions/JsonWebKeyExtensions.cs b/identity-server/src/IdentityServer/Extensions/JsonWebKeyExtensions.cs index 753d85f5b..f72e0b300 100644 --- a/identity-server/src/IdentityServer/Extensions/JsonWebKeyExtensions.cs +++ b/identity-server/src/IdentityServer/Extensions/JsonWebKeyExtensions.cs @@ -2,6 +2,7 @@ // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Text.Json; using Duende.IdentityModel; using Microsoft.IdentityModel.Tokens; @@ -30,7 +31,7 @@ internal static class JsonWebKeyExtensions /// public static string CreateThumbprint(this JsonWebKey jwk) { - var jkt = Base64Url.Encode(jwk.ComputeJwkThumbprint()); + var jkt = Base64Url.EncodeToString(jwk.ComputeJwkThumbprint()); return jkt; } } diff --git a/identity-server/src/IdentityServer/Extensions/ValidatedAuthorizeRequestExtensions.cs b/identity-server/src/IdentityServer/Extensions/ValidatedAuthorizeRequestExtensions.cs index b63641946..29815ae1c 100644 --- a/identity-server/src/IdentityServer/Extensions/ValidatedAuthorizeRequestExtensions.cs +++ b/identity-server/src/IdentityServer/Extensions/ValidatedAuthorizeRequestExtensions.cs @@ -2,6 +2,7 @@ // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Collections.Specialized; using System.Globalization; using System.Security.Cryptography; @@ -159,7 +160,7 @@ public static class ValidatedAuthorizeRequestExtensions var bytes = Encoding.UTF8.GetBytes(clientId + origin + sessionId + salt); var hash = SHA256.HashData(bytes); - return Base64Url.Encode(hash) + "." + salt; + return Base64Url.EncodeToString(hash) + "." + salt; } private static NameValueCollection ToOptimizedRawValues(this ValidatedAuthorizeRequest request) @@ -170,7 +171,7 @@ public static class ValidatedAuthorizeRequestExtensions var collection = new NameValueCollection(); foreach (var key in request.Raw.AllKeys) { - // https://openid.net/specs/openid-connect-core-1_0.html#JWTRequests + // https://openid.net/specs/openid-connect-core-1_0.html#JWTRequests // requires client id and response type to always be in URL if (key == OidcConstants.AuthorizeRequest.ClientId || key == OidcConstants.AuthorizeRequest.ResponseType || diff --git a/identity-server/src/IdentityServer/Extensions/X509CertificateExtensions.cs b/identity-server/src/IdentityServer/Extensions/X509CertificateExtensions.cs index d0c4d424c..e06df5329 100644 --- a/identity-server/src/IdentityServer/Extensions/X509CertificateExtensions.cs +++ b/identity-server/src/IdentityServer/Extensions/X509CertificateExtensions.cs @@ -2,10 +2,10 @@ // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Text.Json; -using Duende.IdentityModel; namespace Duende.IdentityServer.Extensions; @@ -35,5 +35,5 @@ public static class X509CertificateExtensions /// Returns the SHA256 thumbprint of the certificate as a base64url encoded string /// /// - public static string GetSha256Thumbprint(this X509Certificate2 certificate) => Base64Url.Encode(certificate.GetCertHash(HashAlgorithmName.SHA256)); + public static string GetSha256Thumbprint(this X509Certificate2 certificate) => Base64Url.EncodeToString(certificate.GetCertHash(HashAlgorithmName.SHA256)); } diff --git a/identity-server/src/IdentityServer/Models/Messages/ConsentRequest.cs b/identity-server/src/IdentityServer/Models/Messages/ConsentRequest.cs index 247bc34f2..632a31d29 100644 --- a/identity-server/src/IdentityServer/Models/Messages/ConsentRequest.cs +++ b/identity-server/src/IdentityServer/Models/Messages/ConsentRequest.cs @@ -2,6 +2,7 @@ // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Collections.Specialized; using System.Security.Cryptography; using System.Text; @@ -89,7 +90,7 @@ public class ConsentRequest var bytes = Encoding.UTF8.GetBytes(value); var hash = SHA256.HashData(bytes); - return Base64Url.Encode(hash); + return Base64Url.EncodeToString(hash); } } } diff --git a/identity-server/src/IdentityServer/ResponseHandling/Default/DiscoveryResponseGenerator.cs b/identity-server/src/IdentityServer/ResponseHandling/Default/DiscoveryResponseGenerator.cs index 0c533f64f..23a1c8135 100644 --- a/identity-server/src/IdentityServer/ResponseHandling/Default/DiscoveryResponseGenerator.cs +++ b/identity-server/src/IdentityServer/ResponseHandling/Default/DiscoveryResponseGenerator.cs @@ -2,6 +2,7 @@ // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Security.Cryptography; using Duende.IdentityModel; using Duende.IdentityServer.Configuration; @@ -431,13 +432,13 @@ public class DiscoveryResponseGenerator : IDiscoveryResponseGenerator if (key.Key is X509SecurityKey x509Key) { var cert64 = Convert.ToBase64String(x509Key.Certificate.RawData); - var thumbprint = Base64Url.Encode(x509Key.Certificate.GetCertHash()); + var thumbprint = Base64Url.EncodeToString(x509Key.Certificate.GetCertHash()); if (x509Key.PublicKey is RSA rsa) { var parameters = rsa.ExportParameters(false); - var exponent = Base64Url.Encode(parameters.Exponent); - var modulus = Base64Url.Encode(parameters.Modulus); + var exponent = Base64Url.EncodeToString(parameters.Exponent); + var modulus = Base64Url.EncodeToString(parameters.Modulus); var rsaJsonWebKey = new Models.JsonWebKey { @@ -455,8 +456,8 @@ public class DiscoveryResponseGenerator : IDiscoveryResponseGenerator else if (x509Key.PublicKey is ECDsa ecdsa) { var parameters = ecdsa.ExportParameters(false); - var x = Base64Url.Encode(parameters.Q.X); - var y = Base64Url.Encode(parameters.Q.Y); + var x = Base64Url.EncodeToString(parameters.Q.X); + var y = Base64Url.EncodeToString(parameters.Q.Y); var ecdsaJsonWebKey = new Models.JsonWebKey { @@ -480,8 +481,8 @@ public class DiscoveryResponseGenerator : IDiscoveryResponseGenerator else if (key.Key is RsaSecurityKey rsaKey) { var parameters = rsaKey.Rsa?.ExportParameters(false) ?? rsaKey.Parameters; - var exponent = Base64Url.Encode(parameters.Exponent); - var modulus = Base64Url.Encode(parameters.Modulus); + var exponent = Base64Url.EncodeToString(parameters.Exponent); + var modulus = Base64Url.EncodeToString(parameters.Modulus); var webKey = new Models.JsonWebKey { @@ -498,8 +499,8 @@ public class DiscoveryResponseGenerator : IDiscoveryResponseGenerator else if (key.Key is ECDsaSecurityKey ecdsaKey) { var parameters = ecdsaKey.ECDsa.ExportParameters(false); - var x = Base64Url.Encode(parameters.Q.X); - var y = Base64Url.Encode(parameters.Q.Y); + var x = Base64Url.EncodeToString(parameters.Q.X); + var y = Base64Url.EncodeToString(parameters.Q.Y); var ecdsaJsonWebKey = new Models.JsonWebKey { diff --git a/identity-server/src/IdentityServer/Stores/Default/ProtectedDataMessageStore.cs b/identity-server/src/IdentityServer/Stores/Default/ProtectedDataMessageStore.cs index 321ef61c8..86e73b3b3 100644 --- a/identity-server/src/IdentityServer/Stores/Default/ProtectedDataMessageStore.cs +++ b/identity-server/src/IdentityServer/Stores/Default/ProtectedDataMessageStore.cs @@ -2,8 +2,8 @@ // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Text; -using Duende.IdentityModel; using Duende.IdentityServer.Models; using Microsoft.AspNetCore.DataProtection; using Microsoft.Extensions.Logging; @@ -50,7 +50,7 @@ public class ProtectedDataMessageStore : IMessageStore { try { - var bytes = Base64Url.Decode(value); + var bytes = Base64Url.DecodeFromChars(value); bytes = Protector.Unprotect(bytes); var json = Encoding.UTF8.GetString(bytes); result = ObjectSerializer.FromString>(json); @@ -76,7 +76,7 @@ public class ProtectedDataMessageStore : IMessageStore var json = ObjectSerializer.ToString(message); var bytes = Encoding.UTF8.GetBytes(json); bytes = Protector.Protect(bytes); - value = Base64Url.Encode(bytes); + value = Base64Url.EncodeToString(bytes); } catch (Exception ex) { diff --git a/identity-server/src/IdentityServer/Validation/Default/DefaultDPoPProofValidator.cs b/identity-server/src/IdentityServer/Validation/Default/DefaultDPoPProofValidator.cs index 1acec1216..f324b03b8 100644 --- a/identity-server/src/IdentityServer/Validation/Default/DefaultDPoPProofValidator.cs +++ b/identity-server/src/IdentityServer/Validation/Default/DefaultDPoPProofValidator.cs @@ -2,6 +2,7 @@ // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Security.Cryptography; using System.Text; using System.Text.Json; @@ -299,7 +300,7 @@ public class DefaultDPoPProofValidator : IDPoPProofValidator var bytes = Encoding.UTF8.GetBytes(context.AccessToken); var hash = SHA256.HashData(bytes); - var accessTokenHash = Base64Url.Encode(hash); + var accessTokenHash = Base64Url.EncodeToString(hash); if (accessTokenHash != result.AccessTokenHash) { result.IsError = true; @@ -399,7 +400,7 @@ public class DefaultDPoPProofValidator : IDPoPProofValidator skew = Options.DPoP.ServerClockSkew; } - // we do x2 here because clock might be might be before or after, so we're making cache duration + // we do x2 here because clock might be might be before or after, so we're making cache duration // longer than the likelyhood of proof token expiration, which is done before replay skew *= 2; var cacheDuration = Options.DPoP.ProofTokenValidityDuration + skew; diff --git a/identity-server/src/IdentityServer/Validation/Default/TokenRequestValidator.cs b/identity-server/src/IdentityServer/Validation/Default/TokenRequestValidator.cs index 2ec774a36..6abf040e3 100644 --- a/identity-server/src/IdentityServer/Validation/Default/TokenRequestValidator.cs +++ b/identity-server/src/IdentityServer/Validation/Default/TokenRequestValidator.cs @@ -2,6 +2,7 @@ // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Collections.Specialized; using System.Text; using Duende.IdentityModel; @@ -1231,7 +1232,7 @@ internal class TokenRequestValidator : ITokenRequestValidator var codeVerifierBytes = Encoding.ASCII.GetBytes(codeVerifier); var hashedBytes = codeVerifierBytes.Sha256(); - var transformedCodeVerifier = Base64Url.Encode(hashedBytes); + var transformedCodeVerifier = Base64Url.EncodeToString(hashedBytes); return TimeConstantComparer.IsEqual(transformedCodeVerifier.Sha256(), codeChallenge); } diff --git a/identity-server/test/IdentityServer.IntegrationTests/Clients/ClientAssertionClient.cs b/identity-server/test/IdentityServer.IntegrationTests/Clients/ClientAssertionClient.cs index d02788be8..b0fec4358 100644 --- a/identity-server/test/IdentityServer.IntegrationTests/Clients/ClientAssertionClient.cs +++ b/identity-server/test/IdentityServer.IntegrationTests/Clients/ClientAssertionClient.cs @@ -2,6 +2,7 @@ // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; @@ -217,7 +218,7 @@ public class ClientAssertionClient { var token = response.AccessToken.Split('.').Skip(1).Take(1).First(); var dictionary = JsonSerializer.Deserialize>( - Encoding.UTF8.GetString(Base64Url.Decode(token))); + Encoding.UTF8.GetString(Base64Url.DecodeFromChars(token))); return dictionary; } diff --git a/identity-server/test/IdentityServer.IntegrationTests/Clients/ClientCredentialsClient.cs b/identity-server/test/IdentityServer.IntegrationTests/Clients/ClientCredentialsClient.cs index c4cad3d00..151e166dc 100644 --- a/identity-server/test/IdentityServer.IntegrationTests/Clients/ClientCredentialsClient.cs +++ b/identity-server/test/IdentityServer.IntegrationTests/Clients/ClientCredentialsClient.cs @@ -2,6 +2,7 @@ // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Net; using System.Text; using System.Text.Json; @@ -427,7 +428,7 @@ public class ClientCredentialsClient { var token = response.AccessToken.Split('.').Skip(1).Take(1).First(); var dictionary = JsonSerializer.Deserialize>( - Encoding.UTF8.GetString(Base64Url.Decode(token))); + Encoding.UTF8.GetString(Base64Url.DecodeFromChars(token))); return dictionary; } diff --git a/identity-server/test/IdentityServer.IntegrationTests/Clients/CustomTokenResponseClients.cs b/identity-server/test/IdentityServer.IntegrationTests/Clients/CustomTokenResponseClients.cs index b1ad9e728..8f9231fce 100644 --- a/identity-server/test/IdentityServer.IntegrationTests/Clients/CustomTokenResponseClients.cs +++ b/identity-server/test/IdentityServer.IntegrationTests/Clients/CustomTokenResponseClients.cs @@ -2,9 +2,9 @@ // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Text; using System.Text.Json; -using Duende.IdentityModel; using Duende.IdentityModel.Client; using IntegrationTests.Clients.Setup; using Microsoft.AspNetCore.Hosting; @@ -268,7 +268,7 @@ public class CustomTokenResponseClients { var token = response.AccessToken.Split('.').Skip(1).Take(1).First(); var dictionary = JsonSerializer.Deserialize>( - Encoding.UTF8.GetString(Base64Url.Decode(token))); + Encoding.UTF8.GetString(Base64Url.DecodeFromChars(token))); return dictionary; } diff --git a/identity-server/test/IdentityServer.IntegrationTests/Clients/ExtensionGrantClient.cs b/identity-server/test/IdentityServer.IntegrationTests/Clients/ExtensionGrantClient.cs index ea055025f..b1fa62e9e 100644 --- a/identity-server/test/IdentityServer.IntegrationTests/Clients/ExtensionGrantClient.cs +++ b/identity-server/test/IdentityServer.IntegrationTests/Clients/ExtensionGrantClient.cs @@ -2,6 +2,7 @@ // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.IdentityModel.Tokens.Jwt; using System.Net; using System.Text; @@ -582,7 +583,7 @@ public class ExtensionGrantClient { var token = response.AccessToken.Split('.').Skip(1).Take(1).First(); var dictionary = JsonSerializer.Deserialize>( - Encoding.UTF8.GetString(Base64Url.Decode(token))); + Encoding.UTF8.GetString(Base64Url.DecodeFromChars(token))); return dictionary; } diff --git a/identity-server/test/IdentityServer.IntegrationTests/Clients/ResourceOwnerClient.cs b/identity-server/test/IdentityServer.IntegrationTests/Clients/ResourceOwnerClient.cs index 4607b0107..644b765b0 100644 --- a/identity-server/test/IdentityServer.IntegrationTests/Clients/ResourceOwnerClient.cs +++ b/identity-server/test/IdentityServer.IntegrationTests/Clients/ResourceOwnerClient.cs @@ -2,10 +2,10 @@ // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Net; using System.Text; using System.Text.Json; -using Duende.IdentityModel; using Duende.IdentityModel.Client; using IntegrationTests.Clients.Setup; using Microsoft.AspNetCore.Hosting; @@ -262,7 +262,7 @@ public class ResourceOwnerClient { var token = response.AccessToken.Split('.').Skip(1).Take(1).First(); var dictionary = JsonSerializer.Deserialize>( - Encoding.UTF8.GetString(Base64Url.Decode(token))); + Encoding.UTF8.GetString(Base64Url.DecodeFromChars(token))); return dictionary; } diff --git a/identity-server/test/IdentityServer.IntegrationTests/Clients/UserInfoClient.cs b/identity-server/test/IdentityServer.IntegrationTests/Clients/UserInfoClient.cs index 83287304b..fe57fa54f 100644 --- a/identity-server/test/IdentityServer.IntegrationTests/Clients/UserInfoClient.cs +++ b/identity-server/test/IdentityServer.IntegrationTests/Clients/UserInfoClient.cs @@ -2,10 +2,10 @@ // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Net; using System.Text; using System.Text.Json; -using Duende.IdentityModel; using Duende.IdentityModel.Client; using IntegrationTests.Clients.Setup; using Microsoft.AspNetCore.Hosting; @@ -197,7 +197,7 @@ public class UserInfoEndpointClient { var token = response.AccessToken.Split('.').Skip(1).Take(1).First(); var dictionary = JsonSerializer.Deserialize>( - Encoding.UTF8.GetString(Base64Url.Decode(token))); + Encoding.UTF8.GetString(Base64Url.DecodeFromChars(token))); return dictionary; } diff --git a/identity-server/test/IdentityServer.IntegrationTests/Conformance/Pkce/PkceTests.cs b/identity-server/test/IdentityServer.IntegrationTests/Conformance/Pkce/PkceTests.cs index 75b641fdc..2ac2132e9 100644 --- a/identity-server/test/IdentityServer.IntegrationTests/Conformance/Pkce/PkceTests.cs +++ b/identity-server/test/IdentityServer.IntegrationTests/Conformance/Pkce/PkceTests.cs @@ -2,6 +2,7 @@ // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Security.Claims; using System.Text; using Duende.IdentityModel; @@ -529,7 +530,7 @@ public class PkceTests { var codeVerifierBytes = Encoding.ASCII.GetBytes(codeVerifier); var hashedBytes = codeVerifierBytes.Sha256(); - var transformedCodeVerifier = Base64Url.Encode(hashedBytes); + var transformedCodeVerifier = Base64Url.EncodeToString(hashedBytes); return transformedCodeVerifier; } diff --git a/identity-server/test/IdentityServer.IntegrationTests/Endpoints/EndSession/EndSessionTests.cs b/identity-server/test/IdentityServer.IntegrationTests/Endpoints/EndSession/EndSessionTests.cs index 505fffcf5..26b8eb855 100644 --- a/identity-server/test/IdentityServer.IntegrationTests/Endpoints/EndSession/EndSessionTests.cs +++ b/identity-server/test/IdentityServer.IntegrationTests/Endpoints/EndSession/EndSessionTests.cs @@ -2,6 +2,7 @@ // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Net; using System.Security.Claims; using System.Text; @@ -535,7 +536,7 @@ public class EndSessionTests var parts = token.Split('.'); parts.Length.ShouldBe(3); - var bytes = Base64Url.Decode(parts[1]); + var bytes = Base64Url.DecodeFromChars(parts[1]); var json = Encoding.UTF8.GetString(bytes); var payload = JsonSerializer.Deserialize>(json); @@ -583,7 +584,7 @@ public class EndSessionTests var parts = token.Split('.'); parts.Length.ShouldBe(3); - var bytes = Base64Url.Decode(parts[0]); + var bytes = Base64Url.DecodeFromChars(parts[0]); var json = Encoding.UTF8.GetString(bytes); var header = JsonSerializer.Deserialize>(json); @@ -623,7 +624,7 @@ public class EndSessionTests var parts = token.Split('.'); parts.Length.ShouldBe(3); - var bytes = Base64Url.Decode(parts[0]); + var bytes = Base64Url.DecodeFromChars(parts[0]); var json = Encoding.UTF8.GetString(bytes); var header = JsonSerializer.Deserialize>(json); diff --git a/identity-server/test/IdentityServer.IntegrationTests/Endpoints/Token/RefreshTokenTests.cs b/identity-server/test/IdentityServer.IntegrationTests/Endpoints/Token/RefreshTokenTests.cs index 0500d219f..f7d31eb1e 100644 --- a/identity-server/test/IdentityServer.IntegrationTests/Endpoints/Token/RefreshTokenTests.cs +++ b/identity-server/test/IdentityServer.IntegrationTests/Endpoints/Token/RefreshTokenTests.cs @@ -2,9 +2,9 @@ // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Security.Claims; using System.Text.Json; -using Duende.IdentityModel; using Duende.IdentityModel.Client; using Duende.IdentityServer.Models; using Duende.IdentityServer.Test; @@ -97,7 +97,7 @@ public class RefreshTokenTests tokenResult1.AccessToken.ShouldNotBeNull(); - var payload1 = JsonSerializer.Deserialize(Base64Url.Decode(tokenResult1.AccessToken.Split('.')[1])); + var payload1 = JsonSerializer.Deserialize(Base64Url.DecodeFromChars(tokenResult1.AccessToken.Split('.')[1])); var sid1 = payload1.TryGetValue("sid").GetString(); sid1.ShouldBe(_mockPipeline.GetSessionCookie().Value); @@ -114,7 +114,7 @@ public class RefreshTokenTests tokenResult2.IsError.ShouldBeFalse(); tokenResult2.AccessToken.ShouldNotBeNull(); - var payload2 = JsonSerializer.Deserialize(Base64Url.Decode(tokenResult2.AccessToken.Split('.')[1])); + var payload2 = JsonSerializer.Deserialize(Base64Url.DecodeFromChars(tokenResult2.AccessToken.Split('.')[1])); var sid2 = payload2.TryGetValue("sid").GetString(); sid1.ShouldBe(sid2); } @@ -155,7 +155,7 @@ public class RefreshTokenTests tokenResult1.AccessToken.ShouldNotBeNull(); - var payload1 = JsonSerializer.Deserialize(Base64Url.Decode(tokenResult1.AccessToken.Split('.')[1])); + var payload1 = JsonSerializer.Deserialize(Base64Url.DecodeFromChars(tokenResult1.AccessToken.Split('.')[1])); var sid1 = payload1.TryGetValue("sid").GetString(); sid1.ShouldBe(_mockPipeline.GetSessionCookie().Value); @@ -172,7 +172,7 @@ public class RefreshTokenTests tokenResult2.IsError.ShouldBeFalse(); tokenResult2.AccessToken.ShouldNotBeNull(); - var payload2 = JsonSerializer.Deserialize(Base64Url.Decode(tokenResult2.AccessToken.Split('.')[1])); + var payload2 = JsonSerializer.Deserialize(Base64Url.DecodeFromChars(tokenResult2.AccessToken.Split('.')[1])); var sid2 = payload2.TryGetValue("sid").GetString(); sid1.ShouldBe(sid2); } diff --git a/identity-server/test/IdentityServer.IntegrationTests/Extensibility/CustomClaimsServiceTests.cs b/identity-server/test/IdentityServer.IntegrationTests/Extensibility/CustomClaimsServiceTests.cs index fc740ca0e..99b299819 100644 --- a/identity-server/test/IdentityServer.IntegrationTests/Extensibility/CustomClaimsServiceTests.cs +++ b/identity-server/test/IdentityServer.IntegrationTests/Extensibility/CustomClaimsServiceTests.cs @@ -2,10 +2,10 @@ // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Security.Claims; using System.Text; using System.Text.Json; -using Duende.IdentityModel; using Duende.IdentityModel.Client; using Duende.IdentityServer.Models; using Duende.IdentityServer.Services; @@ -64,7 +64,7 @@ public class CustomClaimsServiceTests var accessToken = result.AccessToken; var payload = accessToken.Split('.')[1]; - var json = Encoding.UTF8.GetString(Base64Url.Decode(payload)); + var json = Encoding.UTF8.GetString(Base64Url.DecodeFromChars(payload)); var obj = JsonSerializer.Deserialize>(json); obj["foo"].GetString().ShouldBe("foo1"); diff --git a/identity-server/test/IdentityServer.IntegrationTests/Extensibility/CustomProfileServiceTests.cs b/identity-server/test/IdentityServer.IntegrationTests/Extensibility/CustomProfileServiceTests.cs index 237ee3b9d..51573e50f 100644 --- a/identity-server/test/IdentityServer.IntegrationTests/Extensibility/CustomProfileServiceTests.cs +++ b/identity-server/test/IdentityServer.IntegrationTests/Extensibility/CustomProfileServiceTests.cs @@ -2,11 +2,11 @@ // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Net; using System.Security.Claims; using System.Text; using System.Text.Json; -using Duende.IdentityModel; using Duende.IdentityServer.Models; using Duende.IdentityServer.Services; using IntegrationTests.Common; @@ -73,7 +73,7 @@ public class CustomProfileServiceTests authorization.IdentityToken.ShouldNotBeNull(); var payload = authorization.IdentityToken.Split('.')[1]; - var json = Encoding.UTF8.GetString(Base64Url.Decode(payload)); + var json = Encoding.UTF8.GetString(Base64Url.DecodeFromChars(payload)); var obj = JsonSerializer.Deserialize>(json); obj["foo"].GetString().ShouldBe("bar"); diff --git a/identity-server/test/IdentityServer.IntegrationTests/Extensibility/CustomTokenCreationServiceTests.cs b/identity-server/test/IdentityServer.IntegrationTests/Extensibility/CustomTokenCreationServiceTests.cs index 13f3acce5..0cc7f18ae 100644 --- a/identity-server/test/IdentityServer.IntegrationTests/Extensibility/CustomTokenCreationServiceTests.cs +++ b/identity-server/test/IdentityServer.IntegrationTests/Extensibility/CustomTokenCreationServiceTests.cs @@ -2,9 +2,9 @@ // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Text; using System.Text.Json; -using Duende.IdentityModel; using Duende.IdentityModel.Client; using Duende.IdentityServer; using Duende.IdentityServer.Configuration; @@ -64,7 +64,7 @@ public class CustomTokenCreationServiceTests var accessToken = result.AccessToken; var payload = accessToken.Split('.')[1]; - var json = Encoding.UTF8.GetString(Base64Url.Decode(payload)); + var json = Encoding.UTF8.GetString(Base64Url.DecodeFromChars(payload)); var obj = JsonSerializer.Deserialize>(json); obj["aud"].ToStringList().ShouldContain("custom1"); diff --git a/identity-server/test/IdentityServer.IntegrationTests/Hosting/LocalApiAuthentication/LocalApiAuthenticationTests.cs b/identity-server/test/IdentityServer.IntegrationTests/Hosting/LocalApiAuthentication/LocalApiAuthenticationTests.cs index bf7574728..53125a1ab 100644 --- a/identity-server/test/IdentityServer.IntegrationTests/Hosting/LocalApiAuthentication/LocalApiAuthenticationTests.cs +++ b/identity-server/test/IdentityServer.IntegrationTests/Hosting/LocalApiAuthentication/LocalApiAuthenticationTests.cs @@ -2,6 +2,7 @@ // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.IdentityModel.Tokens.Jwt; using System.Net; using System.Net.Http.Headers; @@ -212,11 +213,11 @@ public class LocalApiAuthenticationTests if (!string.IsNullOrWhiteSpace(accessToken)) { - // ath: hash of the access token. The value MUST be the result of a base64url encoding + // ath: hash of the access token. The value MUST be the result of a base64url encoding // the SHA-256 hash of the ASCII encoding of the associated access token's value. using var sha256 = SHA256.Create(); var hash = sha256.ComputeHash(Encoding.ASCII.GetBytes(accessToken)); - var ath = Base64Url.Encode(hash); + var ath = Base64Url.EncodeToString(hash); payload.Add(JwtClaimTypes.DPoPAccessTokenHash, ath); } @@ -293,7 +294,7 @@ public class LocalApiAuthenticationTests // so it should fail. var newKey = GenerateJwk(); var newJwk = new Microsoft.IdentityModel.Tokens.JsonWebKey(newKey); - var newJkt = Base64Url.Encode(newJwk.ComputeJwkThumbprint()); + var newJkt = Base64Url.EncodeToString(newJwk.ComputeJwkThumbprint()); var proofToken = CreateProofToken("GET", "https://server/api", at, jwkString: newKey); req.Headers.Add("DPoP", proofToken); @@ -328,7 +329,7 @@ public class LocalApiAuthenticationTests // so it should fail. var newKey = GenerateJwk(); var newJwk = new Microsoft.IdentityModel.Tokens.JsonWebKey(newKey); - var newJkt = Base64Url.Encode(newJwk.ComputeJwkThumbprint()); + var newJkt = Base64Url.EncodeToString(newJwk.ComputeJwkThumbprint()); var proofToken = CreateProofToken("GET", "https://server/api", at, jwkString: newKey); req.Headers.Add("DPoP", proofToken); diff --git a/identity-server/test/IdentityServer.UnitTests/Services/Default/DefaultBackChannelLogoutServiceTests.cs b/identity-server/test/IdentityServer.UnitTests/Services/Default/DefaultBackChannelLogoutServiceTests.cs index af2e6104b..3bf04ed56 100644 --- a/identity-server/test/IdentityServer.UnitTests/Services/Default/DefaultBackChannelLogoutServiceTests.cs +++ b/identity-server/test/IdentityServer.UnitTests/Services/Default/DefaultBackChannelLogoutServiceTests.cs @@ -2,8 +2,8 @@ // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Text.Json; -using Duende.IdentityModel; using Duende.IdentityServer; using Duende.IdentityServer.Configuration; using Duende.IdentityServer.Services; @@ -62,7 +62,7 @@ public class DefaultBackChannelLogoutServiceTests }); - var payload = JsonSerializer.Deserialize>(Base64Url.Decode(rawToken.Split('.')[1])); + var payload = JsonSerializer.Deserialize>(Base64Url.DecodeFromChars(rawToken.Split('.')[1])); payload["iss"].GetString().ShouldBe(expected); } } diff --git a/identity-server/test/IdentityServer.UnitTests/Validation/DPoPProofValidatorTests.cs b/identity-server/test/IdentityServer.UnitTests/Validation/DPoPProofValidatorTests.cs index 19bba6035..caeeb5b3d 100644 --- a/identity-server/test/IdentityServer.UnitTests/Validation/DPoPProofValidatorTests.cs +++ b/identity-server/test/IdentityServer.UnitTests/Validation/DPoPProofValidatorTests.cs @@ -1,6 +1,7 @@ // Copyright (c) Duende Software. All rights reserved. // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Security.Claims; using System.Security.Cryptography; using System.Text; @@ -168,7 +169,7 @@ public class DPoPProofValidatorTests using var sha = SHA256.Create(); var bytes = Encoding.UTF8.GetBytes(_context.AccessToken); var hash = sha.ComputeHash(bytes); - return Base64Url.Encode(hash); + return Base64Url.EncodeToString(hash); } [Fact] diff --git a/identity-server/test/IdentityServer.UnitTests/Validation/IdentityTokenValidation.cs b/identity-server/test/IdentityServer.UnitTests/Validation/IdentityTokenValidation.cs index 949a38d5e..ca9f0bc18 100644 --- a/identity-server/test/IdentityServer.UnitTests/Validation/IdentityTokenValidation.cs +++ b/identity-server/test/IdentityServer.UnitTests/Validation/IdentityTokenValidation.cs @@ -2,6 +2,7 @@ // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.IdentityModel.Tokens.Jwt; using System.Text; using System.Text.Json; @@ -93,7 +94,7 @@ public class IdentityTokenValidation // check that the custom aud was ignored var payload = jwt.Split('.')[1]; - var json = Encoding.UTF8.GetString(Base64Url.Decode(payload)); + var json = Encoding.UTF8.GetString(Base64Url.DecodeFromChars(payload)); var values = JsonSerializer.Deserialize>(json); values["aud"].GetString().ShouldBe("roclient"); } diff --git a/identity-server/test/IdentityServer.UnitTests/Validation/TokenRequest Validation/TokenRequestValidation_PKCE.cs b/identity-server/test/IdentityServer.UnitTests/Validation/TokenRequest Validation/TokenRequestValidation_PKCE.cs index be005306a..19ee332ed 100644 --- a/identity-server/test/IdentityServer.UnitTests/Validation/TokenRequest Validation/TokenRequestValidation_PKCE.cs +++ b/identity-server/test/IdentityServer.UnitTests/Validation/TokenRequest Validation/TokenRequestValidation_PKCE.cs @@ -2,6 +2,7 @@ // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Collections.Specialized; using System.Text; using Duende.IdentityModel; @@ -316,7 +317,7 @@ public class TokenRequestValidation_PKCE { var codeVerifierBytes = Encoding.ASCII.GetBytes(codeVerifier); var hashedBytes = codeVerifierBytes.Sha256(); - var transformedCodeVerifier = Base64Url.Encode(hashedBytes); + var transformedCodeVerifier = Base64Url.EncodeToString(hashedBytes); return transformedCodeVerifier; } From 33a6d44c02771b756a5de1ca358402c444e915b9 Mon Sep 17 00:00:00 2001 From: Brett Hazen <2651260+bhazen@users.noreply.github.com> Date: Tue, 9 Dec 2025 13:51:34 -0600 Subject: [PATCH 2/3] Dotnet format to fix failing CI builds --- .../DPoPIntegrationTests.cs | 1 - .../TestDPoPNonceStore.cs | 2 -- bff/hosts/Hosts.Bff.InMemory/LocalApiController.cs | 1 + bff/hosts/Hosts.ServiceDefaults/AppHostServices.cs | 1 + bff/src/Bff.Yarp/Internal/RemoteRouteHandler.cs | 1 + bff/test/Bff.Tests/ConventionTests.cs | 1 + 6 files changed, 4 insertions(+), 3 deletions(-) diff --git a/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/DPoPIntegrationTests.cs b/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/DPoPIntegrationTests.cs index f4e83d6af..3062bbec3 100644 --- a/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/DPoPIntegrationTests.cs +++ b/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/DPoPIntegrationTests.cs @@ -5,7 +5,6 @@ using System.Net; using System.Net.Http.Json; using System.Security.Cryptography; using System.Text.Json; -using Duende.AccessTokenManagement; using Duende.AccessTokenManagement.OpenIdConnect; using Duende.AspNetCore.Authentication.JwtBearer.DPoP; using Duende.AspNetCore.TestFramework; diff --git a/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/TestDPoPNonceStore.cs b/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/TestDPoPNonceStore.cs index 2734d7b48..80f6ce575 100644 --- a/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/TestDPoPNonceStore.cs +++ b/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/TestDPoPNonceStore.cs @@ -1,8 +1,6 @@ // Copyright (c) Duende Software. All rights reserved. // See LICENSE in the project root for license information. -using Duende.AccessTokenManagement; - namespace Duende.AspNetCore.Authentication.JwtBearer; public class TestDPoPNonceStore : IDPoPNonceStore diff --git a/bff/hosts/Hosts.Bff.InMemory/LocalApiController.cs b/bff/hosts/Hosts.Bff.InMemory/LocalApiController.cs index 6444e8f30..034f10b44 100644 --- a/bff/hosts/Hosts.Bff.InMemory/LocalApiController.cs +++ b/bff/hosts/Hosts.Bff.InMemory/LocalApiController.cs @@ -5,6 +5,7 @@ using System.Text.Json; using Microsoft.AspNetCore.Mvc; namespace Host8; + [Route("local")] public class LocalApiController : ControllerBase { diff --git a/bff/hosts/Hosts.ServiceDefaults/AppHostServices.cs b/bff/hosts/Hosts.ServiceDefaults/AppHostServices.cs index f01ac7edc..5ddee973f 100644 --- a/bff/hosts/Hosts.ServiceDefaults/AppHostServices.cs +++ b/bff/hosts/Hosts.ServiceDefaults/AppHostServices.cs @@ -2,6 +2,7 @@ // See LICENSE in the project root for license information. namespace Hosts.ServiceDefaults; + public static class AppHostServices { public const string BffPerf = "bff-perf"; diff --git a/bff/src/Bff.Yarp/Internal/RemoteRouteHandler.cs b/bff/src/Bff.Yarp/Internal/RemoteRouteHandler.cs index b42537dfa..ef1830cdd 100644 --- a/bff/src/Bff.Yarp/Internal/RemoteRouteHandler.cs +++ b/bff/src/Bff.Yarp/Internal/RemoteRouteHandler.cs @@ -9,6 +9,7 @@ using Yarp.ReverseProxy.Forwarder; using Yarp.ReverseProxy.Transforms.Builder; namespace Duende.Bff.Yarp.Internal; + internal class RemoteRouteHandler( SelectedFrontend selectedFrontend, IHttpForwarder httpForwarder, diff --git a/bff/test/Bff.Tests/ConventionTests.cs b/bff/test/Bff.Tests/ConventionTests.cs index a32653e1d..c7cf845dc 100644 --- a/bff/test/Bff.Tests/ConventionTests.cs +++ b/bff/test/Bff.Tests/ConventionTests.cs @@ -17,6 +17,7 @@ using Duende.Bff.Yarp; using Xunit.Abstractions; namespace Duende.Bff.Tests; + public class ConventionTests(ITestOutputHelper output) { public static readonly Assembly BffAssembly = typeof(BffBuilder).Assembly; From ee2452bb49c6e430d2d34da197e9e88ccc279af2 Mon Sep 17 00:00:00 2001 From: Brett Hazen <2651260+bhazen@users.noreply.github.com> Date: Tue, 9 Dec 2025 14:09:33 -0600 Subject: [PATCH 3/3] Constraint ATM.OpenIdConnect version in JwtBearerExtensions --- .../AspNetCore.Authentication.JwtBearer.Tests.csproj | 2 +- .../DPoPIntegrationTests.cs | 1 + .../TestDPoPNonceStore.cs | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/AspNetCore.Authentication.JwtBearer.Tests.csproj b/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/AspNetCore.Authentication.JwtBearer.Tests.csproj index 41787aaa5..3fc5f2b03 100644 --- a/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/AspNetCore.Authentication.JwtBearer.Tests.csproj +++ b/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/AspNetCore.Authentication.JwtBearer.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/DPoPIntegrationTests.cs b/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/DPoPIntegrationTests.cs index 3062bbec3..f4e83d6af 100644 --- a/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/DPoPIntegrationTests.cs +++ b/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/DPoPIntegrationTests.cs @@ -5,6 +5,7 @@ using System.Net; using System.Net.Http.Json; using System.Security.Cryptography; using System.Text.Json; +using Duende.AccessTokenManagement; using Duende.AccessTokenManagement.OpenIdConnect; using Duende.AspNetCore.Authentication.JwtBearer.DPoP; using Duende.AspNetCore.TestFramework; diff --git a/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/TestDPoPNonceStore.cs b/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/TestDPoPNonceStore.cs index 80f6ce575..2734d7b48 100644 --- a/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/TestDPoPNonceStore.cs +++ b/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/TestDPoPNonceStore.cs @@ -1,6 +1,8 @@ // Copyright (c) Duende Software. All rights reserved. // See LICENSE in the project root for license information. +using Duende.AccessTokenManagement; + namespace Duende.AspNetCore.Authentication.JwtBearer; public class TestDPoPNonceStore : IDPoPNonceStore