Skip to content

Commit

Permalink
Modernize code in data, diagnostics, fundamentals (#487)
Browse files Browse the repository at this point in the history
Co-authored-by: Roland Guijt <[email protected]>
  • Loading branch information
RolandGuijt and Roland Guijt authored Jun 20, 2024
1 parent 20dbc55 commit 663acc6
Show file tree
Hide file tree
Showing 13 changed files with 129 additions and 192 deletions.
62 changes: 28 additions & 34 deletions IdentityServer/v7/docs/content/data/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,12 @@ There are [convenience methods]({{<ref "/reference/di#configuration-stores">}})
For example:

```cs
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentityServer()
.AddClientStore<YourCustomClientStore>()
.AddCorsPolicyService<YourCustomCorsPolicyService>()
.AddResourceStore<YourCustomResourceStore>()
.AddIdentityProviderStore<YourCustomAddIdentityProviderStore>();
}
builder.Services.AddIdentityServer()
.AddClientStore<YourCustomClientStore>()
.AddCorsPolicyService<YourCustomCorsPolicyService>()
.AddResourceStore<YourCustomResourceStore>()
.AddIdentityProviderStore<YourCustomAddIdentityProviderStore>();

```

## Caching Configuration Data
Expand All @@ -41,38 +39,34 @@ The caching implementation relies upon an *ICache\<T>* service and must also be
For example:

```cs
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentityServer()
.AddClientStore<YourCustomClientStore>()
.AddCorsPolicyService<YourCustomCorsPolicyService>()
.AddResourceStore<YourCustomResourceStore>()
.AddInMemoryCaching()
.AddClientStoreCache<YourCustomClientStore>()
.AddCorsPolicyCache<YourCustomCorsPolicyService>()
.AddResourceStoreCache<YourCustomResourceStore>()
.AddIdentityProviderStoreCache<YourCustomAddIdentityProviderStore>();
}
builder.Services.AddIdentityServer()
.AddClientStore<YourCustomClientStore>()
.AddCorsPolicyService<YourCustomCorsPolicyService>()
.AddResourceStore<YourCustomResourceStore>()
.AddInMemoryCaching()
.AddClientStoreCache<YourCustomClientStore>()
.AddCorsPolicyCache<YourCustomCorsPolicyService>()
.AddResourceStoreCache<YourCustomResourceStore>()
.AddIdentityProviderStoreCache<YourCustomAddIdentityProviderStore>();

```

The duration of the data in the default cache is configurable on the [IdentityServerOptions]({{<ref "/reference/options#caching">}}).
For example:

```cs
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentityServer(options => {
options.Caching.ClientStoreExpiration = TimeSpan.FromMinutes(5);
options.Caching.ResourceStoreExpiration = TimeSpan.FromMinutes(5);
})
.AddClientStore<YourCustomClientStore>()
.AddCorsPolicyService<YourCustomCorsPolicyService>()
.AddResourceStore<YourCustomResourceStore>()
.AddInMemoryCaching()
.AddClientStoreCache<YourCustomClientStore>()
.AddCorsPolicyCache<YourCustomCorsPolicyService>()
.AddResourceStoreCache<YourCustomResourceStore>();
}
builder.Services.AddIdentityServer(options => {
options.Caching.ClientStoreExpiration = TimeSpan.FromMinutes(5);
options.Caching.ResourceStoreExpiration = TimeSpan.FromMinutes(5);
})
.AddClientStore<YourCustomClientStore>()
.AddCorsPolicyService<YourCustomCorsPolicyService>()
.AddResourceStore<YourCustomResourceStore>()
.AddInMemoryCaching()
.AddClientStoreCache<YourCustomClientStore>()
.AddCorsPolicyCache<YourCustomCorsPolicyService>()
.AddResourceStoreCache<YourCustomResourceStore>();

```

Further customization of the cache is possible:
Expand Down
75 changes: 34 additions & 41 deletions IdentityServer/v7/docs/content/data/ef.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,20 @@ For storing [configuration data]({{<ref "./configuration">}}), then the configur
This support provides implementations of the *IClientStore*, *IResourceStore*, *IIdentityProviderStore*, and the *ICorsPolicyService* extensibility points.
These implementations use a *DbContext*-derived class called *ConfigurationDbContext* to model the tables in the database.

To use the configuration store support, use the *AddConfigurationStore* extension method after the call to *AddIdentityServer*:
To use the configuration store support, in Program.cs use the *AddConfigurationStore* extension method after the call to *AddIdentityServer*:

```csharp
public IServiceProvider ConfigureServices(IServiceCollection services)
{
const string connectionString = @"Data Source=(LocalDb)\MSSQLLocalDB;database=YourIdentityServerDatabase;trusted_connection=yes;";
var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;

services.AddIdentityServer()
// this adds the config data from DB (clients, resources, CORS)
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = builder =>
builder.UseSqlServer(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
});
}
const string connectionString = @"Data Source=(LocalDb)\MSSQLLocalDB;database=YourIdentityServerDatabase;trusted_connection=yes;";
var migrationsAssembly = typeof(Program).GetTypeInfo().Assembly.GetName().Name;

builder.Services.AddIdentityServer()
// this adds the config data from DB (clients, resources, CORS)
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = builder =>
builder.UseSqlServer(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
});
```

To configure the configuration store, use the *ConfigurationStoreOptions* options object passed to the configuration callback.
Expand Down Expand Up @@ -70,41 +67,37 @@ options.ConfigureDbContext = b =>
To enable caching for the EF configuration store implementation, use the *AddConfigurationStoreCache* extension method:

```csharp
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddIdentityServer()
.AddConfigurationStore(options => { ... })
// this is something you will want in production to reduce load on and requests to the DB
.AddConfigurationStoreCache();
}
builder.Services.AddIdentityServer()
.AddConfigurationStore(options => { ... })
// this is something you will want in production to reduce load on and requests to the DB
.AddConfigurationStoreCache();

```

## Operational Store
For storing [operational data]({{<ref "./operational">}}) then the operational store can be used.
This support provides implementations of the *IPersistedGrantStore*, *IDeviceFlowStore*, *IServerSideSessionStore*, and *ISigningKeyStore* extensibility points.
The implementation uses a *DbContext*-derived class called *PersistedGrantDbContext* to model the table in the database.

To use the operational store support, use the *AddOperationalStore* extension method after the call to *AddIdentityServer*:
To use the operational store support, in Program.cs use the *AddOperationalStore* extension method after the call to *AddIdentityServer*:

```csharp
public IServiceProvider ConfigureServices(IServiceCollection services)
{
const string connectionString = @"Data Source=(LocalDb)\MSSQLLocalDB;database=YourIdentityServerDatabase;trusted_connection=yes;";
var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;

services.AddIdentityServer()
// this adds the operational data from DB (codes, tokens, consents)
.AddOperationalStore(options =>
{
options.ConfigureDbContext = builder =>
builder.UseSqlServer(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));

// this enables automatic token cleanup. this is optional.
options.EnableTokenCleanup = true;
options.TokenCleanupInterval = 3600; // interval in seconds (default is 3600)
});
}
const string connectionString = @"Data Source=(LocalDb)\MSSQLLocalDB;database=YourIdentityServerDatabase;trusted_connection=yes;";
var migrationsAssembly = typeof(Program).GetTypeInfo().Assembly.GetName().Name;

builder.Services.AddIdentityServer()
// this adds the operational data from DB (codes, tokens, consents)
.AddOperationalStore(options =>
{
options.ConfigureDbContext = builder =>
builder.UseSqlServer(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));

// this enables automatic token cleanup. this is optional.
options.EnableTokenCleanup = true;
options.TokenCleanupInterval = 3600; // interval in seconds (default is 3600)
});

```

To configure the operational store, use the *OperationalStoreOptions* options object passed to the configuration callback.
Expand Down
11 changes: 4 additions & 7 deletions IdentityServer/v7/docs/content/data/operational/grants.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,10 @@ Custom implementations of *IPersistedGrantStore*, and/or *IDeviceFlowStore* must
For example:

```cs
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentityServer();

services.AddTransient<IPersistedGrantStore, YourCustomPersistedGrantStore>();
services.AddTransient<IDeviceFlowStore, YourCustomDeviceFlowStore>();
}
builder.Services.AddIdentityServer();

builder.Services.AddTransient<IPersistedGrantStore, YourCustomPersistedGrantStore>();
builder.Services.AddTransient<IDeviceFlowStore, YourCustomDeviceFlowStore>();
```

## Grant Expiration and Consumption
Expand Down
7 changes: 2 additions & 5 deletions IdentityServer/v7/docs/content/data/operational/keys.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,8 @@ To register a custom signing key store in the DI container, there is a *AddSigni
For example:

```cs
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentityServer()
.AddSigningKeyStore<YourCustomStore>();
}
builder.Services.AddIdentityServer()
.AddSigningKeyStore<YourCustomStore>();
```

## Key Lifecycle
Expand Down
32 changes: 12 additions & 20 deletions IdentityServer/v7/docs/content/data/operational/sessions.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,17 @@ It is still necessary to call *AddServerSideSessions* to enable the server-side
For example:

```cs
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentityServer()
.AddServerSideSessions()
.AddServerSideSessionStore<YourCustomStore>();
}
builder.Services.AddIdentityServer()
.AddServerSideSessions()
.AddServerSideSessionStore<YourCustomStore>();
```

There is also an overloaded version of a *AddServerSideSessions* that will perform both registration steps in one call.
For example:

```cs
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentityServer()
.AddServerSideSessions<YourCustomStore>();
}
builder.Services.AddIdentityServer()
.AddServerSideSessions<YourCustomStore>();
```

## EntityFramework store implementation
Expand All @@ -50,13 +44,11 @@ For example:


```cs
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentityServer()
.AddServerSideSessions()
.AddOperationalStore(options =>
{
// ...
});
}
builder.Services.AddIdentityServer()
.AddServerSideSessions()
.AddOperationalStore(options =>
{
// ...
});

```
4 changes: 2 additions & 2 deletions IdentityServer/v7/docs/content/diagnostics/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ This makes it easy to query and analyze them and extract useful information that
Events work great with structured logging stores like [ELK](https://www.elastic.co/webinars/introduction-elk-stack), [Seq](https://getseq.net) or [Splunk](https://www.splunk.com/).

### Emitting events
Events are not turned on by default - but can be globally configured in the *ConfigureServices* method, e.g.:
Events are not turned on by default - but can be globally configured when *AddIdentityServer* is called, e.g.:

```cs
services.AddIdentityServer(options =>
builder.Services.AddIdentityServer(options =>
{
options.Events.RaiseSuccessEvents = true;
options.Events.RaiseFailureEvents = true;
Expand Down
55 changes: 14 additions & 41 deletions IdentityServer/v7/docs/content/diagnostics/logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,45 +42,18 @@ In production, logging might produce too much data. It is recommended you either
We personally like [Serilog](https://serilog.net) and the [Serilog.AspNetCore](https://github.com/serilog/serilog-aspnetcore) package a lot. Give it a try:

```cs
public class Program
{
public static int Main(string[] args)
{
Activity.DefaultIdFormat = ActivityIdFormat.W3C;

Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.MinimumLevel.Override("Microsoft.Hosting.Lifetime", LogEventLevel.Information)
.MinimumLevel.Override("System", LogEventLevel.Warning)
.MinimumLevel.Override("Microsoft.AspNetCore.Authentication", LogEventLevel.Information)
.Enrich.FromLogContext()
.WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}", theme: AnsiConsoleTheme.Code)
.CreateLogger();

try
{
Log.Information("Starting host...");
CreateHostBuilder(args).Build().Run();
return 0;
}
catch (Exception ex)
{
Log.Fatal(ex, "Host terminated unexpectedly.");
return 1;
}
finally
{
Log.CloseAndFlush();
}
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder(args)
.UseSerilog()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
//Program.cs
Activity.DefaultIdFormat = ActivityIdFormat.W3C;

Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.MinimumLevel.Override("Microsoft.Hosting.Lifetime", LogEventLevel.Information)
.MinimumLevel.Override("System", LogEventLevel.Warning)
.MinimumLevel.Override("Microsoft.AspNetCore.Authentication", LogEventLevel.Information)
.Enrich.FromLogContext()
.WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}", theme: AnsiConsoleTheme.Code)
.CreateLogger();

builder.Logging.AddSeriLog();
```
18 changes: 5 additions & 13 deletions IdentityServer/v7/docs/content/fundamentals/hosting.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,10 @@ While technically you could share the ASP.NET Core host between Duende IdentityS
{{% /notice %}}

## DI system
You add the necessary services to the DI system by calling *AddIdentityServer* in your startup class:
You add the necessary services to the DI system by calling *AddIdentityServer* at application startup:

```cs
public void ConfigureServices(IServiceCollection services)
{
var builder = services.AddIdentityServer(options => { ... });
}
var idsvrBuilder = builder.Services.AddIdentityServer(options => { ... });
```

Many of the fundamental configuration settings can be set on the options. See the *[IdentityServerOptions]({{< ref "/reference/options" >}})* reference for more details.
Expand All @@ -25,7 +22,7 @@ The builder object has a number of extension methods to add additional services
You can see the full list in the [reference]({{< ref "/reference/di" >}}) section, but very commonly you start by adding the configuration stores for clients and resources, e.g.:

```cs
var builder = services.AddIdentityServer()
var idsvrBuilder = builder.Services.AddIdentityServer()
.AddInMemoryClients(Config.Clients)
.AddInMemoryIdentityResources(Config.IdentityResources)
.AddInMemoryApiScopes(Config.ApiScopes)
Expand All @@ -41,19 +38,14 @@ Since ordering is important in the pipeline, you typically want to put the Ident
This would be a very typical minimal pipeline:

```cs
public void Configure(IApplicationBuilder app)
{
app.UseStaticFiles();

app.UseRouting();
app.UseIdentityServer();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
app.MapDefaultControllerRoute();

```

{{% notice note %}}
Expand Down
Loading

0 comments on commit 663acc6

Please sign in to comment.