Skip to content

Isolate JwtSecurityTokenHandler from consumer DI container#27

Merged
jeanlrnt merged 3 commits intomainfrom
copilot/refactor-di-registration-jwt
Dec 27, 2025
Merged

Isolate JwtSecurityTokenHandler from consumer DI container#27
jeanlrnt merged 3 commits intomainfrom
copilot/refactor-di-registration-jwt

Conversation

Copy link
Contributor

Copilot AI commented Dec 26, 2025

Refactor DI registration to isolate JwtSecurityTokenHandler

Plan:

  • Remove services.AddSingleton(new JwtSecurityTokenHandler...) from ServiceCollectionExtensions.cs
  • Update IMiniJwtService registration to use factory pattern that creates local JwtSecurityTokenHandler instance
  • Add TimeProvider resolution logic with fallback to TimeProvider.System
  • Run existing tests to verify no breaking changes (all 29 existing tests pass)
  • Create additional test to verify handler is not registered globally (new test passes)
  • Update documentation to reflect the new registration pattern
Original prompt

This section details on the original issue you should resolve

<issue_title>Refactor DI registration to isolate JwtSecurityTokenHandler</issue_title>
<issue_description>## Description

Currently, the AddMiniJwt extension method registers JwtSecurityTokenHandler as a global singleton in the user's dependency injection container.

See src/MiniJwt.Core/Extensions/ServiceCollectionExtensions.cs:

services.AddSingleton(new JwtSecurityTokenHandler { MapInboundClaims = false });

The Problem

Registering JwtSecurityTokenHandler globally "pollutes" the consumer's DI container. This creates a high risk of conflict if the consuming application uses other libraries that rely on JwtSecurityTokenHandler (such as Microsoft.AspNetCore.Authentication.JwtBearer, IdentityServer, or OpenIddict).

By registering it this way, MiniJwt.Core inadvertently imposes the setting MapInboundClaims = false globally, which might break other parts of the user's application that expect the default behavior or a different configuration.

Proposed Solution

We should encapsulate the JwtSecurityTokenHandler dependency so it is scoped only to MiniJwtService, without exposing it to the rest of the application.

Instead of registering the handler directly, we should use a factory delegate for IMiniJwtService.

Implementation Plan

Modify ServiceCollectionExtensions.cs to remove the explicit AddSingleton for the handler and instantiate it inside the factory:

// Remove this line:
// services.AddSingleton(new JwtSecurityTokenHandler { MapInboundClaims = false });

// Update the IMiniJwtService registration:
services.AddSingleton<IMiniJwtService>(sp => 
{
    var optionsMonitor = sp.GetRequiredService<IOptionsMonitor<MiniJwtOptions>>();
    var logger = sp.GetRequiredService<ILogger<MiniJwtService>>();
    
    // Resolve TimeProvider (available in .NET 8+ DI) or fallback to System
    var timeProvider = sp.GetService<TimeProvider>() ?? TimeProvider.System;

    // Create a local instance specifically for MiniJwt to avoid global side effects
    var tokenHandler = new JwtSecurityTokenHandler { MapInboundClaims = false };

    return new MiniJwtService(optionsMonitor, logger, tokenHandler, timeProvider);
});

Tasks

  • Remove services.AddSingleton(new JwtSecurityTokenHandler... from ServiceCollectionExtensions.cs.
  • Update IMiniJwtService registration to use the factory pattern.
  • Ensure TimeProvider is correctly resolved or defaulted to TimeProvider.System.
  • Verify that existing tests still pass.</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Co-authored-by: jeanlrnt <63308635+jeanlrnt@users.noreply.github.com>
Copilot AI changed the title [WIP] Refactor DI registration to isolate JwtSecurityTokenHandler Isolate JwtSecurityTokenHandler from consumer DI container Dec 26, 2025
Copilot AI requested a review from jeanlrnt December 26, 2025 17:25
@jeanlrnt jeanlrnt marked this pull request as ready for review December 26, 2025 23:29
Copilot AI review requested due to automatic review settings December 26, 2025 23:29
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors the DI registration to isolate JwtSecurityTokenHandler from the consumer's dependency injection container, preventing configuration conflicts with other JWT libraries (JwtBearer, IdentityServer, OpenIddict).

  • Removed global JwtSecurityTokenHandler singleton registration
  • Implemented factory-based registration for IMiniJwtService with local handler instantiation
  • Added TimeProvider resolution with fallback to TimeProvider.System

Reviewed changes

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

File Description
src/MiniJwt.Core/Extensions/ServiceCollectionExtensions.cs Replaced direct handler registration with factory pattern that creates a local JwtSecurityTokenHandler instance exclusively for MiniJwtService
src/MiniJwt.Tests/MiniJwtTests.Extension.cs Added test to verify JwtSecurityTokenHandler is not globally resolvable while IMiniJwtService remains functional

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jeanlrnt
Copy link
Owner

Update documentation with lasts changes @copilot

Co-authored-by: jeanlrnt <63308635+jeanlrnt@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 26, 2025

Update documentation with lasts changes @copilot

Updated all documentation files to reflect the new factory-based DI registration pattern in commit ac28076.

Changes:

  • README.md: Updated registration examples and unit test sections
  • docs/getting-started.md: Added both DI and manual instantiation examples
  • docs/configuration.md: Updated all configuration methods and multi-tenant examples
  • docs/examples.md: Updated console app and unit testing examples

All examples now show the recommended AddMiniJwt approach while maintaining manual instantiation examples for advanced scenarios.

@jeanlrnt jeanlrnt merged commit b5be0b1 into main Dec 27, 2025
@jeanlrnt jeanlrnt deleted the copilot/refactor-di-registration-jwt branch December 27, 2025 00:03
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.

Refactor DI registration to isolate JwtSecurityTokenHandler

2 participants

Comments