Giter Club home page Giter Club logo

lexikjwtauthenticationbundle's Introduction

LexikJWTAuthenticationBundle

Latest Stable Version

This bundle provides JWT (Json Web Token) authentication for your Symfony API.

It is compatible (and tested) with PHP > 8.2 and Symfony > 6.4.

Documentation

The bulk of the documentation is stored in the Resources/doc directory of this bundle:

Community Support

Please consider opening a question on StackOverflow using the lexikjwtauthbundle tag, it is the official support platform for this bundle.

Github Issues are dedicated to bug reports and feature requests.

Contributing

See the CONTRIBUTING file.

Sponsoring

Huge thanks to Blackfire and JetBrains for providing this project with free open-source licenses.

Blackfire

If you or your company use this package, please consider sponsoring its maintenance and development.

Upgrading from 1.x

Please see the UPGRADE file.

Credits

License

This bundle is under the MIT license.
For the whole copyright, see the LICENSE file distributed with this source code.

lexikjwtauthenticationbundle's People

Contributors

alborq avatar andreybolonin avatar chalasr avatar clementtalleu avatar dependabot[bot] avatar eerison avatar emmanuelvella avatar endroid avatar fracsi avatar garak avatar gfreeau avatar jaugustin avatar javiereguiluz avatar lashae avatar maxhelias avatar mbabker avatar ogizanagi avatar oliboy50 avatar patrickjde avatar phansys avatar pluk77 avatar quentin-st avatar slashfan avatar spomky avatar sroze avatar stloyd avatar tabbi89 avatar tcardonne avatar theofidry avatar vincentchalamon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lexikjwtauthenticationbundle's Issues

JWT: invalid signature

Hello,

When I paste the token received with the login_check uri in jwt.io, it says that the signature is invalid, is it normal ?

A question regarding the implementation of JWT

Hi lexik,

Thank you for this very useful plugin. As JWT is relatively new I have some many questions regarding the implementation of it.

