7

My Symfony2 custom authentication provider now appears to be working.

User Provider

I almost used the FOSUserBundle but I don't even have email addresses for my users and I don't need the added functionality or complication.

So instead I'm just using the entity provider.

I set my encoder to plaintext because the API client library handles that for me, but alas, another snag: it seems like Users are now being authenticated against these User records.

Before I implemented the entity user provider, my login form gave me valid responses: correct credentials yielded no error, bad credentials resulted in my custom "incorrect user/pass error".

Now, even if I supply credentials I know to be correct, all I get is the error message "Bad credentials," as if I'm implementing the UserAuthenticationProvider, but to the best of my knowledge, I'm not. My custom provider directly implements the AuthenticationProviderInterface.

So at the moment I assume I have incorrectly implemented the entity user provider, such that it is somehow overriding my custom authentication provider. What's the correct way to configure the entity user provider and a custom authentication provider, at the same time?

Files

Relevant section of security.yml

encoders:
    WordRot\PlayBundle\Entity\User: plaintext

providers:
    wordnik_users:
        entity: { class: WordRotPlayBundle:User, property: username }

firewalls:
    wordnik_secured:
        pattern: ^/play
        logout: ~
        anonymous: ~
        # The next line specifies the custom authentication provider:
        wordnik: true 
        form_login:
            provider: wordnik_users
            login_path:  /login
            check_path:  /play_check
            # on success
            always_use_default_target_path: true
            default_target_path: /play

EDIT

This might prove useful. It's a diff on the master branch...

  • From when the custom auth provider (WordnikProvider) still got executed (a473d354)
  • To the most recent commit on the master branch (ddcfeae2), where the auth provider is no longer executed.

EDIT 2

With more break points I discovered:

  1. On login form POST, WordnikProvider#supports is being called with a UsernamePasswordToken, thus returning false.
  2. On login form POST, WordnikListener is constructed but it's other methods (attemptAuthentication, requiresAuthentication) are never called. And yet WordnikFactory#createListener, too, is never called! It's a wonder that the listener is constructed.
  3. However on login_check GET, WordnikListener#requiresAuthentication IS called.
Community
  • 1
  • 1
Daniel B.
  • 1,650
  • 1
  • 19
  • 40
  • 1
    The form_login service pretty much assumes you need a password. So make yourself an encoder which says that no password is fine. That should get you one step further. – Cerad Feb 25 '13 at 20:25
  • Cerad, actually it seems that the problem is coming from the UserAuthenticationProvider, as the "Bad credentials." error suggests. Although its a complete mystery to me why that provider is being loaded! I don't think the encoder is the issue. – Daniel B. Feb 27 '13 at 06:02
  • The AuthProvider load a user via the user provider and then authenticates the user by checking the password using the encoder. If you are not using the form_login service at all then take it out. But it sure seems like /play_check is being handled by the default auth handler. – Cerad Feb 27 '13 at 19:25
  • Ah, then that's the problem! I want play_check to be handled by the custom auth provider! I thought the form_login was simply the generic way of declaring a login block, which used a form, I didn't realize it had implications. If not "form_login", what does one use? – Daniel B. Feb 27 '13 at 19:39
  • 1
    return $this->httpUtils->checkRequestPath($request, '/play'); Change play to play_check in your auth listener. That should kick things off for you. – Cerad Feb 27 '13 at 19:43
  • Good eyes! I made this change, and now neither the user provider (good!), nor the auth provider (still bad) are called when the form is submitted. Xdebug breakpoints don't fire. This is progress, I think. – Daniel B. Feb 27 '13 at 20:11
  • Yep. You are doing all the form login stuff yourself so make the form_login block go away as it just confuses things. I would add the firewall provider key back into your listener and then to the token. Not sure how much that is really needed. Make sure your login form is posting to play_check and not play. die() also works well for tracing this sort of stuff. – Cerad Feb 27 '13 at 20:15
  • I take it back, I was in a detached head at an earlier commit. The user manager is still yielding "Bad credentials." I'm not sure about removing the "form_login" service -- I've been told this is the proper way to go about things. – Daniel B. Feb 27 '13 at 20:25
  • Fair enough. Probably should get whomever told you that to explain how two form login services can coexist for the same firewall and process the same routes. You don't have an entry point in your factory so any time a user tries to access a protected resource then the form_login stuff will kick in. – Cerad Feb 27 '13 at 21:01
  • What exactly do you mean by "entry point in your factory"? – Daniel B. Feb 27 '13 at 21:14
  • Maybe we should move this to chat? The entry point tells the system what to do when an unauthenticated user tries to access a controlled url such as play. It redirects the user to login_path. It's just an example of how having the form_login will interfere with your system once you get it working. – Cerad Feb 27 '13 at 21:31
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/25251/discussion-between-montgomery-jean-and-cerad) – Daniel B. Feb 27 '13 at 21:31
  • But I am assuming that your login form is being displayed. You are entering a user name and password and pressing submit. The form is being submitted to /play_check. At a minimum, change the form_login.check_path to something different so we know it's listener is not grabbing it. Then verify that your listener's attemptAuthentication is being called. – Cerad Feb 27 '13 at 21:34

1 Answers1

1

So we had kind of a long discussion on this. The basic problem was that the form_login services was interfering with the wodnik service. Removed form_login and things started working better.

https://chat.stackoverflow.com/rooms/25251/discussion-between-montgomery-jean-and-cerad

Community
  • 1
  • 1
Cerad
  • 48,157
  • 8
  • 90
  • 92