Skip to content

Commit 01e9a2e

Browse files
RolandGuijtRoland Guijt
andauthored
Bump IdentityModel, add Aspire host, remove Serilog. (#314)
* Bump IdentityModel, add Aspire host, remove Serilog. * Add IS metrics and tracing config * Move ServiceDefaults project to v7 root and update references * Add missing using statement * Add using statement * Add missing using statement --------- Co-authored-by: Roland Guijt <roland.guijt@duendesoftware.com>
1 parent a09f6e5 commit 01e9a2e

18 files changed

Lines changed: 276 additions & 37 deletions

File tree

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net10.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
<IsAspireSharedProject>true</IsAspireSharedProject>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<FrameworkReference Include="Microsoft.AspNetCore.App"/>
12+
13+
<PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="10.1.0"/>
14+
<PackageReference Include="Microsoft.Extensions.ServiceDiscovery" Version="10.1.0"/>
15+
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.14.0"/>
16+
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.14.0"/>
17+
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.14.0"/>
18+
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.14.0"/>
19+
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.14.0"/>
20+
</ItemGroup>
21+
22+
</Project>
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
using Microsoft.AspNetCore.Builder;
2+
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
3+
using Microsoft.Extensions.DependencyInjection;
4+
using Microsoft.Extensions.Diagnostics.HealthChecks;
5+
using Microsoft.Extensions.Logging;
6+
using Microsoft.Extensions.ServiceDiscovery;
7+
using OpenTelemetry;
8+
using OpenTelemetry.Metrics;
9+
using OpenTelemetry.Trace;
10+
11+
namespace Microsoft.Extensions.Hosting;
12+
13+
// Adds common Aspire services: service discovery, resilience, health checks, and OpenTelemetry.
14+
// This project should be referenced by each service project in your solution.
15+
// To learn more about using this project, see https://aka.ms/dotnet/aspire/service-defaults
16+
public static class Extensions
17+
{
18+
private const string HealthEndpointPath = "/health";
19+
private const string AlivenessEndpointPath = "/alive";
20+
21+
public static TBuilder AddServiceDefaults<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder
22+
{
23+
builder.ConfigureOpenTelemetry();
24+
25+
builder.AddDefaultHealthChecks();
26+
27+
builder.Services.AddServiceDiscovery();
28+
29+
builder.Services.ConfigureHttpClientDefaults(http =>
30+
{
31+
// Turn on resilience by default
32+
http.AddStandardResilienceHandler();
33+
34+
// Turn on service discovery by default
35+
http.AddServiceDiscovery();
36+
});
37+
38+
// Uncomment the following to restrict the allowed schemes for service discovery.
39+
// builder.Services.Configure<ServiceDiscoveryOptions>(options =>
40+
// {
41+
// options.AllowedSchemes = ["https"];
42+
// });
43+
44+
return builder;
45+
}
46+
47+
public static TBuilder ConfigureOpenTelemetry<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder
48+
{
49+
builder.Logging.AddOpenTelemetry(logging =>
50+
{
51+
logging.IncludeFormattedMessage = true;
52+
logging.IncludeScopes = true;
53+
});
54+
55+
builder.Services.AddOpenTelemetry()
56+
.WithMetrics(metrics =>
57+
{
58+
metrics.AddAspNetCoreInstrumentation()
59+
.AddHttpClientInstrumentation()
60+
.AddRuntimeInstrumentation()
61+
.AddMeter("Duende.IdentityServer", "Duende.IdentityServer.Expirimental", "IdentityServer");
62+
})
63+
.WithTracing(tracing =>
64+
{
65+
tracing.AddSource(builder.Environment.ApplicationName)
66+
.AddAspNetCoreInstrumentation(tracing =>
67+
// Exclude health check requests from tracing
68+
tracing.Filter = context =>
69+
!context.Request.Path.StartsWithSegments(HealthEndpointPath)
70+
&& !context.Request.Path.StartsWithSegments(AlivenessEndpointPath)
71+
)
72+
// Uncomment the following line to enable gRPC instrumentation (requires the OpenTelemetry.Instrumentation.GrpcNetClient package)
73+
//.AddGrpcClientInstrumentation()
74+
.AddHttpClientInstrumentation()
75+
.AddSource("Duende.IdentityServer");
76+
});
77+
78+
builder.AddOpenTelemetryExporters();
79+
80+
return builder;
81+
}
82+
83+
private static TBuilder AddOpenTelemetryExporters<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder
84+
{
85+
var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]);
86+
87+
if (useOtlpExporter)
88+
{
89+
builder.Services.AddOpenTelemetry().UseOtlpExporter();
90+
}
91+
92+
// Uncomment the following lines to enable the Azure Monitor exporter (requires the Azure.Monitor.OpenTelemetry.AspNetCore package)
93+
//if (!string.IsNullOrEmpty(builder.Configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"]))
94+
//{
95+
// builder.Services.AddOpenTelemetry()
96+
// .UseAzureMonitor();
97+
//}
98+
99+
return builder;
100+
}
101+
102+
public static TBuilder AddDefaultHealthChecks<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder
103+
{
104+
builder.Services.AddHealthChecks()
105+
// Add a default liveness check to ensure app is responsive
106+
.AddCheck("self", () => HealthCheckResult.Healthy(), ["live"]);
107+
108+
return builder;
109+
}
110+
111+
public static WebApplication MapDefaultEndpoints(this WebApplication app)
112+
{
113+
// Adding health checks endpoints to applications in non-development environments has security implications.
114+
// See https://aka.ms/dotnet/aspire/healthchecks for details before enabling these endpoints in non-development environments.
115+
if (app.Environment.IsDevelopment())
116+
{
117+
// All health checks must pass for app to be considered ready to accept traffic after starting
118+
app.MapHealthChecks(HealthEndpointPath);
119+
120+
// Only health checks tagged with the "live" tag must pass for app to be considered alive
121+
app.MapHealthChecks(AlivenessEndpointPath, new HealthCheckOptions
122+
{
123+
Predicate = r => r.Tags.Contains("live")
124+
});
125+
}
126+
127+
return app;
128+
}
129+
}