First, it seems like the original JWT is vulnerable to a replay attack and that an optional jti parameter should be used. Are we implementing it here? (http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-13#section-4.1.7)

Also, it seems like you strongly recommend the use of SSL, however we all know that SSL is relatively slower than normal request due to the overhead, do we have to use SSL in all cases like that?

Also, I'm looking at WSSE, what do you think about it? Is it a good alternative to JWT or should I use JWT?

500 instead of 401/403 with symfony 2.3

Hi,

I try to use this bundle (with the default configuration provided in the README) with Symfony 2.3.13

If I don't provide any token (header or query) I got a 500 error :

message: "A Token was not found in the SecurityContext.",
class: "Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException

If I add anonymous: true in the firewall I got this one :

message: "Full authentication is required to access this resource.",
class: "Symfony\Component\Security\Core\Exception\InsufficientAuthenticationException",

This seems to be related to this issue symfony/symfony#8467

I expect to get a 401 or 403 error and not a 500

Did you get the same behavior ?

Stop symfony setting cookies when stateless=true

According to http://symfony.com/doc/current/book/security.html#stateless-authentication
"If you use a form login, Symfony2 will create a cookie even if you set stateless to true."

I have this bundle setup and working correctly, login check returns a token and it is authenticated later with http basic.

However my login check method sets two cookies in the response which appear unneeded, it appears they are both session cookies.

Set-Cookie: PHPSESSID=q0q004iqsbi35hknqtta0chh60; path=/
Set-Cookie: PHPSESSID=q0q004iqsbi35hknqtta0chh60; path=/

I inspected the session contents, one is completely blank and the other contains:

_sf2_attributes|a:0:{}_sf2_flashes|a:0:{}_sf2_meta|a:3:{s:1:"u";i:1399600707;s:1:"c";i:1399600707;s:1:"l";s:1:"0";}

So it appears to not be required.

The docs mentions that if you use form_login, symfony will set cookies even when stateless is false.

Is there any way to disable this behaviour? I realize symfony was not designed originally for apis and this is a symfony behaviour.

I am currently looking at the security component to see if this behaviour can be changed.

Get a 401 when trying to get url

Hi (me again 😒 ),

I'm having an issue. I get a 401 error when I'm trying to get someting with my angular (iconic) app.

Here is the header :

GET /api/newsfeed HTTP/1.1
Host: acme.local
Connection: keep-alive
Accept: application/json, text/plain, */*
Origin: http://localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.134 Safari/537.36
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXUyJ9.eyJleHAiOjE0Mzc1NjY3OTMsInVzZXJuYW1lIjoiYW5nZWxhQG1haWwuY29tIiwiaWF0IjoiMTQzNzQ4MDM5MyJ9.zQ-HVmtCboibXVMIVBWP9t5oUf2zr_XU2VCIeEJohTZ3MfE2ZciAJv1tS-mjQ3J50SGAVFOMROsF58E5rX7FPJdjtRUU7fEOEWL0qSzlXwnSIsXenX-_Sd2MLxo4_C8rq_4HnQtRLE7sZpZ6oubVr4DoKVkWFm116fUzQL4QP84qdJApIbNXMeWpBbZtBBRqFT9y67dBf7mF_Ml_4EMMEKRU_kuParMOPp3cPuKeU8OWMg5TFj5lq5UweelShkHQskdEPkdlsjDPy5WuLfLjJVJjv-2nMBGOMUpZJ91tfg2FnTOLEUQUmSaPaJ1GxVh3HNjjr2VcPqTyx-dkXQ7WF0V_jSkIyoyOfjfk04FqNx47lsDyyaIxr_hs5CHvblmCt2ObTic-O_k8d9FBuVRJFVjTfrHUvB4NBvv7kwvICg57PbcQaHhFhoWfB7JScpD43cw7GaL4PsDLvcSEdz1Hoajvd6u6AowvtNanjDckVdC1egYWvm0tPgFtmfvqvKOGlV8_mFumRbXaxc-CK1Me5ZbcLsIZw25-z2VZqfekVbHNQqC54fwRBu2kX247Hsjgv0KPOGGmJ4AfLhttv6v4skiDZfhWg_AhvREQcgwkAChcOPUC-bniZmyHzCxofBcRALoMnixIDICRK-bdeD4h4ea5f87E2Xm3gvgLY-OX7V4
Referer: http://localhost/acmeApp/www/login.html
Accept-Encoding: gzip, deflate, sdch
Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4

And the response:

HTTP/1.1 401 Unauthorized
Date: Tue, 21 Jul 2015 12:06:34 GMT
Server: Apache/2.4.4 (Win32) PHP/5.4.16
Vary: Authorization
X-Powered-By: PHP/5.4.16
Set-Cookie: PHPSESSID=5232dq7k06ibkh7gejapc7clc6; path=/
Cache-Control: no-cache
Access-Control-Allow-Origin: http://localhost
Content-Length: 44
Keep-Alive: timeout=5, max=98
Connection: Keep-Alive
Content-Type: application/json

At the start I thought it was a problem with the login, but the header show the authorization token is present. So I've no more idea where to look.

My controller :

<?php

namespace Acme\NewsfeedBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use FOS\RestBundle\Controller\Annotations as FOSRest;
use Acme\NewsfeedBundle\Entity\Newsfeed;

/**
 * ApiController
 *
 * @FOSRest\NamePrefix("api_")
 */
class ApiController extends Controller
{
    /**
     * @throws AccessDeniedException
     * @return array
     */
    public function apiGetNewsfeedAction()
    {
        if (!$this->get('security.context')->isGranted('ROLE_USER')) {
            throw new AccessDeniedException();
        }

        $news = $this->getDoctrine()
                        ->getManager()
                        ->getRepository('AcmeNewsfeedBundle:Newsfeed')
                        ->getNewsfeed($count);

        return $news;
    }
}

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

        login:
            pattern:  ^/api/login
            stateless: true
            anonymous: true
            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:
                    enabled: true
                    prefix:  Bearer
                query_parameter:
                    enabled: true
                    name:    bearer

        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:   ~


    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 }

config.yml

# 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%


fos_rest:
    routing_loader:
        default_format: json
    param_fetcher_listener: true
    body_listener: true
    #disable_csrf_role: ROLE_USER
    body_converter:
        enabled: true
    view:
        view_response_listener: force

nelmio_cors:
    defaults:
        allow_credentials: false
        allow_origin: []
        allow_headers: []
        allow_methods: []
        expose_headers: []
        max_age: 0
    paths:
        '^/api/':
            allow_origin: ['*']
            allow_headers: ['*']
            allow_methods: ['POST', 'PUT', 'GET', 'DELETE']
            max_age: 3600

sensio_framework_extra:
    request: { converters: true }
    view:    { annotations: false }
    router:  { annotations: true }

I've no idea what give you more (code). So let me know.

The eventlistener in the sandbox are optional, no ? Be cause I don"t have them in my project.

Thx

Custom token validation

In addition to the ability to add extra fields to the JWT payload, we should have the ability to customize token validation.

For example, if we add the IP address to the payload, when verifying the token, we should check that the current user IP matches to prevent the case of another user re-using an existing token.

The logic could either go into the JWTEncoder decode method or directly with the namshi jws library.

I'll need to look into this more, but I will be working on this next week.

Overriding JWTProvider

I need to override the JWTProvider class' authenticate function (

public function authenticate(TokenInterface $token)
) to modify the logic as follows:

  1. My user id is stored in a payload field called 'uid' and NOT username.
  2. I need a different function called to load the user, instead of the $this->userProvider->loadUserByUsername (since I am using the uid and some other constraint for finding the user).

The first approach that comes to my mind to achieve the above is creating a new class that extends the JWTProvider and rewriting the class definition for the lexik_jwt_authentication.security.authentication.provider to my own class.

This approach will seem to solve my problem, but the bundle makes such implementation unfriendly as the member variables inside the JWTProvider class are declared as private.

    /**
     * @var UserProviderInterface
     */
    private $userProvider;

    /**
     * @var JWTManager
     */
    private $jwtManager;

Wouldn't it better to declare all such variables across this class and other classes as protected so they are well-extendable? It looks right now I will have to copy paste the entire class logic or at least the constructor and assigning of these member variables.

What's your thoughts on the above?

How execute login after register user?

Hi,
after registration user i would autenticate the user.

In my controller after registration i tried this:

$response = $this->forward(
    'AppBundle:Rest\V1\Security:check',
    array(
        'email' => $user->getEmail(),
        'password' => $user->getPlainPassword(),
    )
);

but i receive this error message:

{
    "code": 500,
    "message": "You must configure the check path to be handled by the firewall using form_login in your security firewall configuration.",
    "errors": null
 }

I think that this isn't the right way to do this.
how can i do?
Thank you so much!

Retrieve User from given Token, from an unsecured path

Hi,

First congrats for this awesome and amazing bundle that I'm currently using for all my WebServices projects.

My little question:
What is the best way to retrieve a user from an unsecured path?

My context:
I have a /api/1/example/{id}.json endpoint, to access an element informations.
This path is unsecured.
I'd like to use an optional token, and retrieve matching user if passed through the Request headers.
The problem is that without passing through the firewall (and so the bundle security listener), my token-user association is not handled.

Any idea about this?

Thank you so much.

Unauthorized when I use entity provider

First of all thank you for this nice bundle 👍
Now I'm stack with this problem : when I use the in_memory provider everything is working fine , but when I change the provider to use a Doctrine entity which implements UserInterface , the login_check passes , I get my token but when I try to access to a secured link I get 401 Unauthorized.

issue

Here you can see the token in the request :
issue2

My config :

security:
    encoders:
        Symfony\Component\Security\Core\User\User: plaintext
        Acme\DemoBundle\Entity\DemoUser: plaintext
        Acme\DemoBundle\Entity\DemoAdmin: plaintext

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

    providers:
        users:
            entity: { class: Acme\DemoBundle\Entity\DemoUser, property: email }
        admins:
            entity: { class: Acme\DemoBundle\Entity\DemoAdmin, property: email }

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

        login_admin:
            pattern:  ^/api/admin/login
            stateless: true
            anonymous: true
            provider: admins
            form_login:
                check_path: /api/admin/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_admin:
            pattern:   ^/api/admin
            stateless: true
            lexik_jwt:
                authorization_header:
                    enabled: true
                    prefix:  Bearer
                query_parameter:
                    enabled: true
                    name:    bearer  
        login:
            pattern:  ^/api/login
            stateless: true
            anonymous: true
            provider: users
            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   
    access_control:
        - { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api/admin, roles: [ ROLE_ADMIN ]}
        - { path: ^/api, roles: IS_AUTHENTICATED_FULLY }

