Lexikjwtauthenticationbundle: FOSUserBunder + LexikJWT token storage return null user

Created on 27 Dec 2016  路  7Comments  路  Source: lexik/LexikJWTAuthenticationBundle

Hello, after finally making FOS and Lexik to work together. I face another problem in which $this->get('security.token_storage')->getToken()->getUser() returns null.
I use postman chrome extension to send get request with Authorization header - Bearer [token]
getToken returns an object that contains only token, everything else is null.
onJWTAuthenticated event works (probably as expected) as its event contains both token and correct payload. I tried to debug and found out that everything works until
$token = new JWTUserToken(); $token->setRawToken($requestToken); $authToken = $this->authenticationManager->authenticate($token); $this->tokenStorage->setToken($authToken);
(code snippet from line 92 in JWTListener in Security firewall) in which the authToken is empty.
My config:

  • Security :
security:
    encoders:
        FOS\UserBundle\Model\UserInterface: bcrypt
        # Symfony\Component\Security\Core\User\User: plaintext

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_API:         ROLE_USER
        ROLE_SUPER_ADMIN: ROLE_ADMIN

    providers:
        fos_userbundle:
            id: fos_user.user_provider.username

    firewalls:
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false
        login:
            pattern:  ^/api/login
            stateless: true
            anonymous: true
            provider: fos_userbundle
            form_login:
                check_path:               api_login_check
                username_parameter:       _username
                password_parameter:       _password
                success_handler:          lexik_jwt_authentication.handler.authentication_success
                failure_handler:          lexik_jwt_authentication.handler.authentication_failure
                require_previous_session: false
        api:
            pattern:   ^/api
            stateless: true
            guard:
                authenticators:
                    - lexik_jwt_authentication.jwt_token_authenticator
            lexik_jwt:
                authorization_header:
                    enabled: true
                    prefix:  Bearer
                query_parameter:      
                    enabled: false
                    name:    bearer
                throw_exceptions:        true
                create_entry_point:      false
                authentication_provider: lexik_jwt_authentication.security.authentication.provider
        main:
            pattern: ^/user
            form_login:
                login_path: /user/login
                check_path: /user/login_check
                provider: fos_userbundle
                csrf_token_generator: security.csrf.token_manager
            logout:       true
            anonymous:    true
        refresh:
            pattern:  ^/api/token/refresh
            stateless: true
            anonymous: true
    access_control:
        - { path: ^/user/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/user/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/user/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api/token/refresh, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/, role: ROLE_ADMIN }
        - { path: ^/user , role: ROLE_USER }
        - { path: ^/api , role: IS_AUTHENTICATED_ANONYMOUSLY }
  • Config :
lexik_jwt_authentication:
    private_key_path: %jwt_private_key_path%
    public_key_path:  %jwt_public_key_path%
    pass_phrase:      %jwt_key_pass_phrase%
    token_ttl:        %jwt_token_ttl%
    user_identity_field: username
    token_extractors:
        authorization_header:   
            enabled: true
            prefix:  Bearer
            name:    Authorization
        cookie:        
            enabled: true
            name:    BEARER
        query_parameter:           
            enabled: false
            name:    bearer
    encoder:
        service:            lexik_jwt_authentication.encoder.default
        crypto_engine:  openssl
        signature_algorithm: RS256
fos_user:
    db_driver: orm
    firewall_name: main
    user_class: mhl\UserBundle\Entity\User
    registration:
        confirmation:
            enabled: true
            from_email:
                address:        [email protected]
                sender_name:    webmaster
            template:   FOSUserBundle:Registration:email.txt.twig
    resetting:
        token_ttl: 86400
        email:
            from_email:
                address:        ...
                sender_name:    ...
            template:   FOSUserBundle:Resetting:email.txt.twig
        form:
            type:               FOS\UserBundle\Form\Type\ResettingFormType
            name:               fos_user_resetting_form
    service:
        mailer:             fos_user.mailer.noop

Most helpful comment

Hi @Yanaro,

You're mixing the old and new way to use this bundle, please consider changing from:

        api:
            pattern:   ^/api
            stateless: true
            guard:
                authenticators:
                    - lexik_jwt_authentication.jwt_token_authenticator
            lexik_jwt:
                authorization_header:
                    enabled: true
                    prefix:  Bearer
                query_parameter:      
                    enabled: false
                    name:    bearer
                throw_exceptions:        true
                create_entry_point:      false
                authentication_provider: lexik_jwt_authentication.security.authentication.provider

to:

        api:
            pattern:   ^/api
            stateless: true
            guard:
                authenticators:
                    - lexik_jwt_authentication.jwt_token_authenticator

See the corresponding UPGRADE note: https://github.com/lexik/LexikJWTAuthenticationBundle/blob/master/UPGRADE.md#configuration

Let me know if the issue persists after that

All 7 comments

Hi @Yanaro,

You're mixing the old and new way to use this bundle, please consider changing from:

        api:
            pattern:   ^/api
            stateless: true
            guard:
                authenticators:
                    - lexik_jwt_authentication.jwt_token_authenticator
            lexik_jwt:
                authorization_header:
                    enabled: true
                    prefix:  Bearer
                query_parameter:      
                    enabled: false
                    name:    bearer
                throw_exceptions:        true
                create_entry_point:      false
                authentication_provider: lexik_jwt_authentication.security.authentication.provider

to:

        api:
            pattern:   ^/api
            stateless: true
            guard:
                authenticators:
                    - lexik_jwt_authentication.jwt_token_authenticator

See the corresponding UPGRADE note: https://github.com/lexik/LexikJWTAuthenticationBundle/blob/master/UPGRADE.md#configuration

Let me know if the issue persists after that

Sorry, I never knew that this issue was answered, github failed me I guess. Anyway, I found the way to fix the problem, it's nice the know the reason though.

Hi,
I have a similar problem. When I am running Apache server, I dont get Authentication header as documented; and I switched to symfony's PHP server 127.0.0.1:8000

When I make a POST query to my API (which is not under api root), cause i am unable to configure it for some reason. http://127.0.0.1:8000/app_dev.php/friend/add
friend_follower:
resource: "@FriendFollowerBundle/Controller/"
type: annotation
prefix: /

I receive anonymous user when I try finding the user in controller via:
$user = $this->get('security.token_storage')->getToken()->getUser();

Any, ideas?
config.yml

lexik_jwt_authentication:
private_key_path: '%kernel.root_dir%/../var/jwt/private.pem'
public_key_path: '%kernel.root_dir%/../var/jwt/public.pem'
pass_phrase: 'example'

security.yml

security:
    encoders:
        FOS\UserBundle\Model\UserInterface: bcrypt

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: ROLE_ADMIN

    providers:
        fos_userbundle:
            id: fos_user.user_provider.username_email

    firewalls:
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false

        login:
            pattern:  ^/
            stateless: true
            anonymous: true
            form_login:
                login_path: fos_user_security_login
                provider: fos_userbundle
                check_path: /login_check
                require_previous_session: false
                username_parameter: _username
                password_parameter: _password
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure
            oauth:
                provider: fos_userbundle
                resource_owners:
                    facebook: facebook_login
                    google: google_login
                    linkedin: linkedin_login
                failure_path: app_login
                login_path: app_login
                oauth_user_provider:
                    service: app.provider.oauth
            logout:
                path:   fos_user_security_logout
                target: /

        register:
            pattern:  ^/register
            stateless: true
            anonymous: true

        api:
            pattern:  ^/api
            stateless: true
            anonymous: false
            provider: fos_userbundle
            guard:
                authenticators:
                    - app.jwt_token_authenticator
            lexik_jwt:
                authorization_header: # check token in Authorization Header
                    enabled: true
                    prefix:  Bearer

        refresh:
            pattern:  ^/api/token/refresh
            stateless: true
            anonymous: true

    access_control:
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/login_check$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api/doc, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api/token/refresh, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api/v1, role: IS_AUTHENTICATED_FULLY }
        - { path: ^/admin/, role: ROLE_ADMIN }

