Lexikjwtauthenticationbundle: Get a 404 when i'm trying to login

Created on 10 Jul 2015  路  9Comments  路  Source: lexik/LexikJWTAuthenticationBundle

Hi,
Since 3 days I'm trying to fix it with no success. When I try to login :

curl -X POST http://mysite.local/api/login_check -d _username=johndoe -d _password=test

I get the html code of my 404 page. But when I php app/console router:debug, I see the route

| api_login_check | ANY | ANY | ANY | /api/login_check |
| --- | --- | --- | --- | --- |

I've no idea where's come from. I'm desperate. I don't know what to give you from my code.

My app/config/parameters.yml :

parameters:
    jwt_private_key_path: %kernel.root_dir%/var/jwt/private.pem   # ssh private key path
    jwt_public_key_path:  %kernel.root_dir%/var/jwt/public.pem    # ssh public key path
    jwt_key_pass_phrase:  'test'                                  # ssh key pass phrase
    jwt_token_ttl:        86400

My app/config/routing.yml :

#api login
api_login_check:
   path: /api/login_check

My app/config/config.yml :

# API AUTH JWT
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%

My app/config/security.yml :

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

    role_hierarchy:
        ROLE_MODO:        ROLE_USER
        ROLE_ADMIN:       ROLE_MODO
        ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_MODO, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

    providers:
        fos_userbundle:
            id: fos_user.user_provider.username

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

        main:
            pattern: ^/
            form_login:
                provider: fos_userbundle
                csrf_provider: form.csrf_provider
            logout:       true
            anonymous:    true
            switch_user:  true
            remember_me:
                key:      "%secret%"
                lifetime: 31536000
                path:     /
                domain:   ~

        login:
            pattern:  ^/api/login
            stateless: true
            anonymous: true
            form_login:
                check_path:               /api/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

        api:
            pattern:   ^/api
            stateless: true
            lexik_jwt:
                authorization_header:
                    enabled: true
                    prefix:  Bearer
                query_parameter:
                    enabled: true
                    name:    bearer

    always_authenticate_before_granting: true

    access_control:
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api,       roles: IS_AUTHENTICATED_FULLY }

I took the events listener of your sandbox. Where I just changed the namespace and update my service.yml in my userbundle. I've no idea if there are necessary.

parameters:
#    acme_user.example.class: Acme\UserBundle\Example
    acme_user.event.jwt_response_listener.class: Acme\UserBundle\EventListener\JWTResponseListener
    acme_user.event.jwt_created_listener.class: Acme\UserBundle\EventListener\JWTCreatedListener
    acme_user.event.jwt_decoded_listener.class: Acme\UserBundle\EventListener\JWTDecodedListener


services:
    Acme.twig.user_extension:
        class: Acme\UserBundle\Twig\UserExtension
        tags:
            - { name: twig.extension }
    Acme_user.registration.form.type:
        class: Acme\UserBundle\Form\RegistrationFormType
        arguments: [%fos_user.model.user.class%]
        tags:
            - { name: form.type, alias: Acme_user_registration }
    Acme_user.profile.form.type:
        class: Acme\UserBundle\Form\ProfileFormType
        arguments: [%fos_user.model.user.class%]
        tags:
            - { name: form.type, alias: Acme_user_profile }
    Acme_user.change_password.form.type:
        class: Acme\UserBundle\Form\ChangePasswordFormType
        arguments: [%fos_user.model.user.class%]
        tags:
            - { name: form.type, alias: Acme_user_change_password }
    activity_listener:
        class: Acme\UserBundle\Listener\PageListener
        arguments: [@security.context, @doctrine.orm.entity_manager, @router, @session]
        tags:
            - { name: kernel.event_listener, event: kernel.controller, method: onCoreController }
    acme_user.event.jwt_response_listener:
        class: %acme_user.event.jwt_response_listener.class%
        tags:
            - { name: kernel.event_listener, event: lexik_jwt_authentication.on_authentication_success, method: onAuthenticationSuccessResponse }
    acme_user.event.jwt_created_listener:
        class: %acme_user.event.jwt_created_listener.class%
        tags:
            - { name: kernel.event_listener, event: lexik_jwt_authentication.on_jwt_created, method: onJWTCreated }
    acme_user.event.jwt_decoded_listener:
        class: %acme_user.event.jwt_decoded_listener.class%
        tags:
            - { name: kernel.event_listener, event: lexik_jwt_authentication.on_jwt_decoded, method: onJWTDecoded }

Thx

Most helpful comment

404 and this error message have nothing to do with the bundle, it's related to your security configuration. Move the main firewall declaration block after the api one and it should work (see why : http://stackoverflow.com/a/26665486 and https://test-sf-doc-es.readthedocs.org/en/latest/book/security/authentication.html)

All 9 comments

Hi,

From what I see you have removed the leading _ from the username and password parameters in the form_login configuration of your api login firewall. Can you test using this command : curl -X POST http://localhost:8000/api/login_check -d username=johndoe -d password=test. You should see a response like {"token":"eyJhbGciOiJSUzI1NiIsInR5cCI6Ikp....

Same result, I get the html code of my 404

Are you sure it's a 404 and not a 400 ?

Yes I've only design the 404, 403 and 500. So I'm 100% sure.

I restarted to zero. And follow only the doc and not your sandbox.

  • Symfony 2.6.6
  • FOSUserBundle

I update my composer.json: php ../composer.phar require "lexik/jwt-authentication-bundle"

I update my Kernel: new Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle(),

I create the directories app/var/jwt

I generate the ssh key (with pass phrase _test_)

openssl genrsa -out app/var/jwt/private.pem -aes256 4096
openssl rsa -pubout -in app/var/jwt/private.pem -out app/var/jwt/public.pem

I update my config.yml

imports:
    - { resource: parameters.yml }
    - { resource: security.yml }

framework:
    #esi:             ~
    translator:      { fallback: "%locale%" }
    secret:          "%secret%"
    router:
        resource: "%kernel.root_dir%/config/routing.yml"
        strict_requirements: ~
    form:            ~
    csrf_protection: ~
    validation:      { enable_annotations: true }
    templating:
        engines: ['twig']
        #assets_version: SomeVersionScheme
    default_locale:  "%locale%"
    trusted_hosts:   ~
    trusted_proxies: ~
    session:
        # handler_id set to null will use default session handler from php.ini
        handler_id:  ~
    fragments:       ~
    http_method_override: true

# Twig Configuration
twig:
    debug:            "%kernel.debug%"
    strict_variables: "%kernel.debug%"
    form:
        resources:
            - 'AcmeDefaultBundle:Form:form_row.html.twig'
            - 'AcmeDefaultBundle:Form:form_errors.html.twig'

# Assetic Configuration
assetic:
    debug:          "%kernel.debug%"
    use_controller: false
    bundles:        [ ]
    #java: /usr/bin/java
    filters:
        cssrewrite: ~
        #closure:
        #    jar: "%kernel.root_dir%/Resources/java/compiler.jar"
        #yui_css:
        #    jar: "%kernel.root_dir%/Resources/java/yuicompressor-2.4.7.jar"

# Doctrine Configuration
doctrine:
    dbal:
        driver:   "%database_driver%"
        host:     "%database_host%"
        port:     "%database_port%"
        dbname:   "%database_name%"
        user:     "%database_user%"
        password: "%database_password%"
        charset:  UTF8
        # if using pdo_sqlite as your database driver, add the path in parameters.yml
        # e.g. database_path: "%kernel.root_dir%/data/data.db3"
        # path:     "%database_path%"

    orm:
        auto_generate_proxy_classes: "%kernel.debug%"
        auto_mapping: true

#StofDoctrineExtensionsBundle
stof_doctrine_extensions:
    orm:
        default:
            sluggable: true

# Swiftmailer Configuration
swiftmailer:
    transport: "%mailer_transport%"
    host:      "%mailer_host%"
    username:  "%mailer_user%"
    password:  "%mailer_password%"
    spool:     { type: memory }

# fosUserBundle
fos_user:
    db_driver: orm
    firewall_name: main
    user_class: Acme\UserBundle\Entity\User
    service:
        mailer: fos_user.mailer.twig_swift
    registration:
        form:
            type: Acme_user_registration
        confirmation:
            enabled: true
            template: AcmeUserBundle:Registration:email.html.twig
    resetting:
        email:
            template: AcmeUserBundle:Resetting:email.html.twig
    profile:
        form:
            type: Acme_user_profile
    change_password:
        form:
            type: Acme_user_change_password
    from_email:
        address: [email protected]
        sender_name: Acme

# LiipImagine
liip_imagine:
    resolvers:
        default:
            web_path:
                web_root: %kernel.root_dir%/../web
                cache_prefix: cache
    filter_sets:
        avatar:
            quality: 75
            filters:
                resize_crop_filter: { size: 45 }
                crop: { start: [0, 0], size: [45, 45] }
                strip: ~
        thumb:
            quality: 75
            filters:
                resize_crop_filter: { size: 268 }
                crop: { start: [0, 0], size: [268, 268] }
                strip: ~
# Time ago
knp_time: ~ 

# JWT AUTH (API)
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%

I update my parameters.yml

parameters:
    database_driver: pdo_mysql
    database_host: 127.0.0.1
    database_port: null
    database_name: acme
    database_user: root
    database_password: null
    mailer_transport: mail
    mailer_host: 127.0.0.1
    mailer_user: null
    mailer_password: null
    locale: fr
    secret: '__________secret____________'
    jwt_private_key_path: %kernel.root_dir%/var/jwt/private.pem   # ssh private key path
    jwt_public_key_path:  %kernel.root_dir%/var/jwt/public.pem    # ssh public key path
    jwt_key_pass_phrase:  'test'                                      # ssh key pass phrase
    jwt_token_ttl:        86400

I update my security.yml

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

    role_hierarchy:
        ROLE_MODO:        ROLE_USER
        ROLE_ADMIN:       ROLE_MODO
        ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_MODO, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

    providers:
        fos_userbundle:
            id: fos_user.user_provider.username

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

        main:
            pattern: ^/
            form_login:
                provider: fos_userbundle
                csrf_provider: form.csrf_provider
            logout:       true
            anonymous:    true
            switch_user:  true
            remember_me:
                key:      "%secret%"
                lifetime: 31536000
                path:     /
                domain:   ~
        login:
            pattern:  ^/api/login
            stateless: true
            anonymous: true
            form_login:
                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
        api:
            pattern:   ^/api
            stateless: true
            lexik_jwt: ~


    always_authenticate_before_granting: true

    access_control:
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api,       roles: IS_AUTHENTICATED_FULLY }

I update my routing.yml

// All other bundle routing
acme_user:
    resource: "@AcmeUserBundle/Resources/config/routing.yml"
    prefix:   /

# USER ROUTE
fos_user_security:
    resource: "@FOSUserBundle/Resources/config/routing/security.xml"

fos_user_profile:
    resource: "@FOSUserBundle/Resources/config/routing/profile.xml"
    prefix: /profil

fos_user_register:
    resource: "@FOSUserBundle/Resources/config/routing/registration.xml"
    prefix: /inscription

fos_user_resetting:
    resource: "@FOSUserBundle/Resources/config/routing/resetting.xml"
    prefix: /reset

fos_user_change_password:
    resource: "@FOSUserBundle/Resources/config/routing/change_password.xml"
    prefix: /profil

# Imagine
_imagine:
    resource: .
    type:     imagine

# Api login
api_login_check:
   path: /api/login_check

I flush the cache and :

 curl -X POST http://my-site.local/app_dev.php/api/login_check -d _username=johndoe -d _password=test

I get:

Unable to find the controller for path "/api/login_check". The route is wrongly configured.

404 Not Found - NotFoundHttpException

That's the minimum to do, no ?

404 and this error message have nothing to do with the bundle, it's related to your security configuration. Move the main firewall declaration block after the api one and it should work (see why : http://stackoverflow.com/a/26665486 and https://test-sf-doc-es.readthedocs.org/en/latest/book/security/authentication.html)

Ooooooooh god it's working. Many many many many thanks for your bundle and your support :heart: .

No problem :)

when i try runnig any thing in the console i get this error :

[Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException]
You have requested a non-existent parameter "jwt_private_key_path".

Was this page helpful?
0 / 5 - 0 ratings