Proper way to add verifications at login

Hi,

I'm using your bundle in a new project, it works perfectly well, but I'm facing a problem :
What's the best way to put additional verifications at login?
I'd like to check if my user has some properties matching a right value before authenticating him.

I think I have to do it before JWT creation, so I tried to extend the JWTProvider and override authenticate method, without success.
Have I to listen to SecurityInteractiveLogin event and add my check logic here ?

I'm quite lost here...

Thanks a lot for your help,
Nicolas

Question about token ttl expiration.

The ttl token, starts to count after the last request and if one request is done the token ttl is renewed? or ttl counts form the last login ?

Thanks

Regards

How to get Token expiration date

Hi,
I am setting the token expiration time in the config file.
Is it possible to get the expiry date of a token, for example in an AuthenticationSuccessListener? I would like to attach this information to my token response.

Thanks for your help,
Uli

Authenticated anonymously not work

Hi man,
good work with this bundle. I cloned and try the sandbox: https://github.com/slashfan/LexikJWTAuthenticationBundleSandbox
but i don't understand why if i change access control setting:

access_control:
    - { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/api/pages, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/api, roles: IS_AUTHENTICATED_FULLY }

and i go to http://localhost:8000/angular-demo/index.html
I continue to see the authentication request.

P.S. in PageController.php (getPagesAction function) i comment these lines:

if (!$this->get('security.context')->isGranted('ROLE_USER')) {
    throw new AccessDeniedException();
}

Thanks

[DX] Better apache authorization header "bug" handling

As mentionned by @arendjantetteroo in a precedent issue #23, Apache server will strip any Authorization header not in a valid HTTP BASIC AUTH format, causing the bundle to be useless in "header mode".

To work around the problem, 3 main approches exists :

  • Add rewrite rules to the VirtualHost (description here) : simple but needs server side intervention
  • Use the apache_request_headers php function to retrieve the original header (description here)

For now I have documented the first solution, but it might not be the most DX-friendly. Adding the logic to extract the original header inside the AuthorizationHeaderTokenExtractor might be simpler for newcomers.

Does anybody have an opinion on this one ? Thanks !

get a 401 when i tried to obtain the token

Hi,

I'm new with symfony, and i have a problem with the framework, I'm using the LexikJWTAuthenticationBundle with the fosuserbundle, and when I try to get the token via the curl -X POST curl -X POST http://test2.local/api/login_check -d _username=anas -d _password=anas or when I try to login via the form I get this json :

{"code":401,"message":"Bad credentials"}

When it works good with the fosuserbundle alone but when i added the LexikJWTAuthenticationBundle, it returns the 401 code.

I think it's due to some bad configuration in my config file so here is my config file:

app/config/config.yml

fos_user:
db_driver: orm # other valid values are 'mongodb', 'couchdb' and 'propel'
firewall_name: api
user_class: StageOCP\UserBundle\Entity\User
registration:
form:
type: acme_user_registration
confirmation:
from_email:
address: ---
sender_name: ---
enabled: true
resetting:
email:
from_email: # Use this node only if you don't want the global email address for the resetting email
address: ---
sender_name: ---
service:
mailer: fos_user.mailer.twig_swift

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%

and here is my routing file:

app/config/routing.yml

fos_user:
resource: "@FOSUserBundle/Resources/config/routing/all.xml"

fos_user_security_check:
path: /api/login_check
defaults: { _controller: FOSUserBundle:Security:check }

fos_js_routing:
resource: "@FOSJsRoutingBundle/Resources/config/routing/routing.xml"

api_login_check:
path: /api/login_check

and here is my security file:

app/config/security.yml

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

role_hierarchy:
    ROLE_ADMIN:       ROLE_USER
    ROLE_SUPER_ADMIN: ROLE_ADMIN

providers:
    fos_userbundle:
                id: fos_user.user_provider.username
    in_memory:
        memory: ~