IdentityServer/v7/Quickstarts/6_JS_without_backend/src/IdentityServer/HostingExtensions.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using Duende.IdentityServer;
55
using Google.Apis.Auth.AspNetCore3;
6+
using Microsoft.AspNetCore.DataProtection;
67
using Microsoft.IdentityModel.Tokens;
78
using Serilog;
89

@@ -27,12 +28,12 @@ public static WebApplication ConfigureServices(this WebApplicationBuilder builde
2728
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
2829
options.SignOutScheme = IdentityServerConstants.SignoutScheme;
2930
options.SaveTokens = true;
30-
31+
3132
options.Authority = "https://demo.duendesoftware.com";
3233
options.ClientId = "interactive.confidential";
3334
options.ClientSecret = "secret";
3435
options.ResponseType = "code";
35-
36+
3637
options.TokenValidationParameters = new TokenValidationParameters
3738
{
3839
NameClaimType = "name",
@@ -51,10 +52,10 @@ public static WebApplication ConfigureServices(this WebApplicationBuilder builde
5152
configureOptions: options =>
5253
{
5354
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
54-
55+
5556
options.ClientId = googleClientId;
5657
options.ClientSecret = googleClientSecret;
57-
58+
5859
options.CallbackPath = "/signin-google";
5960
});
6061
}

IdentityServer/v7/SessionManagement/Api/Api.csproj

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@
77

88
<ItemGroup>
99
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.5" />
10-
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
10+
<PackageReference Include="Serilog.AspNetCore" Version="10.0.0" />
11+
</ItemGroup>
12+
13+
<ItemGroup>
14+
<ProjectReference Include="..\..\Apire.ServiceDefaults\Aspire.ServiceDefaults.csproj" />
15+
<ProjectReference Include="..\SessionManagement.ServiceDefaults\SessionManagement.ServiceDefaults.csproj" />
1116
</ItemGroup>
1217

1318
</Project>

IdentityServer/v7/SessionManagement/Api/Program.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
.CreateLogger();
1414

1515
var builder = WebApplication.CreateBuilder(args);
16+
17+
builder.AddServiceDefaults();
1618
builder.Services.AddSerilog();
1719

1820
builder.Services.AddControllers();
@@ -30,6 +32,8 @@
3032

3133
var app = builder.Build();
3234

35+
app.MapDefaultEndpoints();
36+
3337
app.UseRouting();
3438
app.UseAuthentication();
3539
app.UseAuthorization();

IdentityServer/v7/SessionManagement/Client/Client.csproj

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,15 @@
77

88

99
<ItemGroup>
10-
<PackageReference Include="Duende.IdentityModel" Version="7.1.0" />
10+
<PackageReference Include="Duende.IdentityModel" Version="8.1.0" />
1111

1212
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="10.0.5" />
1313
</ItemGroup>
1414

15+
16+
<ItemGroup>
17+
<ProjectReference Include="..\..\Apire.ServiceDefaults\Aspire.ServiceDefaults.csproj" />
18+
<ProjectReference Include="..\SessionManagement.ServiceDefaults\SessionManagement.ServiceDefaults.csproj" />
19+
</ItemGroup>
20+
1521
</Project>

IdentityServer/v7/SessionManagement/Client/Program.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
var builder = WebApplication.CreateBuilder(args);
1212

13+
builder.AddServiceDefaults();
14+
1315
builder.Services.AddControllersWithViews();
1416
builder.Services.AddHttpClient();
1517

@@ -62,6 +64,8 @@
6264

6365
var app = builder.Build();
6466

67+
app.MapDefaultEndpoints();
68+
6569
app.UseDeveloperExceptionPage();
6670
app.UseStaticFiles();
6771

IdentityServer/v7/SessionManagement/IdentityServerHost/IdentityServerHost.csproj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77

88
<ItemGroup>
99
<PackageReference Include="Duende.IdentityServer" Version="7.4.7" />
10-
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
10+
</ItemGroup>
11+
12+
<ItemGroup>
13+
<ProjectReference Include="..\..\Apire.ServiceDefaults\Aspire.ServiceDefaults.csproj" />
14+
<ProjectReference Include="..\SessionManagement.ServiceDefaults\SessionManagement.ServiceDefaults.csproj" />
1115
</ItemGroup>
1216

1317
</Project>

IdentityServer/v7/SessionManagement/IdentityServerHost/Program.cs

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,17 @@
55
using Duende.IdentityServer;
66
using IdentityServerHost;
77
using Microsoft.AspNetCore.DataProtection;
8-
using Serilog;
9-
using Serilog.Sinks.SystemConsole.Themes;
108

119
Console.Title = "IdentityServer";
1210

13-
Log.Logger = new LoggerConfiguration()
14-
.MinimumLevel.Information()
15-
.Enrich.FromLogContext()
16-
.WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}", theme: AnsiConsoleTheme.Code)
17-
.CreateLogger();
18-
1911
var builder = WebApplication.CreateBuilder(args);
20-
builder.Services.AddSerilog();
12+
13+
builder.AddServiceDefaults();
2114

