Back

Laravel and LDAP


I'm still relatively new to Laravel and I'm trying to work out how I can accomplish the following.

I need to authenticate my users against LDAP; After successful authenticating, I need to check a secondary database to see if they have a "profile" setup yet. If they do have a profile, then I want them to be directed to the standard dashboard. If they don't have a profile, I want to direct them to a different page letting them know an email has been sent to me to setup their account.

Can anyone help me with the first two parts? I don't know where to start with the ldap authentication and the secondary database profile lookup.

PrettyHotProgrammer replied 3 years ago

Hi,

I recently faced the same issue in regards to LDAP authentication. I tried a few packages and found the solution in https://github.com/dsdevbe/ldap-connector That said, it only currently supports 4.1.x. Not sure if/when they'll add 4.2 support. After following the directions on the github page I can authenticate against Active Directory.

For the second part, you can have a users table that uses the username or email to check against once the user has logged in via LDAP successfully. If they're in the users table they have a profile, if they're not redirect them to create one.

barryvdh replied 3 years ago

You can make a Pull Request to make it work on 4.2 if you want.

IanSirkit replied 3 years ago

I actually had a hard time with ldap-connector but I may have implemented it wrong.

I ended up getting it going by integrating a PHP extension called ADLDAP

If you need I can post you some of my working code.

qwertytech replied 3 years ago

Thanks for all of the responses. I'm about to be working on the project full time so I will definitely be checking out everything y'all recommended.

@IanSirkit - If I can't get the LDAP-Connector to work, I will let you know.

KuenzelIT replied 3 years ago

I also ended up with ADLDAP when looking for a ldap-solution: http://adldap.sourceforge.net/

Other solutions weren't supported anymore or lacked in functionalities.

qwertytech replied 3 years ago

IanSirkit said:

I actually had a hard time with ldap-connector but I may have implemented it wrong.

I ended up getting it going by integrating a PHP extension called ADLDAP

If you need I can post you some of my working code.

After looking around I've decided to use adLDAP. Could you possibly share anything that you can.

IanSirkit replied 3 years ago

Hey qwerty,

The first thing I did was use a really basic adLDAP connection to make sure I could talk to the LDAP server.

You will want to have a user on the LDAP server with permissions to query all the dc ou cn paths. The way adLDAP works is you log into the LDAP server with an Admin account and use it to authenticate users.

I did this just to make sure/sanity check that I could connect to the LDAP server using adLDAP in plain PHP..

<?php

$ldapConn = ldap_connect('dc-1-dc1.example.ca');
           
// Set some ldap options for talking to AD
ldap_set_option($ldapConn, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldapConn, LDAP_OPT_REFERRALS, 0);
    
//this is the LDAP admin account with access
$adminUsername = [email protected]';
$adminPassword = 'strongpass';


// Bind as a domain admin if they've set it up
$ldap_bind = ldap_bind($ldapConn, $adminUsername, $adminPassword);

//example path for searching
$search = ldap_search($ldapConn, "cn=Example Staff,ou=Groups,ou=Staff,ou=Domain Objects,dc=example,dc=ca", "(cn=*)");

//example get command
$info = ldap_get_entries($ldapConn, $search);

echo 'ldap conn';
var_dump($ldapConn);

echo 'ldap bind';
var_dump($ldap_bind);

echo 'seach var';
var_dump($search);

echo 'search info';
var_dump($info);

ldap_unbind($ldapConn);

Once you have that working, you know you can connect and can move into Laravel. I created a authenticate user method in a controller


//I added a route my login form posts to 

