Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge 7.1 release branch forward to main #1717

Merged
merged 10 commits into from
Jan 9, 2025
18 changes: 12 additions & 6 deletions identity-server/hosts/main/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,19 @@
.ConfigureServices()
.ConfigurePipeline();

var usage = app.Services.GetRequiredService<LicenseUsageSummary>();
if (app.Environment.IsDevelopment())
{
app.Lifetime.ApplicationStopping.Register(() =>
{
var usage = app.Services.GetRequiredService<LicenseUsageSummary>();
Console.Write(Summary(usage));
{
josephdecock marked this conversation as resolved.
Show resolved Hide resolved
Console.ReadKey();
}
});
}

app.Run();

Console.Write(Summary(usage));
Console.ReadKey();
}
catch (Exception ex)
{
Expand All @@ -55,7 +62,7 @@
Log.CloseAndFlush();
}

string Summary(LicenseUsageSummary usage)
static string Summary(LicenseUsageSummary usage)
{
var sb = new StringBuilder();
sb.AppendLine("IdentityServer Usage Summary:");
Expand All @@ -67,4 +74,3 @@ string Summary(LicenseUsageSummary usage)

return sb.ToString();
}

Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ public class PostConfigureApplicationCookieTicketStore : IPostConfigureOptions<C
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly string _scheme;
private readonly LicenseUsageTracker _licenseUsage;
private readonly ILogger<PostConfigureApplicationCookieTicketStore> _logger;

/// <summary>
Expand All @@ -38,7 +37,6 @@ public PostConfigureApplicationCookieTicketStore(
ILogger<PostConfigureApplicationCookieTicketStore> logger)
{
_httpContextAccessor = httpContextAccessor;
_licenseUsage = httpContextAccessor.HttpContext?.RequestServices.GetRequiredService<LicenseUsageTracker>();
_logger = logger;

_scheme = identityServerOptions.Authentication.CookieAuthenticationScheme ??
Expand Down Expand Up @@ -69,7 +67,8 @@ public void PostConfigure(string name, CookieAuthenticationOptions options)
}

IdentityServerLicenseValidator.Instance.ValidateServerSideSessions();
_licenseUsage.FeatureUsed(LicenseFeature.ServerSideSessions);
var licenseUsage = _httpContextAccessor.HttpContext?.RequestServices.GetRequiredService<LicenseUsageTracker>();
licenseUsage.FeatureUsed(LicenseFeature.ServerSideSessions);

var sessionStore = _httpContextAccessor.HttpContext!.RequestServices.GetService<IServerSideSessionStore>();
if (sessionStore is InMemoryServerSideSessionStore)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
namespace Duende.IdentityServer.Licensing;

/// <summary>
/// Usage summary for the current license.
/// Usage summary for the current IdentityServer instance intended for auditing purposes.
/// </summary>
/// <param name="LicenseEdition"></param>
/// <param name="ClientsUsed"></param>
/// <param name="IssuersUsed"></param>
/// <param name="FeaturesUsed"></param>
/// <param name="LicenseEdition">License edition retrieved from license key.</param>
/// <param name="ClientsUsed">Clients used in the current IdentityServer instance.</param>
/// <param name="IssuersUsed">Issuers used in the current IdentityServer instance.</param>
/// <param name="FeaturesUsed">Features used in the current IdentityServer instance.</param>
public record LicenseUsageSummary(
string LicenseEdition,
IReadOnlyCollection<string> ClientsUsed,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -24,7 +25,8 @@ public MockHttpContextAccessor(
IdentityServerOptions options = null,
IUserSession userSession = null,
IMessageStore<LogoutNotificationContext> endSessionStore = null,
IServerUrls urls = null)
IServerUrls urls = null,
Action<ServiceCollection> configureServices = null)
{
options = options ?? TestIdentityServerOptions.Create();

Expand Down Expand Up @@ -63,6 +65,11 @@ public MockHttpContextAccessor(
services.AddSingleton<IServerUrls>(urls);
}

if (configureServices != null)
{
configureServices(services);
}

_context.RequestServices = services.BuildServiceProvider();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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<LicenseAccessor>());
sp.AddSingleton<LicenseAccessor>();
sp.AddSingleton<LicenseUsageTracker>();
});

// 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<Microsoft.AspNetCore.Authentication.AuthenticationOptions>(new()),
TestLogger.Create<PostConfigureApplicationCookieTicketStore>()
);

// 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<TicketStoreShim>();
}
}
Loading