Be aware that you need so setup an account that can be used for lookups. It should be in the config. If it still does not work, I can post my settings that works with AD
Adldap2-Laravel with Windows Active Directory
Hi Laravel Gurus,
I'm new to LDAP and for a project, the requirement is to use username instead of email for authentication. For username authentication i need to connect to the company's active directory.
I tried this https://github.com/jotaelesalinas/laravel-simple-ldap-auth which works perfectly as the way it should with OpenLDAP, but when i am trying the same with the company's Active Directory using my credentials it throws error "Invalid Credentials". There is no issue with the credentials, I'm able to connect using AD Explorer (LDAP Browser).
Does anyone know what needs to be configured differently? Do I need to change something to connect to Active Directory? Is it something to do with the structure of the directory?
PLEASE HELP!!!
Thanks
@sinnbeck Here is my working code setup what I have, I tried all I could:
.env (ldap variables)
LDAP_HOSTS=xxx.xxx.xx.xx // to be replaced
LDAP_BASE_DN="DC=example,DC=com" // to be replaced
LDAP_USER_ATTRIBUTE=samaccountname
LDAP_USER_FORMAT=%[email protected] // to be replaced
LDAP_CONNECTION=default
LDAP_USERNAME=username // to be replaced with admin or user with lookup permission
LDAP_PASSWORD=password
config\auth.php
...
'providers' => [
'users' => [
'driver' => 'ldap', // was 'eloquent'
'model' => App\User::class,
],
],
...
ldap.php // don't have change anything
<?php
return [
'logging' => env('LDAP_LOGGING', false),
'connections' => [
'default' => [
'auto_connect' => env('LDAP_AUTO_CONNECT', false),
'connection' => Adldap\Connections\Ldap::class,
'settings' => [
'schema' => Adldap\Schemas\ActiveDirectory::class,
'account_prefix' => env('LDAP_ACCOUNT_PREFIX', ''),
'account_suffix' => env('LDAP_ACCOUNT_SUFFIX', ''),
'hosts' => explode(' ', env('LDAP_HOSTS', 'corp-dc1.corp.acme.org corp-dc2.corp.acme.org')),
'port' => env('LDAP_PORT', 389),
'timeout' => env('LDAP_TIMEOUT', 5),
'base_dn' => env('LDAP_BASE_DN', 'ou=corp,dc=acme,dc=org'),
'username' => env('LDAP_USERNAME', ''),
'password' => env('LDAP_PASSWORD', ''),
'follow_referrals' => env('LDAP_FOLLOW_REFERRALS', false),
'use_ssl' => env('LDAP_USE_SSL', false),
'use_tls' => env('LDAP_USE_TLS', false),
],
],
],
];
ldap_auth.php
<?php
return [
'connection' => env('LDAP_CONNECTION', 'default'),
// Yes, I am using DatabaseUserProvider cause my users table has items related to
'provider' => Adldap\Laravel\Auth\DatabaseUserProvider::class,
'model' => App\User::class,
'rules' => [
Adldap\Laravel\Validation\Rules\DenyTrashed::class,
],
'scopes' => [
],
'identifiers' => [
'ldap' => [
'locate_users_by' => 'sAMAccountName',
'bind_users_by' => 'distinguishedname',
],
'database' => [
'guid_column' => 'objectguid',
'username_column' => 'username',
],
'windows' => [
'locate_users_by' => 'sAMAccountName',
'server_key' => 'AUTH_USER',
],
],
'passwords' => [
'sync' => env('LDAP_PASSWORD_SYNC', false),
'column' => 'password',
],
'login_fallback' => env('LDAP_LOGIN_FALLBACK', false),
'sync_attributes' => [
'name' => 'cn',
'email' => 'userPrincipalName',
'username' => 'sAMAccountName',
],
'logging' => [
'enabled' => env('LDAP_LOGGING', true),
'events' => [
\Adldap\Laravel\Events\Importing::class => \Adldap\Laravel\Listeners\LogImport::class,
\Adldap\Laravel\Events\Synchronized::class => \Adldap\Laravel\Listeners\LogSynchronized::class,
\Adldap\Laravel\Events\Synchronizing::class => \Adldap\Laravel\Listeners\LogSynchronizing::class,
\Adldap\Laravel\Events\Authenticated::class => \Adldap\Laravel\Listeners\LogAuthenticated::class,
\Adldap\Laravel\Events\Authenticating::class => \Adldap\Laravel\Listeners\LogAuthentication::class,
\Adldap\Laravel\Events\AuthenticationFailed::class => \Adldap\Laravel\Listeners\LogAuthenticationFailure::class,
\Adldap\Laravel\Events\AuthenticationRejected::class => \Adldap\Laravel\Listeners\LogAuthenticationRejection::class,
\Adldap\Laravel\Events\AuthenticationSuccessful::class => \Adldap\Laravel\Listeners\LogAuthenticationSuccess::class,
\Adldap\Laravel\Events\DiscoveredWithCredentials::class => \Adldap\Laravel\Listeners\LogDiscovery::class,
\Adldap\Laravel\Events\AuthenticatedWithWindows::class => \Adldap\Laravel\Listeners\LogWindowsAuth::class,
\Adldap\Laravel\Events\AuthenticatedModelTrashed::class => \Adldap\Laravel\Listeners\LogTrashedModel::class,
],
],
];
Auth\LoginController.php
<?php
namespace App\Http\Controllers\Auth;
use Illuminate\Http\Request;
use Adldap\Laravel\Facades\Adldap;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
use AuthenticatesUsers;
protected $redirectTo = '/home';
public function __construct()
{
$this->middleware('guest')->except('logout');
}
public function username()
{
return 'username';
}
protected function validateLogin(Request $request)
{
$this->validate($request, [
$this->username() => 'required|string|regex:/^[A-Za-z]+\.[A-Za-z]+$/',
'password' => 'required|string',
]);
}
protected function attemptLogin(Request $request)
{
$credentials = $request->only($this->username(), 'password');
$username = $credentials[$this->username()];
$password = $credentials['password'];
$user_format = env('LDAP_USER_FORMAT');
$userdn = sprintf($user_format, $username);
if (Adldap::auth()->attempt($userdn, $password, $bindAsUser = true)) {
$user = \App\User::where($this->username(), $username)->first();
if (!$user) {
$user = new \App\User();
$user->username = $username;
$user->password = '';
$sync_attrs = $this->retrieveSyncAttributes($username);
foreach ($sync_attrs as $field => $value) {
$user->$field = $value !== null ? $value : '';
}
}
$this->guard()->login($user, true);
return true;
}
// the user doesn't exist in the LDAP server or the password is wrong
// log error
return false;
}
protected function retrieveSyncAttributes($username)
{
$ldapuser = Adldap::search()->where(env('LDAP_USER_ATTRIBUTE'), '=', $username)->first();
if (!$ldapuser) {
// log error
return false;
}
$ldapuser_attrs = null;
$attrs = [];
foreach (config('ldap_auth.sync_attributes') as $local_attr => $ldap_attr) {
if ($local_attr == 'username') {
continue;
}
$method = 'get' . $ldap_attr;
if (method_exists($ldapuser, $method)) {
$attrs[$local_attr] = $ldapuser->$method();
continue;
}
if ($ldapuser_attrs === null) {
$ldapuser_attrs = self::accessProtected($ldapuser, 'attributes');
}
if (!isset($ldapuser_attrs[$ldap_attr])) {
// an exception could be thrown
$attrs[$local_attr] = null;
continue;
}
if (!is_array($ldapuser_attrs[$ldap_attr])) {
$attrs[$local_attr] = $ldapuser_attrs[$ldap_attr];
}
if (count($ldapuser_attrs[$ldap_attr]) == 0) {
// an exception could be thrown
$attrs[$local_attr] = null;
continue;
}
$attrs[$local_attr] = $ldapuser_attrs[$ldap_attr][0];
//$attrs[$local_attr] = implode(',', $ldapuser_attrs[$ldap_attr]);
}
return $attrs;
}
protected static function accessProtected($obj, $prop)
{
$reflection = new \ReflectionClass($obj);
$property = $reflection->getProperty($prop);
$property->setAccessible(true);
return $property->getValue($obj);
}
}
Please or to participate in this conversation.