From 2f0596a08c6fe21f86ea80bd56644a15cd611893 Mon Sep 17 00:00:00 2001 From: Joe DeCock Date: Sat, 4 Jan 2025 23:13:49 -0600 Subject: [PATCH 1/5] fix(is): service resolution from HttpContext Fix service resolution in PostConfigureApplicationCookieTicketStore so that it can be constructed without an http context available. --- ...stConfigureApplicationCookieTicketStore.cs | 5 +- .../Common/MockHttpContextAccessor.cs | 9 +++- ...figureApplicationCookieTicketStoreTests.cs | 53 +++++++++++++++++++ 3 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 test/IdentityServer.UnitTests/Configuration/DependencyInjection/PostConfigureApplicationCookieTicketStoreTests.cs diff --git a/src/IdentityServer/Configuration/DependencyInjection/PostConfigureApplicationCookieTicketStore.cs b/src/IdentityServer/Configuration/DependencyInjection/PostConfigureApplicationCookieTicketStore.cs index bfa04987e..b8c4c3aff 100644 --- a/src/IdentityServer/Configuration/DependencyInjection/PostConfigureApplicationCookieTicketStore.cs +++ b/src/IdentityServer/Configuration/DependencyInjection/PostConfigureApplicationCookieTicketStore.cs @@ -21,7 +21,6 @@ public class PostConfigureApplicationCookieTicketStore : IPostConfigureOptions _logger; /// @@ -38,7 +37,6 @@ public PostConfigureApplicationCookieTicketStore( ILogger logger) { _httpContextAccessor = httpContextAccessor; - _licenseUsage = httpContextAccessor.HttpContext?.RequestServices.GetRequiredService(); _logger = logger; _scheme = identityServerOptions.Authentication.CookieAuthenticationScheme ?? @@ -69,7 +67,8 @@ public void PostConfigure(string name, CookieAuthenticationOptions options) } IdentityServerLicenseValidator.Instance.ValidateServerSideSessions(); - _licenseUsage.FeatureUsed(LicenseFeature.ServerSideSessions); + var licenseUsage = _httpContextAccessor.HttpContext?.RequestServices.GetRequiredService(); + licenseUsage.FeatureUsed(LicenseFeature.ServerSideSessions); var sessionStore = _httpContextAccessor.HttpContext!.RequestServices.GetService(); if (sessionStore is InMemoryServerSideSessionStore) diff --git a/test/IdentityServer.UnitTests/Common/MockHttpContextAccessor.cs b/test/IdentityServer.UnitTests/Common/MockHttpContextAccessor.cs index 6ce802a4f..b9d7f2525 100644 --- a/test/IdentityServer.UnitTests/Common/MockHttpContextAccessor.cs +++ b/test/IdentityServer.UnitTests/Common/MockHttpContextAccessor.cs @@ -2,6 +2,7 @@ // See LICENSE in the project root for license information. +using System; using Duende.IdentityServer; using Duende.IdentityServer.Configuration; using Duende.IdentityServer.Models; @@ -24,7 +25,8 @@ public MockHttpContextAccessor( IdentityServerOptions options = null, IUserSession userSession = null, IMessageStore endSessionStore = null, - IServerUrls urls = null) + IServerUrls urls = null, + Action configureServices = null) { options = options ?? TestIdentityServerOptions.Create(); @@ -63,6 +65,11 @@ public MockHttpContextAccessor( services.AddSingleton(urls); } + if (configureServices != null) + { + configureServices(services); + } + _context.RequestServices = services.BuildServiceProvider(); } diff --git a/test/IdentityServer.UnitTests/Configuration/DependencyInjection/PostConfigureApplicationCookieTicketStoreTests.cs b/test/IdentityServer.UnitTests/Configuration/DependencyInjection/PostConfigureApplicationCookieTicketStoreTests.cs new file mode 100644 index 000000000..59dd07471 --- /dev/null +++ b/test/IdentityServer.UnitTests/Configuration/DependencyInjection/PostConfigureApplicationCookieTicketStoreTests.cs @@ -0,0 +1,53 @@ +using Duende.IdentityServer.Configuration; +using Duende.IdentityServer.Licensing.V2; +using FluentAssertions; +using Microsoft.AspNetCore.Authentication.Cookies; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using UnitTests.Common; +using Xunit; + +namespace UnitTests.Configuration.DependencyInjection; + +public class PostConfigureApplicationCookieTicketStoreTests +{ + + [Fact] + public void can_be_constructed_without_httpcontext_and_used_later_with_httpcontext() + { + // Register the dependencies of the usage tracker so that we can resolve it in PostConfigure + var httpContextAccessor = new MockHttpContextAccessor(configureServices: sp => + { + sp.AddSingleton(TestLogger.Create()); + sp.AddSingleton(); + sp.AddSingleton(); + }); + + // The mock http context accessor has a convenient HttpContext, but + // initially we simulate not having it by stashing it away and setting + // the accessor's context to null. + var savedContext = httpContextAccessor.HttpContext; + httpContextAccessor.HttpContext = null; + + var sut = new PostConfigureApplicationCookieTicketStore( + httpContextAccessor, + new IdentityServerOptions + { + Authentication = new AuthenticationOptions + { + // This is needed so that we operate on the correct scheme + CookieAuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme + } + }, + Options.Create(new()), + TestLogger.Create() + ); + + // Now that we've constructed, we can bring back the http context and run PostConfigure + httpContextAccessor.HttpContext = savedContext; + var cookieOpts = new CookieAuthenticationOptions(); + sut.PostConfigure(CookieAuthenticationDefaults.AuthenticationScheme, cookieOpts); + + cookieOpts.SessionStore.Should().BeOfType(); + } +} \ No newline at end of file From 0c6eb67f3b5795215a18bf07de818dbc9217e071 Mon Sep 17 00:00:00 2001 From: Joe DeCock Date: Tue, 7 Jan 2025 11:38:31 -0600 Subject: [PATCH 2/5] fix(is): LicenseUsageSummary resolution Fixed usage in the main host of the LicenseUsageSummary so that it is resolved at shutdown properly. --- hosts/main/Program.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/hosts/main/Program.cs b/hosts/main/Program.cs index cee27845f..27ca14d6b 100644 --- a/hosts/main/Program.cs +++ b/hosts/main/Program.cs @@ -38,12 +38,14 @@ .ConfigureServices() .ConfigurePipeline(); - var usage = app.Services.GetRequiredService(); + app.Lifetime.ApplicationStopping.Register(() => + { + var usage = app.Services.GetRequiredService(); + Console.Write(Summary(usage)); + Console.ReadKey(); + }); app.Run(); - - Console.Write(Summary(usage)); - Console.ReadKey(); } catch (Exception ex) { @@ -55,7 +57,7 @@ Log.CloseAndFlush(); } -string Summary(LicenseUsageSummary usage) +static string Summary(LicenseUsageSummary usage) { var sb = new StringBuilder(); sb.AppendLine("IdentityServer Usage Summary:"); @@ -67,4 +69,3 @@ string Summary(LicenseUsageSummary usage) return sb.ToString(); } - \ No newline at end of file From 0d95d547bda3f3015fd8a55d644ea9e3a0780409 Mon Sep 17 00:00:00 2001 From: Joe DeCock Date: Tue, 7 Jan 2025 14:23:59 -0600 Subject: [PATCH 3/5] fix(is): Only summarize usage in dev --- hosts/main/Program.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/hosts/main/Program.cs b/hosts/main/Program.cs index 27ca14d6b..dc8d2b51b 100644 --- a/hosts/main/Program.cs +++ b/hosts/main/Program.cs @@ -38,12 +38,17 @@ .ConfigureServices() .ConfigurePipeline(); - app.Lifetime.ApplicationStopping.Register(() => + if (app.Environment.IsDevelopment()) { - var usage = app.Services.GetRequiredService(); - Console.Write(Summary(usage)); - Console.ReadKey(); - }); + app.Lifetime.ApplicationStopping.Register(() => + { + var usage = app.Services.GetRequiredService(); + Console.Write(Summary(usage)); + { + Console.ReadKey(); + } + }); + } app.Run(); } From 54bcfd8a4da7dea8fd5854a370b62ee04a14d5de Mon Sep 17 00:00:00 2001 From: khalidabuhakmeh Date: Wed, 8 Jan 2025 10:34:31 -0500 Subject: [PATCH 4/5] Clarify documentation for LicenseUsageSummary parameters. Updated XML documentation to provide detailed descriptions for parameter usage in the LicenseUsageSummary record. This improves clarity, especially for auditing purposes, and ensures better understanding of the fields. --- src/IdentityServer/Licensing/LicenseUsageSummary.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/IdentityServer/Licensing/LicenseUsageSummary.cs b/src/IdentityServer/Licensing/LicenseUsageSummary.cs index 38451b33a..51dbcf66c 100644 --- a/src/IdentityServer/Licensing/LicenseUsageSummary.cs +++ b/src/IdentityServer/Licensing/LicenseUsageSummary.cs @@ -8,12 +8,12 @@ namespace Duende.IdentityServer.Licensing; /// -/// Usage summary for the current license. +/// Usage summary for the current IdentityServer instance intended for auditing purposes. /// -/// -/// -/// -/// +/// License edition retrieved from license key. +/// Clients used in the current IdentityServer instance. +/// Issuers used in the current IdentityServer instance. +/// Features used in the current IdentityServer instance. public record LicenseUsageSummary( string LicenseEdition, IReadOnlyCollection ClientsUsed, From be8c0bc05772c0514106bb9408c7d3884b07aae8 Mon Sep 17 00:00:00 2001 From: Joe DeCock Date: Thu, 9 Jan 2025 12:41:38 -0600 Subject: [PATCH 5/5] Minor formatting change in main host --- hosts/main/Program.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/hosts/main/Program.cs b/hosts/main/Program.cs index dc8d2b51b..4645ee5ae 100644 --- a/hosts/main/Program.cs +++ b/hosts/main/Program.cs @@ -44,9 +44,7 @@ { var usage = app.Services.GetRequiredService(); Console.Write(Summary(usage)); - { - Console.ReadKey(); - } + Console.ReadKey(); }); }