From da745b8988430402b1485bcc29f4b92f7c260b19 Mon Sep 17 00:00:00 2001 From: pgermishuys Date: Fri, 17 Oct 2025 09:01:28 +0200 Subject: [PATCH 1/3] Sync BFF 4.0 with main (including ATM preview packages) --- Directory.Packages.props | 13 ++++++------- .../DPoP/DPoPExtensions.cs | 3 ++- .../DPoP/DPoPProofValidator.cs | 9 +++++---- ...AspNetCore.Authentication.JwtBearer.Tests.csproj | 1 - .../DPoP/DPoPProofValidatorTestBase.cs | 5 +++-- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 60d80dfe9..f8d22ae01 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -42,14 +42,12 @@ - - - + + - - - + + + @@ -67,6 +65,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/AspNetCore.Authentication.JwtBearer.Tests.csproj b/aspnetcore-authentication-jwtbearer/test/AspNetCore.Authentication.JwtBearer.Tests/AspNetCore.Authentication.JwtBearer.Tests.csproj index e9693adfa..d0f3afe2b 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 @@ -15,7 +15,6 @@ - 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; From d6324086ce1664bdfbc020f36d6ed0fbec69688c Mon Sep 17 00:00:00 2001 From: pgermishuys Date: Fri, 17 Oct 2025 09:23:40 +0200 Subject: [PATCH 2/3] Rectify Base64 related Encoding and Decoding method calls --- Directory.Packages.props | 2 +- .../Hosts.IdentityServer/Pages/Diagnostics/ViewModel.cs | 3 ++- .../RemoteApis/Hosts.RemoteApi.DPoP/DPoP/DPoPExtensions.cs | 3 ++- .../Hosts.RemoteApi.DPoP/DPoP/DPoPProofValidator.cs | 5 +++-- bff/src/Bff.Yarp/Bff.Yarp.csproj | 1 - 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index f8d22ae01..9c0fc866a 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -74,7 +74,7 @@ - + diff --git a/bff/hosts/Hosts.IdentityServer/Pages/Diagnostics/ViewModel.cs b/bff/hosts/Hosts.IdentityServer/Pages/Diagnostics/ViewModel.cs index 58bde0f7c..c990771a4 100644 --- a/bff/hosts/Hosts.IdentityServer/Pages/Diagnostics/ViewModel.cs +++ b/bff/hosts/Hosts.IdentityServer/Pages/Diagnostics/ViewModel.cs @@ -2,6 +2,7 @@ // See LICENSE in the project root for license information. +using System.Buffers.Text; using System.Text; using System.Text.Json; using Duende.IdentityModel; @@ -18,7 +19,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 62febb426..e9e0faad1 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 @@ 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/bff/hosts/RemoteApis/Hosts.RemoteApi.DPoP/DPoP/DPoPProofValidator.cs b/bff/hosts/RemoteApis/Hosts.RemoteApi.DPoP/DPoP/DPoPProofValidator.cs index c43a805b3..021a1ed71 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/bff/src/Bff.Yarp/Bff.Yarp.csproj b/bff/src/Bff.Yarp/Bff.Yarp.csproj index b251f23b3..86d1580d0 100644 --- a/bff/src/Bff.Yarp/Bff.Yarp.csproj +++ b/bff/src/Bff.Yarp/Bff.Yarp.csproj @@ -6,7 +6,6 @@ - From 4e1badde42b7929a8365feb376b4601ea51640bc Mon Sep 17 00:00:00 2001 From: pgermishuys Date: Fri, 17 Oct 2025 09:26:03 +0200 Subject: [PATCH 3/3] Remove unused using --- bff/hosts/Hosts.IdentityServer/Pages/Diagnostics/ViewModel.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/bff/hosts/Hosts.IdentityServer/Pages/Diagnostics/ViewModel.cs b/bff/hosts/Hosts.IdentityServer/Pages/Diagnostics/ViewModel.cs index c990771a4..f312d4caa 100644 --- a/bff/hosts/Hosts.IdentityServer/Pages/Diagnostics/ViewModel.cs +++ b/bff/hosts/Hosts.IdentityServer/Pages/Diagnostics/ViewModel.cs @@ -5,7 +5,6 @@ using System.Buffers.Text; using System.Text; using System.Text.Json; -using Duende.IdentityModel; using Microsoft.AspNetCore.Authentication; namespace IdentityServerHost.Pages.Diagnostics;