markitosgv/JWTRefreshTokenBundle

Symfony 5.4: AbstractRefreshToken deprecated

disstudio opened this issue · 19 comments

Installed v1.0.1

My configuration:

# config/packages/gesdinet_jwt_refresh_token.yaml
gesdinet_jwt_refresh_token:
  ttl: '%jwt.refresh_token_ttl%'
  token_parameter_name: refreshToken

Giving this message:
Since gesdinet/jwt-refresh-token-bundle 1.0: The "Gesdinet\JWTRefreshTokenBundle\Entity\AbstractRefreshToken" class is deprecated, use "Gesdinet\JWTRefreshTokenBundle\Model\AbstractRefreshToken" instead.

Trying manually configure arguments to service:

#config/services.yaml
services:
  gesdinet.jwtrefreshtoken.refresh_token_manager:
    class: Gesdinet\JWTRefreshTokenBundle\Doctrine\RefreshTokenManager
    public: true
    arguments: [ '@doctrine.orm.default_entity_manager', 'Gesdinet\JWTRefreshTokenBundle\Model\AbstractRefreshToken']

results to an error: The class 'Gesdinet\JWTRefreshTokenBundle\Model\AbstractRefreshToken' was not found in the chain configured namespaces App\Entity, ... , Gesdinet\JWTRefreshTokenBundle\\Entity

Same for me

Same for me

Remove controller: gesdinet.jwtrefreshtoken::refresh part in routes.yaml
and you might be missing:
refresh_jwt: ~
in security.yaml, check documentation of new version configs.

Remove controller: gesdinet.jwtrefreshtoken::refresh part in routes.yaml and you might be missing: refresh_jwt: ~ in security.yaml, check documentation of new version configs.

This solution doesn't work, without controller: gesdinet.jwtrefreshtoken::refresh I have 404 error, and refresh_jwt parameter is not valid.
And also I don't see how it could work if class RefreshTokenAuthenticator extends not existent class AbstractGuardAuthenticator

@vandal-kherson I had this problem also, I'm just saying how I fixed it. There is a thread somewhere that if there is controller defined it uses old version of refresh token code, which uses AbstractGuardAuthenticator and if you remove it, then it does not use it. Check if you have added refresh_jwt: ~ in security.yaml. For me it was those 2 steps to fix this issue. Also note that those steps are for v1.0.1 if you use other one version than it might be other issue.

ses old version of refresh token code, which uses AbstractGuardAuthenticator and if you remove it, then it does not use it. Check if you have added refresh_jwt: ~ in security.yaml. For me it was those 2 steps to fix this issue. Also note that those steps are for v1.0.1 if you use other one version than it might be other issue.

How you fix error like "Unable to find the controller for path "/security/token/refresh". The route is wrongly configured."?

Remove controller: gesdinet.jwtrefreshtoken::refresh part in routes.yaml and you might be missing: refresh_jwt: ~ in security.yaml, check documentation of new version configs.

This line is removed:

# config/routes.yaml
gesdinet_jwt_refresh_token:
  path:       /api/token/refresh

api_gesdinet_jwt_refresh_token:
  path:       /api/admin/token/refresh
# config/packages/security.yaml
  firewalls:

    refresh:
      pattern:  ^/api/token/refresh
      provider: entity_provider
      stateless: true
      refresh_jwt: ~

    refresh_admin:
      pattern:  ^/api/admin/token/refresh
      provider: app_admin_provider
      stateless: true
      refresh_jwt: ~

Still the same issue

Same for me @markitosgv is it a regression ?

@vandal-kherson @disstudio @badr-ou

The issue you mention (ie. 404 if the controller: gesdinet.jwtrefreshtoken::refresh is removed from routes.yaml) only occurs on "empty" GET requests without a refresh_token in the request. The route will function correctly when you pass a refresh_token to the route.

For more information, see: #255 (comment)

The proposed fix for this issue is here: #303

The 1.1 release should fix this.

@mbabker, I am afraid not.

I just upgraded to v.1.1.1 - Symfony 5.4 and have the same issue:

My configuration:

/config/packages/security.yaml

  firewalls:
    dev:
        pattern: ^/(_(profiler|wdt)|css|images|js)/
        security: false
    api:
        pattern: ^/api
        stateless: true
        json_login:
            check_path: /api/login_check
            success_handler: lexik_jwt_authentication.handler.authentication_success
            failure_handler: lexik_jwt_authentication.handler.authentication_failure
        custom_authenticators:
            - app.google_login_authenticator
            - App\Security\TokenAuthenticator
        entry_point: App\Security\TokenAuthenticator
        user_checker: App\Security\UserEnabledChecker
        refresh_jwt:
            check_path: /api/token/refresh

/config/routes.yaml

    gesdinet_jwt_refresh_token:
          path: /api/token/refresh

Which error are you getting? There are a few of them mentioned in this issue. The 1.1 release fixed the routing-related quirks when hitting the refresh endpoint without a refresh token (which, with your config, that issue should be gone). It didn't fix the AbstractRefreshToken class deprecation, that one can only be fixed inside your app if you're extending from that class (nothing in the bundle is using that class). And if you're getting the AbstractGuardAuthenticator error, check all of the authenticators your app is using to make sure none of them use the deprecated Security-Guard component (some packages, like this one and the LexikJWTAuthenticationBundle, are still shipping classes extending the deprecated class, but that's not an issue for you as long as you aren't using them).

@BernardA the initial problem was that the refresh_jwt authenticator would only support requests where the refresh_token was available. If it was not available in the request, the authenticator would not support it, and thus things fall back to requiring a controller definition in the route.

That meant an empty GET request would result in a 404 if no controller was set. Even then, without a controller in the route definition, the authenticator worked fine if the refresh_token was set in the request. That issue is fixed in the latest release, by testing for the check_path configuration instead of the presence of a refresh_token.

In your current configuration, does the refresh_jwt authenticator process requests where the refresh_token is set correctly? If that is not the case, it might be that something in your configuration is blocking the refresh_jwt authenticator from triggering at all. Maybe other authenticators trigger before it does.

Also, as you have the route named in your routes.yaml you can configure the check_path with the named route (ie. check_path: gesdinet_jwt_refresh_token)

For reference, my (working) configuration is as follows:

expand configuration
# security.yaml
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        api_docs:
            pattern: ^/api/docs
            stateless: true
        api:
            pattern: ^/api
            stateless: true
            provider: chain_provider
            entry_point: jwt
            jwt: ~
            json_login_ldap:
                service: Symfony\Component\Ldap\Ldap
                dn_string: 'uid={username},%env(resolve:LDAP_BASE_DN)%'
                check_path: api_token_auth
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure
                require_previous_session: false
            refresh_jwt:
                check_path: api_token_refresh
            logout:
                path: api_token_invalidate
# routes.yaml
api_token_auth:
    path: /api/token/auth
    methods: ['POST']

api_token_refresh:
    path: /api/token/refresh
    methods: ['POST']

api_token_invalidate:
    path: /api/token/invalidate
    methods: ['POST']

@mbabker, @Jayfrown Thanks for prompt response. I did not arrive to the point of actually testing it. For the time being I have that deprecation warning on the web profiler.

In no instance am I using that class, so not sure where the deprecation warning is coming from. So when I googled it I ended up here.

Soon as I actually test I will let you know if it works or not.

deprecation Since gesdinet/jwt-refresh-token-bundle 1.0: The "Gesdinet\JWTRefreshTokenBundle\Entity\AbstractRefreshToken" class is deprecated, use "Gesdinet\JWTRefreshTokenBundle\Model\AbstractRefreshToken" instead.

Usually there’s a stack trace with those deprecations, does that show what’s causing it? It sounds like something is loading the file at some point (maybe something in the framework that tries scanning files and automatically configuring stuff), you can ignore that deprecation if you aren’t using the class at all.

Oh yeah, I'm actually getting the same deprecation notice. In my case it seems to be API Platform's ReflectionClassRecursiveIterator which is including all PHP files in given directories (which probably includes all enabled bundles or something), finding all declared classes, and creating a ReflectionClass for all of them.

{▼
  /srv/app/vendor/gesdinet/jwt-refresh-token-bundle/Entity/AbstractRefreshToken.php:16 {▼
    require_once …
    › 
    › trigger_deprecation('gesdinet/jwt-refresh-token-bundle', '1.0', 'The "%s" class is deprecated, use "%s" instead.', AbstractRefreshToken::class, BaseAbstractRefreshToken::class);
    › 
  }
  /srv/app/vendor/api-platform/core/src/Util/ReflectionClassRecursiveIterator.php:49 {▼
    › try {
    ›     require_once $sourceFile;
    › } catch (\Throwable $t) {
    arguments: {▼
      "/srv/app/vendor/gesdinet/jwt-refresh-token-bundle/Entity/AbstractRefreshToken.php"
    }
  }
}

There you have both context and trace:

Screenshot 2022-04-26 at 20 39 44

Hi

There you have both context and trace:

Screenshot 2022-04-26 at 20 39 44

hello, I have the same 

@BernardA @Khatib-Abbas

So it's like I explained above, this happens because API Platform's ReflectionClassRecursiveIterator includes all files inside some given $directories, which ends up loading this deprecated class, even if your app does not use that class directly.

In any case, you can ignore this deprecation warning as it's not triggered by your app code.


A var_dump($directories) spits out the following:

array(2) { [0]=> string(19) "/srv/app/src/Entity" [1]=> string(56) "/srv/app/vendor/gesdinet/jwt-refresh-token-bundle/Entity" } 

It seems to be called here, which uses the api_platform.resource_class_directories argument as per this config, the value of which is set here. The value is based on $config['mapping']['paths'] and $this->getBundlesResourcesPaths(), the latter of which appears to scan all active bundles for an ./Entity directory.

In my case, this bundle is the only one that has this:

❯ ls -lad vendor/*/*/Entity
drwxr-xr-x  5 jayfrown  staff  160 Apr 11 16:46 vendor/gesdinet/jwt-refresh-token-bundle/Entity

I don't think we can do anything about this in 1.x as we can't remove deprecated classes until the next major release.