Skip to content

Align DBSC with ASP.NET Core auth-scheme conventions - #68520

Open
rokonec wants to merge 1 commit into
mainfrom
roman/dbsc-auth-scheme-consistency
Open

Align DBSC with ASP.NET Core auth-scheme conventions#68520
rokonec wants to merge 1 commit into
mainfrom
roman/dbsc-auth-scheme-consistency

Conversation

@rokonec

@rokonec rokonec commented Aug 14, 2026

Copy link
Copy Markdown
Member

Aligns the Device Bound Sessions scheme with established ASP.NET Core authentication-scheme conventions, implementing the approved API review from #68117 plus the consistency gaps that review left open.

Follows up on #67388 (DBSC prototype).

Why

DBSC deviated from every other built-in scheme in ways that surprise callers:

  • The named scheme did not authenticate. AuthenticateAsync("DeviceBoundSession") returned NoResult, while a hidden {source}.Dbsc policy scheme did the real work.
  • There were no typed Events. Instead the component mutated the source cookie scheme's OnSigningIn/OnSigningOut — something no other built-in scheme does.
  • AddDeviceBoundSession took a sourceScheme string across four overloads with shifting parameter order.

What changed

Authentication (behavioral)

DbscHandler.HandleAuthenticateAsync now authenticates the session cookie scheme, falls back to the source scheme, and restamps the ticket with the DBSC scheme. The hidden policy scheme is removed.

The fallback is result-aware rather than cookie-presence-based. This fixes a latent defect: an expired or tampered session cookie previously blocked fallback to a still-valid source cookie.