Route::post('authenticate_user', array('as'=>'auth_user', 'uses'=>[email protected]'));

// login function
class HomeController extends BaseController {

public function authenticateUser()
{
	include (app_path() . "/lib/adldap/adLDAP.php");
	$adldap = new adldap\adLDAP();

	//get username from form
	$username = Input::get('username');

	//check if username/password passes auth
    if ( $adldap->authenticate($username, Input::get('password') ) )
    {
    	//I have an extra check to see if the user loggin in is in our staff ou... this allows me to identify staff over regular AD users.
    	if($adldap->user()->inGroup($username,"SIRKit Staff")) {
    		$ldap_user_info = $adldap->user()->info($username);
    		$ldap_user_name = $ldap_user_info[0]["displayname"][0];

    		//to take advantage of laravel's user object I add the user to the database of my app if they don't already exist. Adding them to my DB won't allow them to login as the auth method checks LDAP but it allows you to use the model

    		//check for user and create user object
    		$docs_user = User::find($username);
    		//if doesn't exist yet add them
    		if(!$docs_user) {
        		$user = new User;
        		$user->id = $username;
        		$user->name = $ldap_user_name;
        		$user->username = $username;
        		$user->email = $ldap_user_info[0]["mail"][0];
        		$user->save();
        		$docs_user = User::find($username);
    		}
    		//log user in
    		Auth::login($docs_user);
    		//redirect
    		return Redirect::intended('home')->with('message', 'Login Success');
    	}
        
    }
    //login failed
    return Redirect::route('home')->with('message', 'Login Failed <br /> Please Try Again');

}

If you have any questions please ask, I hope this gets you where you need to be.

qwertytech replied 3 years ago

Ian,

I hope I don't sound like a total idiot but I'm a little lost.

I looked at the base example on their site and I didn't know where to put your code above int it.

<?php
     require_once(dirname(__FILE__) .'/adLDAP.php');

     try {
         $adldap = new adLDAP();
     } catch (adLDAPException $e) {
          echo $e;
          exit;
     }
?>

Second degree of difficulty is that I'm setting this all up under IIS. My SysAdmin won't allow any other web servers.

IanSirkit replied 3 years ago

hey qwerty

No sweat, I might not have fully explained what everything I posted was.

The first thing you want to do is set up a test_conn.php file on the server... outside of laravel, just a stand alone script you can hit from a browser.

Use the the first block of code that I posted for this stand alone PHP page. The reason for the first stand alone script is I found when I was setting everything up directly in Laravel that there were a bunch of issues with connecting to the LDAP server. It was easier to debug in a simple script. This way when you move the code over to Laravel you can be sure that any errors aren't a result of not being able to connect to the LDAP server as we will make sure that is working first with this script.

Basically the first block of code I posted is a proof of concept to make sure your webserver can talk to your LDAP that way we don't have to wonder if future problems are connection issues not code issues.

Can you try the first block in a php script and see if you can get a connection to your LDAP server? Once you get that working I can walk you through getting it into laravel. Keep asking if you have questions, sometimes I think I am being clear and I am not

delsdog replied 2 years ago

Hey @IanSirkit, that code was really helpful, thanks.

I'd like to know if I have to have a Users model (and table) at all? I've currently got Login::auth working as per your description, but I don't run the ->save on the object. If I then output Auth::user() I get the authenticated user as expected, when I then add a redirect to any other page and try checking Auth::user() again only to find that it's null.

Could this be because I am not using a model for the users?

I've checked the cookies being generated and can't see one being generated on login (my other apps do have one, but then they have user models as well)

Any help would be greatly appreciated.

IanSirkit replied 2 years ago

Hey Del,

I'm glad it helped. I ran into the exact same issue, my solution was to create a user in the database, I don't store a password, and the details for the account I grab from the LDAP auth. Eg, email.

I spent a lot of time trying to create a user model in memory with sessions and I got close but gave in because of time and just created the table.... Now I am really glad I did. In my app I started recording "updatedBy" and some other user tracking. These requirements came later and having the usernames to lookup in my DB made things more friendly.

When a user logs in I check to see if they exist in the database already, if they do I just grab that user model and log them in. If they don't exist I create them.

It looks like this: (Something I haven't added yet is checking to see if their email has changed on their AD account and updating the user table)

if ( $adldap->authenticate($username, Input::get('password') ) )
        {
        	if($adldap->user()->inGroup($username,"Company Staff")) {
        		$ldap_user_info = $adldap->user()->info($username);
        		$ldap_user_name = $ldap_user_info[0]["displayname"][0];
        		$docs_user = User::find($username);
        		if(!$docs_user) {
	        		$user = new User;
	        		$user->id = $username;
	        		$user->name = $ldap_user_name;
	        		$user->username = $username;
	        		$user->email = $ldap_user_info[0]["mail"][0];
	        		$user->save();
	        		$docs_user = User::find($username);
        		}
        		Auth::login($docs_user);
        		return Redirect::intended('home')->with('message', 'Login Success');
        	}
        }
qwertytech replied 2 years ago

Hi @IanSirkit,

Sorry I haven't replied sooner. I got pulled into a different project that had to be completed before this on.

I've followed your example pretty well except for one part.

include (app_path() . "/lib/adldap/adLDAP.php");

Where is this file actually stored?

rameezrami replied 1 year ago

i am also new to laravel and LDAP, i have tried the basic code without including class to controller and is working but the problem is when i use the second code ie when including the lib file it shows an error " Class 'Adldap\Interfaces\ConnectionInterface' not found ".

i have the full ldap class and folders in "app/lib/adldap/" so the main class file in "app/lib/adldap/Adldap.php" .

can u plz check this?

rameezrami replied 1 year ago

hi all, i made it out... problem was i didn't inform laravel where to look for the class file for the namespace "Adldap" .

in composer .json

    "psr-4": {
        "Adldap\\": "app/lib/Adldap"
    },
riskinovitasari replied 1 month ago

Sorry before, but I do not know where to start asking to get the answer I need. Then i saw the question asked by @qwertytech two years ago. Right now I need the same thing as he asked in the forum. I have to authenticate the user who is logged in the server ldap and also in the database that I have. However, i found a constraint. Firstly, I can not register a new account and get an error message (BadMethodCallException in Validator.php line 1067: The second [validateUsername] does not exist.) Method, I can only login using one account only. So when I login with another account, I get an error message (BindException in Guard.php line 80: Can not contact LDAP server). For the number two constraint, I'm sure I made a mistake in the ldap.php script but I still do not know how to fix it. I hope you guys can help me. thanks before.


Sign in to participate in this thread!



We'd like to thank these amazing companies for supporting us