9

I'm using Symfony framework v 2.4.2 to update an existing website which performs a double check to log users in:

  1. first, it checks if the username and password belong to a valid Active Directory user (using PHP's ldap_bind() function);
  2. if so, it checks the username only against a DB table (no password is stored in the DB);
  3. if the username is found in the DB table, the website loads the user profile from DB, and the user is authenticated.

How can I replicate this auth process in Symfony2?

So far, I got stuck with FOSUserBundle and FR3DLdapBundle: I managed to use chained providers (ldap and db), but seemingly LDAP credentials are completely ignored: users can login with the credentials stored in the DB, even if the ldap_bind() fails - which is the exact opposite of points 1 & 2.

Besides, when using FOSUserBundle, it seems to be mandatory to store passwords inside the DB.

Please pay attention to point no. 2: users must be free to change their LDAP password from outside the website (that is, from Active Directory), and then log in with the new credentials- without any update to the website's users database.

Any solution is welcome, I'm not so much in love with FOSUserBundle and even less with FR3DLdapBundle.

2 Answers 2

4

I worked it out like this:

  1. created a custom user entity based on the FOSUSerBundle User model;
  2. created a custom user provider (see Javad answer to this question), registered it as a service and added it to my providers section in app/config/security.yml;
  3. from v2.4 on, Symfony (luckily) offers a simplified authentication system that does not force you to go through all the custom authentication provider stuff (which IMHO was a real pain): it's called Authenticator and it's documented here. I implemented my own Authenticator class and performed the double check using my custom UserProvider class.
Sign up to request clarification or add additional context in comments.

4 Comments

Do you build any option in your solution that if the user is authenticated but does not exists in DB to create an profile for him in DB, too? Or you may not need this; but I am curious
No, not at all: the user must exist in both LDAP and database.
did by any change you can show some code? i have almost the same goal to accomplish. As an added bonus feature i try to SSO via kerberos or NTLM :-)
@Rufinus it's a private project, so I'm not so free to give code references... which part are you interested in?
3

You need to define a CustomUserProvider for LDAP which will find the user in AD and in your security.yml you need to set this provider (Custom User Provider)

providers:
    ldap_provider:
        id: myprovider.security.user.provider   # as you know when you create a custom web service provider you need to define it as a service and use the ID of the service here #

You also need to enable your service in your firewall
Next step is to create custom Authentication Provider for LDAP which authenticate the user and password through LDAP and return the user object from DB (Custom Authentication Provider)

Base on this process first it will try to find user in LDAP if it exists it will continue authenticating through LDAP and if user is authenticated it will return the User Object from DB

Here is a sample for custom user provider

public function loadUserByUsername($username)
{
   $ldap_obj = new adLDAP('exampl.ldapdircetory.com', 'prot', 'Base_DN', 'ldap_admin_user', 'ldap_admin_pass'));
   $filter = "( &(objectclass=person)( |(uid=".$username.")(cn=".$username.")(mail=".$username.") ) )";
   $info = $ldap_obj->search_user($filter);
   if ($info['count'] != 0) {
      // create temp User instance of UserInterface base on the returned info
      $user = new User();
      ...
      return $user
   }
   else {
      throw new UsernameNotFoundException('No match username was found.');
   }

I assume you have adLDAP class to authenticate user(s) through LDAP

2 Comments

Thanks a lot, I've implemented the custom user provider following your directions, and used it in conjunction with FOSUserBundle. Could you be more specific on the second part (return the user object from DB)? I've got an User entity, now how do I authenticate it and load its roles from db?
Sorry for be late answer I was sick; but good news that you yourself found the solution; happy to see that :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.