Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalidate a JWT token - Adding the jti claim by the JWTManager class instead of doing it via a listener #1218

Merged
merged 1 commit into from
Apr 27, 2024

Conversation

ldaspt
Copy link
Contributor

@ldaspt ldaspt commented Apr 22, 2024

Hello @chalasr and @mbabker,

This PR aims to address the enhancements suggested by @mbabker in the discussion of the PR #1170.

@see #1170 (comment)

Changes included:

  • Remove AddClaimsToJWTListener
  • Addition of the concept of Payload Enrichment which aims to enrich the payload just before generating the token in the JwtManager class
  • Added a random jti when the JWT token invalidation functionality is enabled
  • Added a null payload enrichment and a chain enrichment (which may be superfluous)

The payload enrichment cannot be overridden via the bundle configuration, if the developer wants to overload it, he will have to decorate the service lexik_jwt_authentication.payload_enrichment. If necessary, I can do as for the lexik_jwt_authentication.encoder service so that this is configurable via the bundle configuration

I hope the PR answers the request correctly

Please review the changes at your convenience, and I welcome any feedback or further suggestions

@mbabker
Copy link
Contributor

mbabker commented Apr 23, 2024

I'd make two changes to this:

  1. Always use the ChainEnrichment as the lexik_jwt_authentication.payload_enrichment service, this way the service definition is stable, and makes the next point easier
  2. Make a service tag for these new enricher services and use a compiler pass to get those tagged services and inject them into the chain; these should support priorities so developers can set them in the order they need using an attribute (i.e. #[Autoconfigure(tags: [['lexik_jwt_authentication.payload_enrichment' => ['priority' => 10]]])]) or through a service definition (i.e. <tag name="lexik_jwt_authentication.payload_enrichment" priority="10" /> in XML), and this will let developers easily add enrichments in their apps/bundles without needing to mess with this bundle's service definitions (be it through adding decorators or remapping the enrichment service to another class entirely)
<?php

namespace Lexik\Bundle\JWTAuthenticationBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class CollectPayloadEnrichmentsPass implements CompilerPassInterface
{
    use PriorityTaggedServiceTrait;

    public function process(ContainerBuilder $container): void
    {
        if (!$container->hasDefinition('lexik_jwt_authentication.payload_enrichment')) {
            return;
        }

        $container->getDefinition('lexik_jwt_authentication.payload_enrichment')
            ->replaceArgument(0, $this->findAndSortTaggedServices('lexik_jwt_authentication.payload_enrichment', $container));
    }
}

With this, I'd then update the service definition for the random JTI enrichment to be this:

<service id="lexik_jwt_authentication.payload_enrichment.random_jti_enrichment" class="Lexik\Bundle\JWTAuthenticationBundle\Services\PayloadEnrichment\RandomJtiEnrichment">
    <tag name="lexik_jwt_authentication.payload_enrichment" priority="0" />
</service>

And update this block in the extension to add an else and remove the tag if the blocklist token feature isn't enabled (which matches the way you're redefining the service now to switch from the null enrichment to the random enrichment), so...

if ($this->isConfigEnabled($container, $config['blocklist_token'])) {
    // Existing code
} else {
    $container->getDefinition('lexik_jwt_authentication.payload_enrichment.random_jti_enrichment')
        ->clearTag('lexik_jwt_authentication.payload_enrichment');
}

@ldaspt
Copy link
Contributor Author

ldaspt commented Apr 26, 2024

@mbabker It's fixed, it's much better, thank you

@@ -174,6 +174,9 @@ public function load(array $configs, ContainerBuilder $container): void
$loader->load('blocklist_token.xml');
$blockListTokenConfig = $config['blocklist_token'];
$container->setAlias('lexik_jwt_authentication.blocklist_token.cache', $blockListTokenConfig['cache']);
} else {
$container->getDefinition('lexik_jwt_authentication.payload_enrichment.random_jti_enrichment')
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If the definition of lexik_jwt_authentication.payload_enrichment.random_jti_enrichment was placed in the Resources/config/blocklist_token.xml file, I feel like this code wouldn't have been necessary

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this can be cleaned up for 3.0 TBH. Things are kind of in a weird state with this stuff because the payload enrichment services should always be there but the bundle right now only needs the JTI enricher to be active when the blocklist functionality is enabled. Always turning on the JTI enricher in 2.x could be disruptive to downstream users for whatever reason, so it's probably safer to have this block for the next 2.x release, and in 3.0, the bundle defaults to always providing the JTI and a downstream app can replace/remove this service if they want to take control over that.

Copy link
Collaborator

@chalasr chalasr left a comment

Choose a reason for hiding this comment

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

Nice

@chalasr chalasr force-pushed the fix-replace-add-claims-listener branch from e405607 to 069b7bb Compare April 27, 2024 15:41
@chalasr
Copy link
Collaborator

chalasr commented Apr 27, 2024

Thank you @ldaspt.

@chalasr chalasr merged commit ed77442 into lexik:2.x Apr 27, 2024
9 checks passed
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.

3 participants