firewalls:
    login:
        pattern:  ^/login|^/api/login
        provider:  fos_userbundle
        stateless: true
        anonymous: true
        form_login:
            login_path:               fos_user_security_login
            check_path:               fos_user_security_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
        provider:  fos_userbundle
        stateless: true
        anonymous: true
        lexik_jwt:
            authorization_header:
                enabled: true
                prefix:  Bearer
            query_parameter:
                enabled: true
                name:    bearer
    dev:
        pattern: ^/(_(profiler|wdt)|css|images|js)/
        security: false

    main:
        pattern: ^/
        form_login:
            provider: fos_userbundle
            csrf_provider: security.csrf.token_manager # Use form.csrf_provider instead for Symfony <2.4
        logout:       true
        anonymous:    true
        remember_me:
            key:      "%secret%"
            lifetime: 31536000 # 365 jours en secondes

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

and here is my vhost conf :

<VirtualHost *:80>
RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.)
RewriteRule .
- [e=HTTP_AUTHORIZATION:%1]
DocumentRoot "C:\wamp\www\Test2\web"
ServerName test2.local
ServerAlias test2.local
ErrorLog "logs/siteA.localhost-error.log"
CustomLog "logs/siteA.localhost-access.log" common
Alias /sf C:\wamp\www\Test2\lib\vendor\symfony\data\web\sf

Using JWTEncoderInterface to decode a token and ignoring Expired

A lot of APIs using the JWT will need an endpoint that allows developers to refresh the token (say if its expired).

One of the key requirements of building a refresh token endpoint is to be able to decode the existing the token (which will be passed as input), capture important data (like username field, etc) and create a new token out of it with the same data.

Presently using the JWTEncoder's decode function will always return a false if the token has expired. But my use-case requires the need to refresh tokens even if expired. How do I access the payload of a token even after its expired?

Presently, the only way I see it is rewriting the JWTEncoder class and adding a new function like decodeIgnoreExpired($jwt) function.

What are your thoughts?

Packet stability

Hi,
When do you plan to consider this packet as stable and tag it?
I see no open issues...

May I be of any help?

Thank you

POST token in url not body

Hey there nice lib.

It appears that I can't send the token in the POST body, only appended to the url as if it were a GET. Is this true or am I stupid.

Javascript side it would be nice to do something:

  params = {'Bearer':'287hxgbgbd7823hd98hd23d892'}

    $.ajax
        url: 'http://www.myapi.com'
        type: 'POST'
        data: params
        dataType: 'json'

Thanks

Returning a json object onAuthenticationFailure

At the moment, the AuthenticationFailureHandler returns a string 'Bad credentials' in case of an authentication failure, with an application/json content-type.

Would it be possible to return a proper json object instead? Because this is not consistent, especially with the FosRestBundle error code format.

In other words, why not doing

        return new JsonResponse(array(
            'code' => 401,
            'message' => 'Bad credentials'
        ), 401);

instead of

        return new JsonResponse('Bad credentials', 401);

401 - Invalid Credentials (since upgrade to Yosemite)

Hi there,

First of all thank you for a great bundle. I've been using this successfully using my Mac with Mavericks. I believe I was using Apache 2.4.?? and PHP 5.4.?? I originally had the Header stripping issue which I fixed and it was working fine.

I've since upgraded to Yosemite and am using Apache 2.4.9 and PHP 5.5.14 and I'm getting 401 - Invalid Credentials after I request after I've logged in. I am able to log in and retrieve a token. I am then doing my next request, I can see the Authorisation in my request header with the saved token, but I'm getting a 401 returned. In my previous setup this would have worked.

I've also regenerated my SSH keys.

I've tried manually running my API request using DHC for Chrome with the token (which has previous worked) and again still no luck. It's almost as if the token is expiring straight away. I'm not sure how I can debug this issue?

Is there anything you think this could be and any suggestions how I can try and resolve this issue?

Kind regards,
Paul Pounder

Issue with security.yml (authentication_provider)

I'm trying to use this bundle with FOSUser and i'm a bit stuck ..
Authentication works well, i get my token fine.

But I'm having an issue with my security.yml and can't find what..

