Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trying to catch entered password for an API call #372

Closed
maximebourdel opened this issue Aug 2, 2017 · 8 comments
Closed

Trying to catch entered password for an API call #372

maximebourdel opened this issue Aug 2, 2017 · 8 comments

Comments

@maximebourdel
Copy link

maximebourdel commented Aug 2, 2017

Hello,

I installed LexikJWTAuthenticationBundle and everything is ok thank you for the tool

Now I would like to change my provider and make the check from an external API.

the workflow would be the following :

  • user logging in with his user/pass with a form
  • provider checking the username and password with a post html request thanks to the API
  • if API returns ok we accept the login and generate the token else : bad credential.

right know i know how to make this but i have to enter the password by myself into the provider class (something like $password = 'mypassword'... )

Do you know how could I get the password entered in the LOGIN form and catch it into my UserProvider implementing UserProviderInterface
or even in my WebserviceUser implementing JWTUserInterface ?

I started with this :
https://symfony.com/doc/current/security/custom_provider.html

Thank you in advance.
Cordially

@maximebourdel
Copy link
Author

maximebourdel commented Aug 6, 2017

explanation
it would look like something like this.
The problem is i don't know how to catch that password for a test on my OTHER website

(sorry it is paint cacoo was crashing...)

@maximebourdel
Copy link
Author

I found a solution to catch password,

i had to edit "create" method for Lexik\Bundle\JWTAuthenticationBundle\Services\JWTManager

and add this line ,'password' => $user->getPassword()

so my provider now has its password in payloads.

`
public function create(UserInterface $user)
{
$payload = [
'roles' => $user->getRoles()
,'password' => $user->getPassword()
];
$this->addUserIdentityToPayload($user, $payload);

    $jwtCreatedEvent = new JWTCreatedEvent($payload, $user);
    $this->dispatcher->dispatch(Events::JWT_CREATED, $jwtCreatedEvent);

    $jwtString = $this->jwtEncoder->encode($jwtCreatedEvent->getData());

    $jwtEncodedEvent = new JWTEncodedEvent($jwtString);
    $this->dispatcher->dispatch(Events::JWT_ENCODED, $jwtEncodedEvent);

    return $jwtString;
}

`

And edit the "retrieveUser" method in the class Symfony\Component\Security\Core\Authentication\Provider\DaoAuthenticationProvider

and add this line , ['password' => $token->getCredentials()]

`

protected function retrieveUser($username, UsernamePasswordToken $token)
{
$user = $token->getUser();
if ($user instanceof UserInterface) {
return $user;
}

    try {
        $user = $this->userProvider->loadUserByUsername($username, ['password' => $token->getCredentials()]);

        if (!$user instanceof UserInterface) {
            throw new AuthenticationServiceException('The user provider must return a UserInterface object.');
        }

        return $user;
    } catch (UsernameNotFoundException $e) {
        $e->setUsername($username);
        throw $e;
    } catch (\Exception $e) {
        $e = new AuthenticationServiceException($e->getMessage(), 0, $e);
        $e->setToken($token);
        throw $e;
    }
}`

It works fine but the problem is it is not really good to edit inside vendors.

So i would like to know how i could override those two methods.

@chalasr
Copy link
Collaborator

chalasr commented Aug 11, 2017

Hi @maximebourdel, apologies for my late answer. I would suggest to write your own FormLoginAuthenticator, you should find inspiration in https://knpuniversity.com/screencast/guard/login-form.
Idea is that your custom user provider needs to be aware of username and password, which is not the most common, so you need some custom form login. Guard is the simplest approach for achieving this, and seems perfectly adapted since this is very specific to your project. Your form login authenticator would just gives both keys to the provider.

i had to edit "create" method for Lexik\Bundle\JWTAuthenticationBundle\Services\JWTManager and add this line ,'password' => $user->getPassword()

Putting an hardcoded password in the token payload is not a good idea.
You should rollback, really :)

@maximebourdel
Copy link
Author

Hi @chalasr, thank you for the answer,
I will try to implement it tomorrow :)
But, does that mean i do not need to use LexikJWT ?
Will i still have a token system with this solution ?

@chalasr
Copy link
Collaborator

chalasr commented Aug 11, 2017

Sure, I mean that instead of using the traditional built-in symfony form_login, you need to write some custom logic. Do not hesitate to ask here if you have any doubt when implementing, I'll try to be more reactive.

@maximebourdel
Copy link
Author

Aheum,
Sorry but I asked two questions so I did not understand what you meant by "sure".

What I understand is that i will have to create my own logic with form_login but do i have to uninstall lexik ?

Another thing i did not said is that my own bundle has its own entities.
These entities return json thanks to FOSRestBundle.
I made a route called /api and i want this route to be only reachable by authenticated users.
Is that solution still ok with this system ?

Thank you in advance.

@maximebourdel
Copy link
Author

hum, it seems KnpUGuardBundle is requiered and it is deprecated since 2.8 and i use 3.2 for my project.
can i replace some parts of the tutorial with that part i saw in your git ?
https://github.com/lexik/LexikJWTAuthenticationBundle/blob/8386bd1b83e75aef497e024219ee24978db527d6/Resources/doc/6-extending-jwt-authenticator.md
It looks very similar.

@maximebourdel
Copy link
Author

Hi @chalasr

I made a project apart in symfony 2.8 and managed to create my authentication with this exemple.
But now i would like to move it to my symfony 3.2 initial project.

It looks like after checkCredentials method,
KnpU\Guard\Authenticator\AbstractFormLoginAuthenticator is called
and this is the part i would like to replace.

Do you know how i could replace that call ?

Thank you in advance

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants