dotnet / dotnet/aspnetcore

Registration flag for all middleware

Open
#66,211 0 comments 0 reactions 0 assignees View on GitHub
area-middleware design-proposal feature-authentication
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 5h
Merged PRs (30d)
276

Description

## Summary

Add a registration flag for all middleware to indicate whether it has already been added to the pipeline, similar to `UseAuthentication` and `UseAuthorization`. Currently, `UseSession` and some other middleware do not expose such a flag, making it hard to prevent duplicate registrations.

## Motivation and goals

- Prevent accidental multiple registrations of the same middleware, which can lead to subtle bugs, duplicated processing, or session inconsistencies.
- Provide developers a consistent way to check if a middleware has already been added, improving safety and maintainability.
- `UseAuthentication` and `UseAuthorization` already implement this pattern with internal flags, but `UseSession` does not. Adding this would unify middleware behavior across the framework.

**Goals:**

- Introduce a standard mechanism for middleware to track registration.
- Ensure existing middleware like `UseSession`, `UseCors`, `UseResponseCaching` can optionally adopt this.
- Maintain backward compatibility with existing applications.

## In scope

- Adding an internal registration flag to `SessionMiddleware` and other extension methods. (`UseCors`, `UseResponseCaching`...)

## Out of scope

- Changing the public API signature of middleware extension methods.

## Risks / unknowns

- Developers may expect `UseSession()` to be idempotent already; adding the flag could change subtle behaviors if a middleware was previously registered twice intentionally.
- Backward compatibility must be preserved: applications that currently register `UseSession` multiple times should not break.
- Security/performance: minimal, but double registration previously could have caused slight overhead or unintended side effects.

## Examples

```csharp
using Microsoft.AspNetCore.Session;
using Microsoft.Extensions.Options;

namespace Microsoft.AspNetCore.Builder;

public static class SessionMiddlewareExtensions

{
internal const string SessionMiddlewareSetKey = "__SessionMiddlewareSet";

public static IApplicationBuilder UseSession(this IApplicationBuilder app)
{
ArgumentNullException.ThrowIfNull(app);

app.Properties[SessionMiddlewareSetKey] = true;
return app.UseMiddleware();
}

public static IApplicationBuilder UseSession(this IApplicationBuilder app, SessionOptions options)
{
ArgumentNullException.ThrowIfNull(app);
ArgumentNullException.ThrowIfNull(options);

app.Properties[SessionMiddlewareSetKey] = true;
return app.UseMiddleware(Options.Create(options));
}
}
```

```csharp
// Program.cs
app.UseSession();

// Inside a NuGet package or shared library
if (!app.Properties.ContainsKey("__SessionMiddlewareSet"))
{
app.UseSession();
}

// Developers can rely on similar pattern to UseAuthorization/UseAuthentication
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.