Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lexik JWT returns 401 Unauthorized

I am using LexikJWTBundle for a RESTful API.

Login works just fine and I get my token. But when I make a GET request I get a 401 with no content. The Authorization header seems ok since I get this in the profiler: Request Headers: authorization: Bearer {token} Request Server Parameters: HTTP_AUTHORIZATION: Bearer {token}

The 401 I get is from: https://github.com/lexik/LexikJWTAuthenticationBundle/blob/master/Security/Firewall/JWTListener.php#L80

I've tried different solutions but still it's not working.

Would you have any idea on how to resolve/debug this?

My config:

# config.yml
...

lexik_jwt_authentication:
    private_key_path: %kernel.root_dir%/var/jwt/private.pem   # ssh private key path
    public_key_path:  %kernel.root_dir%/var/jwt/public.pem    # ssh public key path
    pass_phrase:      'TEST'                                      # ssh key pass phrase
    token_ttl:        86400                                   # token ttl - defaults to 86400

And

# security.yml

security:
role_hierarchy:
    ROLE_SUPER_ADMIN:       [ROLE_ADMIN, ROLE_SONATA_ADMIN, ROLE_ALLOWED_TO_SWITCH]
# http://sonata-project.org/bundles/admin/2-3/doc/reference/security.html
# set access_strategy to unanimous, else you may have unexpected behaviors
access_decision_manager:
    strategy: unanimous

encoders:
    FOS\UserBundle\Model\UserInterface: sha512

providers:
    fos_userbundle:
        id: fos_user.user_provider.username_email

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

    api_login:
        pattern: ^/api/login # Default: .*
        provider: fos_userbundle

        # form login
        form_login:
            login_path:     fos_user_security_login
            # csrf_provider: form.csrf_provider # Default: my.csrf_provider.id
            # LexikJWT # 09/01/15 - Note: provient de la configuration officielle.
            check_path:     api_login_check
            success_handler:          lexik_jwt_authentication.handler.authentication_success
            failure_handler:          lexik_jwt_authentication.handler.authentication_failure
            require_previous_session: false 
        anonymous: true # Default: ~

    api:
        pattern:   ^/api
        stateless: true
        lexik_jwt:
            authorization_header: # check token in Authorization Header
                enabled: true
                prefix:  Bearer
        anonymous: true

access_control:
    # Secured part of the site
    # This config requires being logged for the whole site and having the admin role for the admin part.
    # Change these rules to adapt them to your needs
    - { path: "^/api/contacts$", roles: IS_AUTHENTICATED_ANONYMOUSLY, methods: [POST] }
    - { path: "^/api/users/dt$", roles: IS_AUTHENTICATED_ANONYMOUSLY, methods: [GET] }
    - { path: "^/api/users$", roles: IS_AUTHENTICATED_ANONYMOUSLY, methods: [POST] }
    - { path: "^/api",       roles: [IS_AUTHENTICATED_FULLY, ROLE_API] }
like image 627
Xavier13 Avatar asked Jan 15 '15 10:01

Xavier13


People also ask

What is JWT verify?

JSON Web TokensEach JWT is cryptographically signed, so it's easy to verify that it is legitimate. An API user can't just make up their own JWT and use it to access the API because that user won't have access to the secret key used to generate the correct JWT signature. JWTs contain three parts: header. payload.

What is JWT token in node JS?

JWTs are mainly used for authentication. After a user signs in to an application, the application then assigns JWT to that user. Subsequent requests by the user will include the assigned JWT. This token tells the server what routes, services, and resources the user is allowed to access.

How do I save a JWT token in cookie NodeJS?

First we will create our jwt and then we will store it in a cookie called "access_token". The cookie will have some options, such as httpOnly (to be used during the development of the application) and secure (to be used during the production environment, with https).


2 Answers

I just found a solution on the same problem

Here my security.yml

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

    login:
        pattern:  ^/api/login
        stateless: true
        anonymous: true
        provider:   user_db
        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
        lexik_jwt:
            authorization_header: # check token in Authorization Header
                enabled: true
                prefix:  Bearer
            throw_exceptions:        false     # When an authentication failure occurs, return a 401 response immediately
            create_entry_point:      true      # When no authentication details are provided, create a default entry point that returns a 401 response
            authentication_provider: lexik_jwt_authentication.security.authentication.provider

My problem was the username and the password parameters. I change "username" by "_username" and "password" by "_password"

like image 147
Crossmax Avatar answered Oct 15 '22 17:10

Crossmax


You should add the ROLE_API in the role_hierarchy of your security.yml :

role_hierarchy:
    # ...
    ROLE_API: [ROLE_USER]

Then, users ranked with ROLE_API can access routes restricted to IS_AUTHENTICATED_FULLY.

Also, if you are using a web server, try to use your application using the built-in server (i.e. app/console server:run).

Apache seems to modify the token in headers.

like image 30
chalasr Avatar answered Oct 15 '22 15:10

chalasr