cnam / security-jwt-service-provider

Silex security jwt service provider (silex 1.x and 2.x version) allow oauth2 header
GNU General Public License v2.0
60 stars 40 forks source link

fail to getUsername() on security.token_storage token #16

Closed soubok closed 8 years ago

soubok commented 8 years ago

Hello,

I try to get the username on a secure route using: $app['security.token_storage']->getToken()->getUsername()

and I get the following error:

PHP Notice:  Undefined property: Silex\Component\Security\Http\Token\JWTToken::$usernameClaim in C:\work\web\nova-backoffice\vendor\cnam\security-jwt-service-provider\src\Silex\Component\Security\Http\Token\JWTToken.php on line 60

Except for the secret_key and header_name, security.jwt configuration use the default settings. The secure routes are defined like this:

    'secure' => array(
        'pattern' => '^.*$',
        'users' => $app['users'],
        'jwt' => array(
            'use_forward' => true,
            'require_previous_session' => false,
            'stateless' => true,
        )           
    ),

Version:

        "doctrine/dbal": "^2.5",
        "silex/silex": "~1.3",
        "symfony/security": "~2.7",
        "cnam/security-jwt-service-provider": "1.*"

Note that $token->setUsernameClaim($this->options['username_claim']); is properly called in JWTListener.php:65

Do you need more details, or there is something obvious I am doing wrong ?

cnam commented 8 years ago

Hello @soubok we fix this bug in version 1.0.6

soubok commented 8 years ago

Thanks, the error does not appear any more, but the getUsername() returns an empty string, should I fill new issue ?

cnam commented 8 years ago

What field your are using for encode token:

$app['security.jwt.encoder']->encode(['name' => $user->getUsername()]);

By default getUsername() from getToken() returns "username" from field "name" .

If your are using custom field in jwt token for send username, your must be configure

$app['security.jwt'] = [
    'options'    => [
        'username_claim' => 'name',
    ]
];
soubok commented 8 years ago

I use the default field (name)

soubok commented 8 years ago

I also noticed that the public function loadUserByUsername($username) of the UserProviderInterface is called with the good value for $username (when my secure route is called)

ps: my $app['security.token_storage']->getToken()->getUsername() returns null, not an empty string

cnam commented 8 years ago

if your need username your must user model and get name from modal.

$token = $app['security.token_storage']->getToken();

if (null !== $token {
        $user = $token->getUser();
        $username = $user->getUsername();
}
soubok commented 8 years ago

thank you, it works!

soubok commented 8 years ago

And now the last issue for today :)

I try to use the secure method of Silex\Route\SecurityTrait (see http://silex.sensiolabs.org/doc/providers/security.html#traits) on my secure route:

$app->get('/admin', function(Request $request) use($app) {

    return $app->json('ok', 200);
})->secure('ROLE_ADMIN');

When I load this route, loadUserByUsername is called twice, once with the right $username and the second time with null

... more simply: I cannot use $app['security.authorization_checker']->isGranted('ROLE_ADMIN') in my route because my loadUserByUsername function get null as $username argument.

cnam commented 8 years ago

Hello, try to use version 1.1.0 we add full capability silex security.

soubok commented 8 years ago

Thanks, it works !