API surface (approved in #68117)

namespace Microsoft.AspNetCore.Authentication.Dbsc;

public static class DbscDefaults            // AuthenticationScheme = "DBSC"
public class DbscHandler                     // was DeviceBoundSessionHandler
public class DbscOptions                     // SourceScheme replaces 3 scheme properties
public class DbscScopeRule
public static class DbscRegistration         // WriteRegistrationAsync(HttpContext, string dbscScheme)

// Microsoft.Extensions.DependencyInjection
DbscExtensions.AddDbsc()
DbscExtensions.AddDbsc(string authenticationScheme)
DbscExtensions.AddDbsc(string authenticationScheme, Action<DbscOptions> configureOptions)
  • SourceScheme (default CookieAuthenticationDefaults.AuthenticationScheme) replaces RegistrationSourceScheme, RefreshScheme, and SessionScheme. Derived scheme names are now internal and derived from the DBSC scheme, because SourceScheme materializes after companion schemes register.
  • The four W3C wire DTOs (SessionInstruction, SessionCredential, SessionScope, SessionScopeRule) are internal; their public review was tabled. The serialized wire contract is unchanged, asserted byte-for-byte.
  • Stronger Validate (non-empty source scheme, cycle guard, positive durations, scope-rule members) and URI-escaped derived cookie names.
  • Duplicate DBSC schemes over one source scheme now fail with a message naming both schemes, detected after named options materialize.

Typed events

DbscEvents follows the CookieAuthenticationEvents pattern, with EventsType support and CreateEventsAsync:

  • OnRegistrationHeaderCreating - also the natural future home for federated provider data
  • OnSessionRegistered
  • OnSessionRefreshed

Important

DbscEvents, its context types, and WriteRegistrationAsync are not covered by the #68117 approval. The review asked for events but tabled their shape. WriteRegistration became async so both the automatic sign-in path and the public helper raise events consistently. This needs API sign-off before merge.

Sign-out

No base-class change: DbscHandler remains AuthenticationHandler<DbscOptions>, matching the approved surface, so SignOutAsync(dbscScheme) is still unsupported and logout flows through SourceScheme - which clears the source, session, and refresh cookies.

Added a four-branch sign-out matrix covering the registration-exchange guard, registered DBSC agents, non-DBSC agents, and mid-registration state.

Breaking changes

This is an experimental 0.x package gated behind ASP0031.

  • AddDeviceBoundSession(scheme, sourceScheme) becomes AddDbsc(scheme, o => o.SourceScheme = ...). The two-argument overload's string now means the DBSC scheme, not the source scheme.
  • HttpContext.WriteDeviceBoundSessionRegistration(sourceScheme) becomes await DbscRegistration.WriteRegistrationAsync(context, dbscScheme).
  • Derived cookie names changed, so existing DBSC sessions do not carry forward.
  • Namespace, package, assembly, and directory renamed to Microsoft.AspNetCore.Authentication.Dbsc.

Validation

  • Microsoft.AspNetCore.Authentication.Test: 864 passed, 0 failed, 3 skipped.
  • DBSC tests grew from 115 to 152.
  • Verified end-to-end in Chrome against the DbscDebugServer sample: registration, refresh (POST /.well-known/dbsc/refresh returning 200), and in-scope API calls all succeed, with DbscHandler logging AuthenticationScheme: DBSC was successfully authenticated.

Follow-ups (not in this PR)

- authenticate via the named scheme with result-aware session/source fallback
- add DbscOptions.SourceScheme, three AddDbsc overloads, and typed DbscEvents
- internalize wire DTOs and rename types, namespace, and package to Dbsc

🔐 - Generated by Copilot
Copilot AI lite review requested due to automatic review settings August 14, 2026 11:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request renames and refactors the experimental Device Bound Session Credentials implementation to Microsoft.AspNetCore.Authentication.Dbsc, aligning it with ASP.NET Core authentication-scheme conventions (DBSC scheme now authenticates directly, policy-scheme indirection removed), while expanding validation, adding typed events, and updating tests/build metadata accordingly.

Changes:

  • Introduces the Microsoft.AspNetCore.Authentication.Dbsc package (new options/events/handler/registration helper) and removes the older DeviceBoundSessions extension wiring.
  • Updates and expands authentication tests under src/Security/Authentication/test/Dbsc/ to cover authenticate, sign-out matrix, options validation, and event firing.
  • Renames and re-wires repo build metadata (project references, shipping/trimmable lists, solution folders) to the new assembly/package name.

Reviewed changes

Copilot reviewed 58 out of 63 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/Security/Authentication/test/Microsoft.AspNetCore.Authentication.Test.csproj Updates test project reference to the new Dbsc assembly.
src/Security/Authentication/test/DeviceBoundSessions/DeviceBoundSessionSignOutTests.cs Removes legacy sign-out tests tied to the prior package/shape.
src/Security/Authentication/test/DeviceBoundSessions/DeviceBoundSessionOptionsTests.cs Removes legacy options tests for the prior options type.
src/Security/Authentication/test/DeviceBoundSessions/DeviceBoundSessionAuthenticationOptionsTests.cs Removes tests for the prior policy-scheme default-upgrade behavior.
src/Security/Authentication/test/Dbsc/DbscSignOutTests.cs Adds sign-out behavior tests for the new scheme topology.
src/Security/Authentication/test/Dbsc/DbscRevocationTests.cs Renames/updates revocation tests to Dbsc namespace and derived cookie names.
src/Security/Authentication/test/Dbsc/DbscRegistrationHeaderTests.cs Updates registration-header emission tests for async/event-aware emission.
src/Security/Authentication/test/Dbsc/DbscProofKey.cs Renames proof-JWT helper namespace to Dbsc.
src/Security/Authentication/test/Dbsc/DbscOptionsTests.cs Adds DbscOptions validation and derived cookie-name escaping tests.
src/Security/Authentication/test/Dbsc/DbscLifetimeTests.cs Updates lifetime/sliding/TimeProvider tests to new scheme names and headers.
src/Security/Authentication/test/Dbsc/DbscJwtValidatorTests.cs Renames validator tests to DbscJwtValidator.
src/Security/Authentication/test/Dbsc/DbscInstructionTests.cs Updates instruction JSON/context + asserts wire output stability.
src/Security/Authentication/test/Dbsc/DbscEventsTests.cs Adds tests asserting typed events fire once and in-order across stages.
src/Security/Authentication/test/Dbsc/DbscCredentialTests.cs Updates credential attribute/cookie naming expectations for new defaults.
src/Security/Authentication/test/Dbsc/DbscCookieProtectionTests.cs Updates derived-cookie post-config tests and introduces Moq for options monitor.
src/Security/Authentication/test/Dbsc/DbscChallengeProtectorTests.cs Renames challenge protector tests to DbscChallengeProtector.
src/Security/Authentication/test/Dbsc/DbscAuthenticationOptionsTests.cs Adds tests for default authenticate-scheme upgrade + duplicate-source-scheme detection.
src/Security/Authentication/test/Dbsc/DbscAuthenticateTests.cs Adds tests for DBSC scheme authentication + restamping + fallback behavior.
src/Security/Authentication/DeviceBoundSessions/src/PublicAPI.Unshipped.txt Removes unshipped API list for the old package.
src/Security/Authentication/DeviceBoundSessions/src/PostConfigureDeviceBoundSessionCookieOptions.cs Removes legacy cookie post-config integration.
src/Security/Authentication/DeviceBoundSessions/src/PostConfigureDeviceBoundSessionAuthenticationOptions.cs Removes legacy auth-options post-config behavior.
src/Security/Authentication/DeviceBoundSessions/src/DeviceBoundSessionSourceSchemes.cs Removes legacy scheme-mapping container.
src/Security/Authentication/DeviceBoundSessions/src/DeviceBoundSessionExtensions.cs Removes legacy DI entry points/overloads.
src/Security/Authentication/Dbsc/src/SessionScopeRule.cs Makes wire DTO internal and updates namespace/serialization attributes.
src/Security/Authentication/Dbsc/src/SessionScope.cs Makes wire DTO internal and updates namespace/serialization attributes.
src/Security/Authentication/Dbsc/src/SessionInstruction.cs Makes wire DTO internal and updates namespace/serialization attributes.
src/Security/Authentication/Dbsc/src/SessionCredential.cs Makes wire DTO internal and updates namespace/serialization attributes.
src/Security/Authentication/Dbsc/src/PublicAPI.Unshipped.txt Adds the new Dbsc public API surface for API baselining.
src/Security/Authentication/Dbsc/src/PublicAPI.Shipped.txt Initializes shipped API tracking for the new assembly.
src/Security/Authentication/Dbsc/src/PostConfigureDbscOptions.cs Adds post-config to validate and claim SourceScheme after options materialize.
src/Security/Authentication/Dbsc/src/PostConfigureDbscDerivedCookieOptions.cs Copies source-cookie settings onto derived cookies and scopes refresh cookie path.
src/Security/Authentication/Dbsc/src/PostConfigureDbscCookieOptions.cs Hooks source cookie scheme sign-in/out to registration header emission and derived-cookie clearing.
src/Security/Authentication/Dbsc/src/PostConfigureDbscAuthenticationOptions.cs Redirects app default-authenticate scheme from wrapped source to DBSC scheme.
src/Security/Authentication/Dbsc/src/Microsoft.AspNetCore.Authentication.Dbsc.csproj New package project file for the Dbsc assembly.
src/Security/Authentication/Dbsc/src/DbscSourceSchemes.cs Adds scheme mapping + duplicate-source-scheme enforcement.
src/Security/Authentication/Dbsc/src/DbscScopeRule.cs Renames scope rule type to DbscScopeRule.
src/Security/Authentication/Dbsc/src/DbscRegistrationHeaderCreatingContext.cs Adds event context for registration-header creation.
src/Security/Authentication/Dbsc/src/DbscRegistrationHeader.cs Makes registration header emission async and event-aware.
src/Security/Authentication/Dbsc/src/DbscRegistration.cs Replaces HttpContext extension with DbscRegistration.WriteRegistrationAsync helper.
src/Security/Authentication/Dbsc/src/DbscRegisteredContext.cs Adds event context for successful registration stage.
src/Security/Authentication/Dbsc/src/DbscRefreshedContext.cs Adds event context for successful refresh stage.
src/Security/Authentication/Dbsc/src/DbscOptions.cs Replaces prior options shape with SourceScheme + typed Events + stronger validation.
src/Security/Authentication/Dbsc/src/DbscLoggingExtensions.cs Renames logging helpers to DbscLoggingExtensions.
src/Security/Authentication/Dbsc/src/DbscJwtValidator.cs Renames/updates proof JWT validator to DbscJwtValidator.
src/Security/Authentication/Dbsc/src/DbscJwtResult.cs Renames validator result DTO to DbscJwtResult.
src/Security/Authentication/Dbsc/src/DbscJsonContext.cs Renames JSON source-gen context to DbscJsonContext.
src/Security/Authentication/Dbsc/src/DbscHandler.cs Implements direct authentication on the DBSC scheme + event hooks for register/refresh.
src/Security/Authentication/Dbsc/src/DbscExtensions.cs Adds AddDbsc(...) DI entry points and derived scheme registration.
src/Security/Authentication/Dbsc/src/DbscEvents.cs Introduces typed events surface (delegates + virtual methods).
src/Security/Authentication/Dbsc/src/DbscDefaults.cs Renames defaults class and sets AuthenticationScheme to “DBSC”.
src/Security/Authentication/Dbsc/src/DbscCookieEvents.cs Renames cookie events wrapper and updates registration-exchange guard key.
src/Security/Authentication/Dbsc/src/DbscConstants.cs Renames protocol constants container to DbscConstants.
src/Security/Authentication/Dbsc/src/DbscChallengeProtector.cs Renames and updates challenge protector purposes for the new namespace/package.
src/Security/Authentication/Dbsc/samples/DbscDebugServer/Properties/launchSettings.json Adds sample launch settings.
src/Security/Authentication/Dbsc/samples/DbscDebugServer/Program.cs Updates sample to AddDbsc and new options/scheme behavior.
src/Security/Authentication/Dbsc/samples/DbscDebugServer/HarLoggingMiddleware.cs Adds HAR capture middleware for debugging protocol flows.
src/Security/Authentication/Dbsc/samples/DbscDebugServer/DbscDebugServer.csproj Updates sample project reference to new Dbsc assembly.
src/Security/Authentication/Dbsc/samples/DbscDebugServer/DbscDebug.cs Updates sample constants for new cookie names and challenge purposes.
src/Security/Authentication/Dbsc/samples/DbscDebugServer/Dashboard.cs Adds dashboard HTML UI for interactive debug/inspection.
eng/TrimmableProjects.props Renames trimmable project entry to the Dbsc assembly.
eng/ShippingAssemblies.props Renames shipping assembly entry to the Dbsc assembly.
eng/ProjectReferences.props Updates project reference provider mapping to Dbsc csproj path.
AspNetCore.slnx Renames solution folders/projects from DeviceBoundSessions to Dbsc paths.
Suppressed comments (1)

src/Security/Authentication/Dbsc/src/DbscOptions.cs:97

  • DbscOptions.Validate doesn’t currently verify that the internally-derived cookie scheme names (RefreshScheme / SessionScheme) are configured. If DbscHandler is registered via AddScheme<DbscOptions, DbscHandler> (instead of AddDbsc), these will remain null and later SignInAsync(Options.RefreshScheme/SessionScheme, ...) will throw with a less actionable error. Consider failing fast with a clear message directing callers to use AddDbsc(...).

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants