From b72b73b540cf188df04f1204b8c04bed1daf4636 Mon Sep 17 00:00:00 2001
From: Brett Hazen <2651260+bhazen@users.noreply.github.com>
Date: Thu, 4 Sep 2025 14:06:50 -0500
Subject: [PATCH 1/4] Updated IdentityServer projects to latest preview version
of IdentityModel
---
Directory.Packages.props | 2 +-
.../DPoP/DPoPExtensions.cs | 3 ++-
.../DPoP/DPoPProofValidator.cs | 9 +++++----
.../DPoP/DPoPProofValidatorTestBase.cs | 5 +++--
.../Pages/Diagnostics/ViewModel.cs | 4 ++--
.../DPoP/DPoPExtensions.cs | 3 ++-
.../DPoP/DPoPProofValidator.cs | 5 +++--
.../src/ConsoleResourceIndicators/Program.cs | 10 +++++-----
.../src/Constants/TokenResponseExtensions.cs | 6 +++---
.../UI/Main/Pages/Diagnostics/ViewModel.cs | 4 ++--
.../Configuration/CryptoHelper.cs | 3 ++-
.../AuthenticationPropertiesExtensions.cs | 6 +++---
.../Extensions/JsonWebKeyExtensions.cs | 3 ++-
.../ValidatedAuthorizeRequestExtensions.cs | 3 ++-
.../Extensions/X509CertificateExtensions.cs | 4 ++--
.../Models/Messages/ConsentRequest.cs | 3 ++-
.../Default/DiscoveryResponseGenerator.cs | 19 ++++++++++---------
.../Default/ProtectedDataMessageStore.cs | 6 +++---
.../Default/DefaultDPoPProofValidator.cs | 3 ++-
.../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 ++-
37 files changed, 100 insertions(+), 79 deletions(-)
diff --git a/Directory.Packages.props b/Directory.Packages.props
index ab4e81320..0f7bfa57a 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -49,7 +49,7 @@
-
+
diff --git a/aspnetcore-authentication-jwtbearer/src/AspNetCore.Authentication.JwtBearer/DPoP/DPoPExtensions.cs b/aspnetcore-authentication-jwtbearer/src/AspNetCore.Authentication.JwtBearer/DPoP/DPoPExtensions.cs
index d28c3862b..097fe4a78 100644
--- a/aspnetcore-authentication-jwtbearer/src/AspNetCore.Authentication.JwtBearer/DPoP/DPoPExtensions.cs
+++ b/aspnetcore-authentication-jwtbearer/src/AspNetCore.Authentication.JwtBearer/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;
@@ -44,5 +45,5 @@ internal static class DPoPExtensions
///
/// Create the value of a thumbprint
///
- public static string CreateThumbprint(this JsonWebKey jwk) => Base64Url.Encode(jwk.ComputeJwkThumbprint());
+ public static string CreateThumbprint(this JsonWebKey jwk) => Base64Url.EncodeToString(jwk.ComputeJwkThumbprint());
}
diff --git a/aspnetcore-authentication-jwtbearer/src/AspNetCore.Authentication.JwtBearer/DPoP/DPoPProofValidator.cs b/aspnetcore-authentication-jwtbearer/src/AspNetCore.Authentication.JwtBearer/DPoP/DPoPProofValidator.cs
index f048dee75..d80d7a1e4 100644
--- a/aspnetcore-authentication-jwtbearer/src/AspNetCore.Authentication.JwtBearer/DPoP/DPoPProofValidator.cs
+++ b/aspnetcore-authentication-jwtbearer/src/AspNetCore.Authentication.JwtBearer/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;
@@ -21,7 +22,7 @@ internal class DPoPProofValidator : IDPoPProofValidator
private const string DataProtectorPurpose = "DPoPJwtBearerEvents-DPoPProofValidation-nonce";
///
- /// Provides the options for DPoP proof validation.
+ /// Provides the options for DPoP proof validation.
///
internal readonly IOptionsMonitor OptionsMonitor;
@@ -263,7 +264,7 @@ internal class DPoPProofValidator : 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.SetError("Invalid 'ath' value.");
@@ -278,7 +279,7 @@ internal class DPoPProofValidator : IDPoPProofValidator
return;
}
var jtiBytes = Encoding.UTF8.GetBytes(jtiString);
- result.TokenIdHash = Base64Url.Encode(SHA256.HashData(jtiBytes));
+ result.TokenIdHash = Base64Url.EncodeToString(SHA256.HashData(jtiBytes));
}
if (string.IsNullOrEmpty(result.TokenIdHash))
@@ -382,7 +383,7 @@ internal class DPoPProofValidator : IDPoPProofValidator
skew = dPoPOptions.ServerClockSkew;
}
- // we do x2 here because the clock might be before or after, so we're making cache duration
+ // we do x2 here because the clock might be before or after, so we're making cache duration
// longer than the likelihood of proof token expiration, which is done before replay
skew *= 2;
var cacheDuration = dPoPOptions.ProofTokenValidityDuration + skew;
diff --git a/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/DPoP/DPoPProofValidatorTestBase.cs b/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/DPoP/DPoPProofValidatorTestBase.cs
index 1626ba042..1947ac9c9 100644
--- a/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/DPoP/DPoPProofValidatorTestBase.cs
+++ b/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/DPoP/DPoPProofValidatorTestBase.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;
@@ -19,7 +20,7 @@ public abstract class DPoPProofValidatorTestBase
{
ProofValidator = CreateProofValidator();
var jtiBytes = Encoding.UTF8.GetBytes(TokenId);
- TokenIdHash = Base64Url.Encode(SHA256.HashData(jtiBytes));
+ TokenIdHash = Base64Url.EncodeToString(SHA256.HashData(jtiBytes));
Context = new()
{
Options = Options,
@@ -52,7 +53,7 @@ public abstract class DPoPProofValidatorTestBase
protected DPoPProofValidationResult Result = new();
- // This is just an arbitrary date that we're going to do all our date arithmetic relative to.
+ // This is just an arbitrary date that we're going to do all our date arithmetic relative to.
// It was chosen because it is convenient to use - it is well within the range of DateTime
protected const long IssuedAt = 1704088800; // Mon Jan 01 2024 06:00:00 GMT+0000
protected const long ValidFor = 100;
diff --git a/bff/hosts/Hosts.IdentityServer/Pages/Diagnostics/ViewModel.cs b/bff/hosts/Hosts.IdentityServer/Pages/Diagnostics/ViewModel.cs
index 58bde0f7c..f312d4caa 100644
--- a/bff/hosts/Hosts.IdentityServer/Pages/Diagnostics/ViewModel.cs
+++ b/bff/hosts/Hosts.IdentityServer/Pages/Diagnostics/ViewModel.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 Microsoft.AspNetCore.Authentication;
namespace IdentityServerHost.Pages.Diagnostics;
@@ -18,7 +18,7 @@ public class ViewModel
if (result.Properties.Items.ContainsKey("client_list"))
{
var encoded = result.Properties.Items["client_list"];
- var bytes = Base64Url.Decode(encoded);
+ var bytes = Base64Url.DecodeFromChars(encoded);
var value = Encoding.UTF8.GetString(bytes);
Clients = JsonSerializer.Deserialize(value);
diff --git a/bff/hosts/RemoteApis/Hosts.RemoteApi.DPoP/DPoP/DPoPExtensions.cs b/bff/hosts/RemoteApis/Hosts.RemoteApi.DPoP/DPoP/DPoPExtensions.cs
index 54656c069..beb2bf0ed 100644
--- a/bff/hosts/RemoteApis/Hosts.RemoteApi.DPoP/DPoP/DPoPExtensions.cs
+++ b/bff/hosts/RemoteApis/Hosts.RemoteApi.DPoP/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 @@ 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/bff/hosts/RemoteApis/Hosts.RemoteApi.DPoP/DPoP/DPoPProofValidator.cs b/bff/hosts/RemoteApis/Hosts.RemoteApi.DPoP/DPoP/DPoPProofValidator.cs
index 734358666..984f7879c 100644
--- a/bff/hosts/RemoteApis/Hosts.RemoteApi.DPoP/DPoP/DPoPProofValidator.cs
+++ b/bff/hosts/RemoteApis/Hosts.RemoteApi.DPoP/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/UI/Main/Pages/Diagnostics/ViewModel.cs b/identity-server/hosts/UI/Main/Pages/Diagnostics/ViewModel.cs
index 2a160b3d6..6bab58ec3 100644
--- a/identity-server/hosts/UI/Main/Pages/Diagnostics/ViewModel.cs
+++ b/identity-server/hosts/UI/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 Duende.IdentityServer.UI.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 1447992d6..e2161f753 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.Globalization;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
@@ -75,7 +76,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 c76d6d57a..852e3e496 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)
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 554bb545e..6275b8a56 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;
@@ -435,13 +436,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
{
@@ -459,8 +460,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
{
@@ -484,8 +485,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
{
@@ -502,8 +503,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 451e98ef3..d51fb7fe1 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.Globalization;
using System.Security.Cryptography;
using System.Text;
@@ -302,7 +303,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;
diff --git a/identity-server/src/IdentityServer/Validation/Default/TokenRequestValidator.cs b/identity-server/src/IdentityServer/Validation/Default/TokenRequestValidator.cs
index abd7c111f..a4b78bfa3 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 56de3fba3..c5cfdd5e0 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;
@@ -223,7 +224,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 a913cbecb..35854ef2c 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;
@@ -433,7 +434,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 83801d7a6..e157ef7e0 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 Duende.IdentityServer.IntegrationTests.Clients.Setup;
using Duende.IdentityServer.IntegrationTests.Common;
@@ -275,7 +275,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 0c6b2ff1b..24156783e 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;
@@ -588,7 +589,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 ef492f51d..fd5b8f050 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 Duende.IdentityServer.IntegrationTests.Clients.Setup;
using Microsoft.AspNetCore.Hosting;
@@ -268,7 +268,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 76875c33e..2a8eb18a7 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 Duende.IdentityServer.IntegrationTests.Clients.Setup;
using Duende.IdentityServer.IntegrationTests.Common;
@@ -204,7 +204,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 5cd7fddbe..f22f5a3ee 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;
@@ -528,7 +529,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 25ea0df75..42b2f9133 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.Globalization;
using System.Net;
using System.Security.Claims;
@@ -581,7 +582,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);
@@ -629,7 +630,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);
@@ -669,7 +670,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 940f18fe8..c96235752 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.IntegrationTests.Common;
using Duende.IdentityServer.Models;
@@ -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 290e7ba65..84130fc52 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.IntegrationTests.Common;
using Duende.IdentityServer.Models;
@@ -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 b5c3869c8..1b662ad82 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.IntegrationTests.Common;
using Duende.IdentityServer.Models;
using Duende.IdentityServer.Services;
@@ -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 c4cd24e17..a8ff3cf5b 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.Configuration;
using Duende.IdentityServer.IntegrationTests.Common;
@@ -63,7 +63,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 5ee8c133f..34550eff9 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 7d87e09c1f79ddfff2c6f0572b5d368ebd3aba45 Mon Sep 17 00:00:00 2001
From: Joe DeCock
Date: Thu, 16 Oct 2025 15:15:27 -0500
Subject: [PATCH 2/4] Disable nuget packaging for internal projects
---
identity-server/hosts/Shared/Host.Shared.csproj | 1 +
identity-server/hosts/UI/AspNetIdentity/UI.AspNetIdentity.csproj | 1 +
.../hosts/UI/EntityFramework/UI.EntityFramework.csproj | 1 +
identity-server/hosts/UI/Main/UI.Main.csproj | 1 +
shared/Xunit.Playwright/Duende.Xunit.Playwright.csproj | 1 +
5 files changed, 5 insertions(+)
diff --git a/identity-server/hosts/Shared/Host.Shared.csproj b/identity-server/hosts/Shared/Host.Shared.csproj
index dee7a1949..724447fa3 100644
--- a/identity-server/hosts/Shared/Host.Shared.csproj
+++ b/identity-server/hosts/Shared/Host.Shared.csproj
@@ -5,6 +5,7 @@
enable
enable
Duende.IdentityServer.Hosts.Shared
+ false
diff --git a/identity-server/hosts/UI/AspNetIdentity/UI.AspNetIdentity.csproj b/identity-server/hosts/UI/AspNetIdentity/UI.AspNetIdentity.csproj
index c4badcf24..8286ca8bb 100644
--- a/identity-server/hosts/UI/AspNetIdentity/UI.AspNetIdentity.csproj
+++ b/identity-server/hosts/UI/AspNetIdentity/UI.AspNetIdentity.csproj
@@ -7,6 +7,7 @@
true
Duende.IdentityServer.UI.AspNetIdentity
true
+ false
diff --git a/identity-server/hosts/UI/EntityFramework/UI.EntityFramework.csproj b/identity-server/hosts/UI/EntityFramework/UI.EntityFramework.csproj
index 64c46b889..90af3cddc 100644
--- a/identity-server/hosts/UI/EntityFramework/UI.EntityFramework.csproj
+++ b/identity-server/hosts/UI/EntityFramework/UI.EntityFramework.csproj
@@ -7,6 +7,7 @@
true
Duende.IdentityServer.UI.EntityFramework
true
+ false
diff --git a/identity-server/hosts/UI/Main/UI.Main.csproj b/identity-server/hosts/UI/Main/UI.Main.csproj
index b396d5c26..14622405b 100644
--- a/identity-server/hosts/UI/Main/UI.Main.csproj
+++ b/identity-server/hosts/UI/Main/UI.Main.csproj
@@ -8,6 +8,7 @@
Duende.IdentityServer.UI
true
true
+ false
diff --git a/shared/Xunit.Playwright/Duende.Xunit.Playwright.csproj b/shared/Xunit.Playwright/Duende.Xunit.Playwright.csproj
index fe2a6dc09..5942a9e3a 100644
--- a/shared/Xunit.Playwright/Duende.Xunit.Playwright.csproj
+++ b/shared/Xunit.Playwright/Duende.Xunit.Playwright.csproj
@@ -7,6 +7,7 @@
Duende.Xunit.Playwright
true
false
+ false
From 2721b7c72380695de96fcae6ef4100fac6fdb4eb Mon Sep 17 00:00:00 2001
From: Joe DeCock
Date: Thu, 16 Oct 2025 15:56:09 -0500
Subject: [PATCH 3/4] Update to latest previews of AccessTokenManagement
Also temporarily overriding some versions in JwtBearer to work around circular dependencies (we will return to this after releasing IdentityServer)
---
Directory.Packages.props | 10 +++++-----
.../AspNetCore.Authentication.JwtBearer.csproj | 2 +-
.../DPoP/DPoPExtensions.cs | 3 +--
.../DPoP/DPoPProofValidator.cs | 5 ++---
.../AspNetCore.Authentication.JwtBearer.Tests.csproj | 5 ++---
.../DPoP/DPoPProofValidatorTestBase.cs | 3 +--
6 files changed, 12 insertions(+), 16 deletions(-)
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 0f7bfa57a..dcd2e318d 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -42,15 +42,15 @@
-
-
-
-
+
+
+
+
-
+
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 d0d87a42a..5cf525060 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/src/AspNetCore.Authentication.JwtBearer/DPoP/DPoPExtensions.cs b/aspnetcore-authentication-jwtbearer/src/AspNetCore.Authentication.JwtBearer/DPoP/DPoPExtensions.cs
index 097fe4a78..d28c3862b 100644
--- a/aspnetcore-authentication-jwtbearer/src/AspNetCore.Authentication.JwtBearer/DPoP/DPoPExtensions.cs
+++ b/aspnetcore-authentication-jwtbearer/src/AspNetCore.Authentication.JwtBearer/DPoP/DPoPExtensions.cs
@@ -1,7 +1,6 @@
// 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;
@@ -45,5 +44,5 @@ internal static class DPoPExtensions
///
/// Create the value of a thumbprint
///
- public static string CreateThumbprint(this JsonWebKey jwk) => Base64Url.EncodeToString(jwk.ComputeJwkThumbprint());
+ public static string CreateThumbprint(this JsonWebKey jwk) => Base64Url.Encode(jwk.ComputeJwkThumbprint());
}
diff --git a/aspnetcore-authentication-jwtbearer/src/AspNetCore.Authentication.JwtBearer/DPoP/DPoPProofValidator.cs b/aspnetcore-authentication-jwtbearer/src/AspNetCore.Authentication.JwtBearer/DPoP/DPoPProofValidator.cs
index d80d7a1e4..bad212e01 100644
--- a/aspnetcore-authentication-jwtbearer/src/AspNetCore.Authentication.JwtBearer/DPoP/DPoPProofValidator.cs
+++ b/aspnetcore-authentication-jwtbearer/src/AspNetCore.Authentication.JwtBearer/DPoP/DPoPProofValidator.cs
@@ -1,7 +1,6 @@
// 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;
@@ -264,7 +263,7 @@ internal class DPoPProofValidator : IDPoPProofValidator
var bytes = Encoding.UTF8.GetBytes(context.AccessToken);
var hash = SHA256.HashData(bytes);
- var accessTokenHash = Base64Url.EncodeToString(hash);
+ var accessTokenHash = Base64Url.Encode(hash);
if (accessTokenHash != result.AccessTokenHash)
{
result.SetError("Invalid 'ath' value.");
@@ -279,7 +278,7 @@ internal class DPoPProofValidator : IDPoPProofValidator
return;
}
var jtiBytes = Encoding.UTF8.GetBytes(jtiString);
- result.TokenIdHash = Base64Url.EncodeToString(SHA256.HashData(jtiBytes));
+ result.TokenIdHash = Base64Url.Encode(SHA256.HashData(jtiBytes));
}
if (string.IsNullOrEmpty(result.TokenIdHash))
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 e9693adfa..0b1f5d96b 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,12 +10,11 @@
-
-
+
+
-
diff --git a/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/DPoP/DPoPProofValidatorTestBase.cs b/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/DPoP/DPoPProofValidatorTestBase.cs
index 1947ac9c9..baceb26e4 100644
--- a/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/DPoP/DPoPProofValidatorTestBase.cs
+++ b/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/DPoP/DPoPProofValidatorTestBase.cs
@@ -1,7 +1,6 @@
// 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;
@@ -20,7 +19,7 @@ public abstract class DPoPProofValidatorTestBase
{
ProofValidator = CreateProofValidator();
var jtiBytes = Encoding.UTF8.GetBytes(TokenId);
- TokenIdHash = Base64Url.EncodeToString(SHA256.HashData(jtiBytes));
+ TokenIdHash = Base64Url.Encode(SHA256.HashData(jtiBytes));
Context = new()
{
Options = Options,
From 672f12830502ad96e8ff1a78b5058bac83f97fc7 Mon Sep 17 00:00:00 2001
From: Joe DeCock
Date: Thu, 16 Oct 2025 16:25:56 -0500
Subject: [PATCH 4/4] Revert BFF so that we can update just IdentityServer
first
---
Directory.Packages.props | 11 +++++++----
.../Pages/Diagnostics/ViewModel.cs | 5 ++---
.../Hosts.RemoteApi.DPoP/DPoP/DPoPExtensions.cs | 3 +--
.../Hosts.RemoteApi.DPoP/DPoP/DPoPProofValidator.cs | 3 +--
bff/migrations/UserSessionDb/UserSessionDb.csproj | 1 +
5 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/Directory.Packages.props b/Directory.Packages.props
index dcd2e318d..5199f3b11 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -42,15 +42,17 @@
-
+
-
+
-
-
+
+
+
+
@@ -69,6 +71,7 @@
+
diff --git a/bff/hosts/Hosts.IdentityServer/Pages/Diagnostics/ViewModel.cs b/bff/hosts/Hosts.IdentityServer/Pages/Diagnostics/ViewModel.cs
index f312d4caa..4d93aaf24 100644
--- a/bff/hosts/Hosts.IdentityServer/Pages/Diagnostics/ViewModel.cs
+++ b/bff/hosts/Hosts.IdentityServer/Pages/Diagnostics/ViewModel.cs
@@ -1,10 +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 +17,7 @@ public class ViewModel
if (result.Properties.Items.ContainsKey("client_list"))
{
var encoded = result.Properties.Items["client_list"];
- var bytes = Base64Url.DecodeFromChars(encoded);
+ var bytes = Base64Url.Decode(encoded);
var value = Encoding.UTF8.GetString(bytes);
Clients = JsonSerializer.Deserialize(value);
diff --git a/bff/hosts/RemoteApis/Hosts.RemoteApi.DPoP/DPoP/DPoPExtensions.cs b/bff/hosts/RemoteApis/Hosts.RemoteApi.DPoP/DPoP/DPoPExtensions.cs
index beb2bf0ed..54656c069 100644
--- a/bff/hosts/RemoteApis/Hosts.RemoteApi.DPoP/DPoP/DPoPExtensions.cs
+++ b/bff/hosts/RemoteApis/Hosts.RemoteApi.DPoP/DPoP/DPoPExtensions.cs
@@ -1,7 +1,6 @@
// 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;
@@ -67,7 +66,7 @@ static class DPoPExtensions
///
public static string CreateThumbprint(this JsonWebKey jwk)
{
- var jkt = Base64Url.EncodeToString(jwk.ComputeJwkThumbprint());
+ var jkt = Base64Url.Encode(jwk.ComputeJwkThumbprint());
return jkt;
}
}
diff --git a/bff/hosts/RemoteApis/Hosts.RemoteApi.DPoP/DPoP/DPoPProofValidator.cs b/bff/hosts/RemoteApis/Hosts.RemoteApi.DPoP/DPoP/DPoPProofValidator.cs
index 984f7879c..cbff2e5e1 100644
--- a/bff/hosts/RemoteApis/Hosts.RemoteApi.DPoP/DPoP/DPoPProofValidator.cs
+++ b/bff/hosts/RemoteApis/Hosts.RemoteApi.DPoP/DPoP/DPoPProofValidator.cs
@@ -1,7 +1,6 @@
// 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;
@@ -227,7 +226,7 @@ public class DPoPProofValidator
var bytes = Encoding.UTF8.GetBytes(context.AccessToken);
var hash = sha.ComputeHash(bytes);
- var accessTokenHash = Base64Url.EncodeToString(hash);
+ var accessTokenHash = Base64Url.Encode(hash);
if (accessTokenHash != result.AccessTokenHash)
{
result.IsError = true;
diff --git a/bff/migrations/UserSessionDb/UserSessionDb.csproj b/bff/migrations/UserSessionDb/UserSessionDb.csproj
index 7b282f273..7bb7a2c0d 100644
--- a/bff/migrations/UserSessionDb/UserSessionDb.csproj
+++ b/bff/migrations/UserSessionDb/UserSessionDb.csproj
@@ -7,6 +7,7 @@
+