I used this example to protect my authenticated route (/api) and i'm getting this error trying to call /api/users/me/ :

InvalidConfigurationException: Unrecognized option "authentication_provider" under "security.firewalls.api.lexik_jwt"

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

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: ROLE_ADMIN

    providers:
        fos_userbundle:
            id: myproject_user.user_provider.email


    firewalls:
        api_login:
            pattern: ^/api/users/login
            stateless: true
            anonymous: true
            form_login:
                check_path: /api/users/login
                require_previous_session: false
                username_parameter: email
                password_parameter: password
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure 


        api:
            pattern: ^/api/
            lexik_jwt:
                authorization_header: # check token in Authorization Header
                    enabled: true
                    prefix:  Bearer
                query_parameter:      # check token in query string parameter
                    enabled: true
                    name:    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  


    access_control:
        # - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        # - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
        # - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
        # - { path: ^/admin/, role: ROLE_ADMIN }

The "authentication_provider" seems to be the issue, but I don't know why..

How to manually authenticate a user

Hello,

Is it possible to manually authenticate a user in a method ?

In my api, I have "public" method (no login required) and "private" method (login required).

I tried this, but it is quite ugly.

$extractor = new AuthorizationHeaderTokenExtractor('token');
$requestToken = $extractor->extract($request);

$token = new JWTUserToken();
$token->setRawToken($requestToken);

$authToken = $this->get('security.authentication.manager')->authenticate($token);
$this->get('security.context')->setToken($authToken);

CORS request

Is it possible to bypass firewall on CORS preflight request ? Yhanks

Set token to invalid status

Hi,

I'm french so sorry for my english.
How can I set a token to a invalidat status ?

(En français : Je voudrais que le token devienne invalide quand je le souhaite, est-ce possible ?)

Thanks

How make regular auth and lexikJwt auth side-by-side?

Hi,

My app is using a regular authentication (with FOSUserBundle), and I desire add support to auth on my API with LexikJWT, for authentication of users using others apps connected to my app.

How I make this?

Thk's.

how to use the query parameter ?

hello, i was wondering could you provide an example using the query parameter ?

Because i want to use it, but every time i do a request and pass the token i got a 401 response.
i'm not sure, but i think my problem comes from my firewalls :

    login_api:
        pattern:   /api/login
        stateless: true
        anonymous: true
        provider: entity_users
        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
        logout:
             path: /api/logout

    api:
        pattern:   ^/api
        stateless: true
        lexik_jwt:
            authorization_header: # check token in Authorization Header
                enabled: false
            query_parameter:      # check token in query string parameter
                enabled: true
                name:    token
            throw_exceptions: false     # When an authentication failure occurs, return a 401 response immediately
            create_entry_point: false    # When no authentication details are provided, create a default entry point that returns a 401 response

and this is the way i use the token in the frontend :

                        var fdata = {token:data.token};
                        $.ajax({
                           url : "{{ path('api_homepage') }}",
                           type: "POST",
                            data: fdata,
                           success: function(data, textStatus, jqXHR)
                           {
                               console.log("ok1");
                               console.log(data);
                           },
                           error: function (jqXHR, textStatus, errorThrown)
                           {
                               console.log("ko2");
                           },
                       });

"Bad credentials" after the first login_check

Hi,

I'm trying to use this Bundle with FOSUserBundle.

When I call /api/login_check, the JWT is generated, but if I do it a second call with the same username and the same password I have a :

{
    code: 401
    message: "Bad credentials"
}

And at every call to other api route I have a :

{
    code: 401
    message: "Invalid credentials"
}

I already use this bundle on an other app without FOSUser and it's works fine.

Bad config ? Thanks.

Flexibility to use other secret tokens instead of private key

First of all, thanx for the awesome bundle! One thing I noticed is that tokens can only be signed by using a private key statically stored in a file. I think it would be nice to make this more flexible and allow other types of "secret tokens" to be passed to the encoder.

When using JWT authentication for an API-driven CMS, it would be nice to gain some more control on the generation and invalidation of tokens, on a per-user level. If I want some user's token to become invalid (and force the user to login again) for some reason, I could simply regenerate its "secret token", if it was stored in the database.

