12

I'm writing an application using Symfony2 which will interface with the Wordnik REST API.

Currently, the Wordnik API does not offer OAuth capabilities, so I have to accept a username and password which I'll then transparently pass to the API interface.

I'd like to integrate this API authentication into Symfony2's security system, but so far I haven't been able to identify what the best implementation route is.

I don't think the custom user provider is correct, because the password is not stored in my system. All examples regarding custom authentication providers seem to pertain to the securing of a part of an application as an API, rather than against a REST API.

It's not clear to me to what extent the FOSUserBundle helps to solve this problem either.

The ideal flow:

  • User provides credentials.
  • Credentials are passed to the 3rd party REST API
  • If the credentials are correct:
    • A corresponding "third party user" Entity is created by my application, if it doesn't exist.
    • The user is authenticated using this "third party user" Entity.

What is the best way to implement this within a Symfony2 security context?

Thanks!

Related Questions:

Community
  • 1
  • 1
Daniel B.
  • 1,650
  • 1
  • 19
  • 40
  • I'm struggling with the same problem. Could you please share your code for how you implemented this? – Steffan Dec 17 '15 at 21:21
  • @Steffan - It's going on 2 years since this code was written, but you can see the provider / token that we wrote here: https://github.com/freen/wordrot/tree/584a7b361ba21eb1cf5303949cb6b3d30eecf687/src/WordRot/PlayBundle/Security/Authentication .... on subsequent commits I removed the PHP backend in favor of trying out a Node backend instead, so that commit is the last state of the PHP. – Daniel B. Dec 18 '15 at 16:10
  • Thx alot, but I found an easier way to do it with the [guard system](https://knpuniversity.com/screencast/guard/login-form) thx to @DevDonkey from [this](http://stackoverflow.com/questions/34376315/symfony2-authenticate-is-not-executed?noredirect=1#comment56501487_34376315) post. – Steffan Dec 20 '15 at 21:15

1 Answers1

4

you have to implement a custom authentication provider as described in: http://symfony.com/doc/current/cookbook/security/custom_authentication_provider.html

I can't tell you what the best way is but just to help you get started: You create a listener, a token, a provider and a factory.

The attemptAuthentication method of the listener takes the credentials provided by the user and creates a new Token with that input. At the end of the method you'll add a: return $this->authenticationManager->authenticate($token);

Your provider will use this token in the authenticate method to send the API request.

For non-existing users you have two options: - create a user in the authenticate method after the API call and after you check whether it already exists which I believe is NOT they way to go - create your own authentication failure handler which is like https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationFailureHandler.php but at the top of the onAuthenticationFailure method you add if ($exception instanceof UsernameNotFoundException && (null !== $token = $exception->getToken()) && $token instanceof YourWordnikToken) { // create that user here }

That's just the basic idea how it works...I'm on IRC with the nickname hacfi - let me know if you need further guidance

hacfi
  • 756
  • 3
  • 7
  • hey hacfi, I don't see you in the channel at the moment :) you can find my app's code here: https://github.com/freen/wordrot ... I'm currently getting this error: `Fatal error: Cannot access parent:: when current class scope has no parent in /[...]/vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Provider/UserAuthenticationProvider.php on line 43` ... It seems like the configuration is slightly off, if it is still trying to use the UserAuthenticationProvider (should be using WordnikProvider) -- Do you see any issues with my implementation? – Daniel B. Feb 20 '13 at 00:40
  • I'll clone the repo to tonight and try to fix it! – hacfi Feb 20 '13 at 14:37
  • Hey Hacfi, thanks for your help! I merged in your pull request, [solved a constructor argument error on the authentication provider](https://github.com/freen/wordrot/commit/0ec3ae9f33bc66fbcdcad668b47de0ee2120d9fe), but I'm still getting the exact same error as before. – Daniel B. Feb 20 '13 at 19:30
  • See pullrequest...next points: - work on the token - add api call to authenticate in the WordnikProvider – hacfi Feb 21 '13 at 01:55
  • The main problem seems to be its continued loading of the DaoAuthenticationProvider. Still looking into it. Thanks for all your help! – Daniel B. Feb 21 '13 at 15:47
  • Why is that a problem? Setup xdebug and see for yourself that at https://github.com/symfony/symfony/blob/v2.1.7/src/Symfony/Component/Security/Http/Firewall.php#L64 it checks Dao first and then yours. Dao is kind of ignored. – hacfi Feb 21 '13 at 20:42
  • 1
    I don't think that's correct - the application seems to load Dao which in turn loads (extends) the UserAuthenticationProvider. [See the full stacktrace.](https://gist.github.com/freen/5006382) However WordnikProvider does not extend that provider, but [directly implements the AuthenticationProviderInterface](https://github.com/freen/wordrot/blob/master/src/WordRot/PlayBundle/Security/Authentication/Provider/WordnikProvider.php). That's why I believe the error is in the configuration of the implementation, and the WordnikProvider is never loaded. – Daniel B. Feb 21 '13 at 21:22
  • If you're still interested in looking into this issue, I opened a new question here: [Symfony2 won't load custom authentication provider, loads DaoAuthenticationProvider](http://stackoverflow.com/questions/15008721/symfony2-wont-load-custom-authentication-provider-loads-daoauthenticationprovi). – Daniel B. Feb 21 '13 at 21:23