2215
builder.Services.AddRazorPages();
2316

2417
var idsvrBuilder = builder.Services.AddIdentityServer(options =>
2518
{
26-
options.Events.RaiseErrorEvents = true;
27-
options.Events.RaiseInformationEvents = true;
28-
options.Events.RaiseFailureEvents = true;
29-
options.Events.RaiseSuccessEvents = true;
30-
3119
// see https://docs.duendesoftware.com/identityserver/fundamentals/resources/
3220
options.EmitStaticAudienceClaim = true;
3321

@@ -68,6 +56,8 @@
6856

6957
var app = builder.Build();
7058

59+
app.MapDefaultEndpoints();
60+
7161
if (app.Environment.IsDevelopment())
7262
{
7363
app.UseDeveloperExceptionPage();
Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
# Session Management Sample
2-
3-
This sample requires all three projects to be run at once.
4-
5-
Things of note:
6-
* In the *IdentityServer* project in *Startup.cs*, server-side sessions are enabled with a call to *AddServerSideSessions*. This only uses in-memory server-side sessions by default, so restarting the host will lose session data.
7-
* Also in *Startup.cs* with the call to *AddIdentityServer* various settings are configured on the *ServerSideSessions* options object to control the behavior.
8-
* The client application configured in *Clients.cs* has *CoordinateLifetimeWithUserSession* enabled, which causes its refresh token to slide the server-side session for the user.
9-
* When launching the *IdentityServer* project, you should visit the *~/serversidesessions* page to see the active sessions. Note that there is no authorization on this page (so consider adding it based on your requirements).
10-
* Once you login, you should see a user's session in the list.
11-
* As the client app refreshes its access token, you should see the user's session expiration being extended.
12-
* When you revoke the user's session, the user should be logged out of the client app.
1+
**Session Management Sample**
2+
This sample requires all three projects to be run at once. That can easily be done by running the included Aspire AppHost. The Aspire dashboard will show the status of all running applications and show you the links to the running applications. Aspire will also collect the Open Telemetry data (logs, metrics, traces) and make it available on the dashboard.
3+
 Please note that Aspire’s service discovery isn’t used here so that projects can still run without Aspire, but it can easily be [added](https://aspire.dev/fundamentals/service-discovery/ "https://aspire.dev/fundamentals/service-discovery/") if needed.
4+
Things of note:
5+
- In the *IdentityServer* project in *Startup.cs*, server-side sessions are enabled with a call to *AddServerSideSessions*. This only uses in-memory server-side sessions by default, so restarting the host will lose session data.
6+
- Also in *Startup.cs* with the call to *AddIdentityServer* various settings are configured on the *ServerSideSessions* options object to control the behavior.
7+
- The client application configured in *Clients.cs* has *CoordinateLifetimeWithUserSession* enabled, which causes its refresh token to slide the server-side session for the user.
8+
- When launching the *IdentityServer* project, you should visit the *~/serversidesessions* page to see the active sessions. Note that there is no authorization on this page (so consider adding it based on your requirements).
9+
- Once you login, you should see a user's session in the list.
10+
- As the client app refreshes its access token, you should see the user's session expiration being extended.
11+
- When you revoke the user's session, the user should be logged out of the client app.

0 commit comments

Comments
 (0)