This could be solved simply by creating an interface for the encoder and make the encoder configurable.

Please let me know your thoughts on this subject. If you have some other ways of handling this, that's fine also. If you agree with my feedback, I would be happy to contribute. :)

Login using /api/login

Hello,
I want to use your bundle to create a secure API for my iOS app but I don't understand how to get the token using the URL. I configured the bundle as you said but now I don't know what to do...
Can you help me ?
Thanks

PS: I think you are french but I'm not sure

Security vulnerability in namshi/jose

Hi,

This bundle uses "namshi/jose" version ~1.2 (1.2.2 as of April 4), however there's a note on namshi's page:
"Unsecure JWSes are disabled by default since version 2.1.2. You should not use previous versions other than 1.0.2, 1.1.2, 2.0.3 as they have a security vulnerability."
Also, not sure if related or not, but tokens provided by the LexikJWTAuthenticationBundle do not pass verification on jwt.io - says "Invalid Signature".

Thank you!!
D.O.

FOSUser + LexikJWT still returning 401 "Bad Credentials"

Hello,
After reading and trying all fixes found in here trying to get LexikJWT and FOSUser working together, I finally create my own new issue because I could really not find a way, it's still returning 401 "Bad Credentials"...

I need a "backend admin" login (which is working) independent from my API login which will be used in an hybrid app.

Here is my security.yml :

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

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_API:         ROLE_USER
        ROLE_SUPER_ADMIN: ROLE_ADMIN

    providers:
        fos_userbundle:
            id: fos_user.user_provider.username_email

    firewalls:
        admin:
            pattern: ^/admin
            form_login:
                login_path: /admin/login
                check_path: /admin/login_check
                provider: fos_userbundle
                csrf_provider: form.csrf_provider
            logout:
                path:        /admin/logout
                target:      /admin
            anonymous:    true

        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
                require_previous_session: false
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure

        api:
            pattern:   ^/api
            stateless: true
            provider: fos_userbundle
            lexik_jwt:
                authorization_header:
                    enabled: true
                    prefix:  Bearer
                throw_exceptions:        false
                create_entry_point:      true

    access_control:
        - { path: ^/admin/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/, role: ROLE_ADMIN }
        - { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api, roles: [IS_AUTHENTICATED_FULLY, ROLE_API, ROLE_ADMIN] }

If someone has any idea why I cannot manage to get this working, I thank you in advance.

I'm trying using Sandbox's AngularJS implementation and Curl CLI, they both return 401 Bad Credentials..

Anonymous Token?

I am using the JWT token (via data modifiers) to pass additional data like say a unique traceable session id to maintain state across a guest checkout. In this case, authentication is optional and the login token will not have the 'username' field set.

How do I go about achieving the above?

  1. Is there an anonymous token implementation in this bundle?
  2. If I override the JWTProvider's authenticate(..) function, would that suffice? I was thinking of removing the AuthenticationException which is thrown when !isset($payload['username')) and instead doing something here that treats this request as anonymous.

What are your thoughts on this?

[DX] More details about cors and header authorization in readme

After installing this bundle and running into cors issue like 2 other closed issues on your repo (which i missed), it might be nice to add a hint about the cors nelmio bundle in case you run code that uses the jwt but not on your own domain.

Another issue i had is that Apache removed the Authorization header instead of providing it to symfony, so the authorization didn't work. This can be solved by adding some modrewrite rules to the htaccess.
http://stackoverflow.com/questions/11990388/request-headers-bag-is-missing-authorization-header-in-symfony-2

A link to the gfreeau bundle : https://packagist.org/packages/gfreeau/get-jwt-bundle might be nice as well.

Are you interested in a PR to the readme about these issues, so others can more easily and faster use this bundle?

Problème login_check

Bonjour,
J'ai installé LexikJWTAuthenticationBundle en suivant la documentation.

Cependant j'arrive pas à accéder à l'url "api/login_check".

j'ai cette erreur là :
Unable to find the controller for path "/api/login_check". The route is wrongly configured.

C'est là première fois que je met en place un système de token.

security.yml :
firewalls:

    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: ~

access_control:
    - { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/api,       roles: IS_AUTHENTICATED_FULLY } 

Routing.yml :

REST

rest :
type : rest
resource : "routing_rest.yml"
prefix : /api

api_login_check:
path: /api/login_check

Pouvez-vous m'aider, merci.

Change Entry Point ?

Hi,

I would change the body of entry point when the user tries to use a protected API without being authenticated.
The default body is :

{
    "code": 401,
    "message": "Invalid Credentials"
}

To be consistent with other message errors, I would like to have :

{
    "error": {
        "code": 401,
        "message": "Invalid Credentials"
    }
}

Is there a way to do that ?

Thanks,

Vincent

What's the result of going to /api/login?

Hi,
Thanks for creating this bundle. I'm using it with FOSUser, /api/login_check works as expected and returns the JWT when the correct username and password are POSTed.

But what controller action is /api/login (set in the firewalls section of security.yml) supposed to map to? For me it's going to FOSUser's login form which isn't correct for an API, but this is the default FOSUser behaviour, I haven't defined any custom routes for /api/login, do I need to?

Here's my security.yml.

Thanks in advance :)

Get a 404 when i'm trying to login

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

Suggestion for documentation

Recently Ive come up with action to issue new, refreshed token without providing username / password. This may be used to decrease token TTL (which increases security).

  public function refreshAction(Request $request)
    {
        /* @var $token JWTUserToken */
        $token = $this->get('security.context')->getToken();

        //Code to issue new, refreshed JWT token
        /* @var $jwtAuthenticationSuccess AuthenticationSuccessHandler */
        $jwtAuthenticationSuccess = $this->get('lexik_jwt_authentication.handler.authentication_success');
        return $jwtAuthenticationSuccess->onAuthenticationSuccess($request, $token);
    }

You may be interested in adding this to documentation examples.

Unable to find the controller for path /v1/login_check

Hello!

I was following the security.yml in the sandbox application and this bundle. However, I cannot seem to get past this firewall issue.

Symfony version: 2.5.5

security.yml

security:
    encoders:
        Acme\UserBundle\Entity\User:
            algorithm:        sha1
            encode_as_base64: false
            iterations:       10

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

    providers:
        acme_userbundle:
            id: acme_user.provider

    firewalls:

        login:
            pattern:  ^/v1/login
            stateless: true
            anonymous: true
            form_login:
                check_path:               /v1/login_check
                success_handler:          lexik_jwt_authentication.handler.authentication_success
                failure_handler:          lexik_jwt_authentication.handler.authentication_failure
                require_previous_session: false

        api:
            pattern:   ^/v1
            stateless: true
            lexik_jwt: ~

    access_control:
        - { path: ^/v1/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/v1, roles: IS_AUTHENTICATED_FULLY }

app/routing.yml

acme_api:
    resource: "@AcmeAPIBundle/Resources/config/routing.yml"
    prefix:   /v1

src/AcmeAPIBundle/Resources/config/routing.yml

login_check:
    path: /login_check

acme_api_v1:
    type:     rest
    resource: "Acme\APIBundle\Controller\UserController"
    defaults: {_format: json}
    prefix:   /

Thanks!

JWT Token combined simple_preauth

Hi,

we are trying to combine LexikJWT authentication with a api key simple_preauth and are struggling with the configuration.
Can you tell me if it is possible, to have a simple_preauth that is issuing a PreAuthToken in the same firewall as lexik_jwt?

Unauthorized response when toggle Wifi - 3G

Hello I'm developing a Iphone and Android app and I'm working with this bundle to users authentification. Everything works well except when I toggle wifi to 3g or viceversa. After toggle I send the same token but I get 401 response status. I don't know why this happens. Maybe is a CORS problem? Someone have any idea ?

Thank you!

Question: Compatibility/Usage with HWIOAuthBundle

Has anyone tried using this in combination with HWIOAuthBundle? What’s the best way to add Facebook login to a JWT api? Do I have to add a separate firewall for HWIOAuth and create a redirect which create a JWT token?

How should i customize response on Authentification Failure ?

Hi,

I would like to now how to if it is possible to modify the "Bad Credential" response when the authentification failed.

I saw how to modify the success response in your documentation, but not for the failure response.

Thank you in advance

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.