@chalasr I successfully got my firewall configured and now routing through api firewall. I have a question that when I send the jwt token in the Authorization header, I dont receive a preauthentication token in JWTTokenAuthenticator.php on line 100.

var_dump looks like:

object(Lexik\Bundle\JWTAuthenticationBundle\Security\Authentication\Token\PreAuthenticationJWTUserToken)#569 (8) {
  ["rawToken":"Lexik\Bundle\JWTAuthenticationBundle\Security\Authentication\Token\PreAuthenticationJWTUserToken":private]=>
  string(835) "eyJhbGciOiJSUzI1NiJ9.eyJyb2xlcyI6WyJST0xFX1VTRVIiXSwidXNlcm5hbWUiOiJwcmFzaGFudC5iYWxhbkBob3RtYWlsLmNvbSIsImlhdCI6MTQ5ODYzNTc0NiwiZXhwIjoxNDk4NjM5MzQ2fQ.i4cjTLaurmNK_wgzjzRsRTHg4HdJR2q9A9bb_CVMETSBavMBQYRmG8DsWT15osqCDli1enaFMquVayTehyYX4aGez0TZtP_hB4U-S3Gxq7lslfzlFr6hDT_3lM3wRXKHiLTMvfwt-pnwfdUZdNB7TdU48NSGTRD8KWmeCjG9ifofPwBwxkKHElt4uA8_M78ksTMTsW4haKIZd_qSF6L0ubnhDWD8f7zZSw4E9rw_JYgbX0LsWedHkAB_9rjWHBAPfu-mw-BFrp8GA-2VyWr8ZbRDf3YTvIpRuqsAeYrXp52aFKxTUI9--tBkfVF1thP45a9y-0pIZ810tfFXZPRlKDK7dx8Jr9B16eT6c0Ea1fw4MC55qBvVFB2fO0bY-ylT3NiodQvYEGeO5VDybdahd1RBBvumRQmYCO4ZPaPe9tH2K46V82gP0t6dOZFipvJkaLWWRRZIiGgRRhvDWRfmne5pnnGiqjxMfPS1vC8cDGfmTIXxCuPJ1CgMhuytLIlr3seFaTG0qXzvr3VI8JF9tJ939T_d6mGDQpiQTjfu5uM2LZUKcWJB0pxTmM170gcG3WnmZ1L0gkqjeCZActtIg9TryYoonErF1atUi-w5rXtjw9q3uKXFLOAbZKZhZG0HqxnshcAkEy663Fo36q5CtpcM3gKkJ9bz26SKzhk8e84"
  ["payload":"Lexik\Bundle\JWTAuthenticationBundle\Security\Authentication\Token\PreAuthenticationJWTUserToken":private]=>
  NULL
  ["credentials":"Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken":private]=>
  NULL
  ["guardProviderKey":"Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken":private]=>
  NULL
  ["user":"Symfony\Component\Security\Core\Authentication\Token\AbstractToken":private]=>
  NULL
  ["roles":"Symfony\Component\Security\Core\Authentication\Token\AbstractToken":private]=>
  array(0) {
  }
  ["authenticated":"Symfony\Component\Security\Core\Authentication\Token\AbstractToken":private]=>
  bool(false)
  ["attributes":"Symfony\Component\Security\Core\Authentication\Token\AbstractToken":private]=>
  array(0) {
  }
}

Do I need to make a change to my User entity?

@pbalan It has been a long time. But from your config I assumed that you were using FOS UserBundle + Lexik + HWIO. Was I right? Would you be that kind to explain to me how did you make them all work?

@denrolya yes, you were right. I had got it to work. And, it's been long time I moved away from Symfony since. Thanks for your response though.

@denrolya I have posted my setup here. https://github.com/pbalan/gbc
Repository doesn't have all the code and may not work out of box. But can serve as a template for the above.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ndoulgeridis picture ndoulgeridis  路  3Comments

kemicofa picture kemicofa  路  5Comments

ghost picture ghost  路  5Comments

rolandrajko picture rolandrajko  路  3Comments

evaldoprestes picture evaldoprestes  路  3Comments