Skip to content
This repository was archived by the owner on Jul 24, 2023. It is now read-only.

Commit ead560c

Browse files
committed
Working on some major refactoring.
1 parent 3bd1a43 commit ead560c

File tree

3 files changed

+145
-70
lines changed

3 files changed

+145
-70
lines changed

src/AdldapAuthUserProvider.php

Lines changed: 66 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -38,36 +38,15 @@ public function retrieveByToken($identifier, $token)
3838
*/
3939
public function retrieveByCredentials(array $credentials)
4040
{
41-
// Get the search query for users only.
42-
$query = $this->newAdldapUserQuery();
41+
$user = $this->authenticateWithCredentials($credentials);
4342

44-
// Make sure the connection is bound
45-
// before we try to utilize it.
46-
if ($query->getConnection()->isBound()) {
47-
// Get the username input attributes.
48-
$attributes = $this->getUsernameAttribute();
49-
50-
// Get the input key.
51-
$key = key($attributes);
52-
53-
// Filter the query by the username attribute and retrieve the first user result.
54-
$user = $query->where([$attributes[$key] => $credentials[$key]])->first();
55-
56-
// If the user is an Adldap User model instance.
57-
if ($user instanceof User) {
58-
// Retrieve the users login attribute.
59-
$username = $this->getUsernameFromUser($user);
60-
61-
// Retrieve the password from the submitted credentials.
62-
$password = $this->getPasswordFromCredentials($credentials);
43+
// If the user is an Adldap User model instance.
44+
if ($user instanceof User) {
45+
// Retrieve the password from the submitted credentials.
46+
$password = $this->getPasswordFromCredentials($credentials);
6347

64-
// Try to log the user in.
65-
if (!is_null($password) && $this->authenticate($username, $password)) {
66-
// Login was successful, we'll create a new
67-
// Laravel model with the Adldap user.
68-
return $this->getModelFromAdldap($user, $password);
69-
}
70-
}
48+
// Construct / retrieve the eloquent model from our Adldap user.
49+
return $this->getModelFromAdldap($user, $password);
7150
}
7251

7352
if ($this->getLoginFallback()) {
@@ -82,17 +61,21 @@ public function retrieveByCredentials(array $credentials)
8261
*/
8362
public function validateCredentials(Authenticatable $user, array $credentials)
8463
{
85-
if ($this->getPasswordSync()) {
86-
// If password syncing is enabled. We can hit our
87-
// local database to check the hashed password.
64+
if ($this->authenticateWithCredentials($credentials)) {
65+
// We've authenticated successfully, we'll finally
66+
// save the user to our local database.
67+
$this->saveModel($user);
68+
69+
return true;
70+
}
71+
72+
if ($this->getLoginFallback() && $user->exists) {
73+
// If the user exists in our local database already and fallback is
74+
// enabled, we'll perform standard eloquent authentication.
8875
return parent::validateCredentials($user, $credentials);
8976
}
9077

91-
// We've already performed LDAP authentication on the user
92-
// and password synchronization is disabled, therefore
93-
// we can't validate the submitted password in our
94-
// local database. We'll return true here.
95-
return true;
78+
return false;
9679
}
9780

9881
/**
@@ -122,7 +105,17 @@ protected function discoverAdldapFromModel($model)
122105
}
123106

124107
/**
125-
* Authenticates a user against Active Directory.
108+
* Checks if we're currently connected to our configured LDAP server.
109+
*
110+
* @return bool
111+
*/
112+
protected function isConnected()
113+
{
114+
return $this->getAdldap()->getConnection()->isBound();
115+
}
116+
117+
/**
118+
* Authenticates a user against our LDAP connection.
126119
*
127120
* @param string $username
128121
* @param string $password
@@ -135,23 +128,49 @@ protected function authenticate($username, $password)
135128
}
136129

137130
/**
138-
* Returns the configured username from the specified AD user.
131+
* Authenticates against Active Directory using the specified credentials.
139132
*
140-
* @param User $user
133+
* @param array $credentials
141134
*
142-
* @return string
135+
* @return User|false
143136
*/
144-
protected function getUsernameFromUser(User $user)
137+
protected function authenticateWithCredentials(array $credentials = [])
145138
{
146-
$username = $user->{$this->getLoginAttribute()};
139+
// Make sure we're connected to our LDAP server before we run any operations.
140+
if ($this->isConnected()) {
141+
// Retrieve the Adldap user.
142+
$user = $this->newAdldapUserQuery()->where([
143+
$this->getUsernameValue() => $this->getUsernameFromCredentials($credentials)
144+
])->first();
145+
146+
if ($user instanceof User) {
147+
// Retrieve the authentication username for the AD user.
148+
$username = $this->getUsernameFromAdUser($user);
147149

148-
if (is_array($username)) {
149-
// We'll make sure we retrieve the users first username
150-
// attribute if it's contained in an array.
151-
$username = Arr::get($username, 0);
150+
// Retrieve the users password.
151+
$password = $this->getPasswordFromCredentials($credentials);
152+
153+
// Perform LDAP authentication.
154+
if ($this->authenticate($username, $password)) {
155+
// Passed, return the user instance.
156+
return $user;
157+
}
158+
}
152159
}
153160

154-
return $username;
161+
return false;
162+
}
163+
164+
/**
165+
* Returns the username from the specified credentials.
166+
*
167+
* @param array $credentials
168+
*
169+
* @return string
170+
*/
171+
protected function getUsernameFromCredentials(array $credentials = [])
172+
{
173+
return Arr::get($credentials, $this->getUsernameKey());
155174
}
156175

157176
/**

src/Middleware/WindowsAuthenticate.php

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,18 @@ public function handle(Request $request, Closure $next)
6868
// Double check that we have the correct AD user instance.
6969
if ($user instanceof User) {
7070
// Retrieve the Eloquent user model from our AD user instance.
71+
// We'll assign the user a random password since we don't
72+
// have access to it through SSO auth.
7173
$model = $this->getModelFromAdldap($user, str_random());
7274

73-
if ($model instanceof Model) {
74-
// If we've been given the correct object instance, we'll log the user in.
75-
$this->auth->login($model);
75+
// Save model in case of changes.
76+
$this->saveModel($model);
7677

77-
// Perform any further operations on the authenticated user model.
78-
$this->handleAuthenticatedUser($model);
79-
}
78+
// Manually log the user in.
79+
$this->auth->login($model);
80+
81+
// Perform any further operations on the authenticated user model.
82+
$this->handleAuthenticatedUser($model);
8083
}
8184
}
8285
}

src/Traits/ImportsUsers.php

Lines changed: 70 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
use Adldap\Laravel\Facades\Adldap;
66
use Adldap\Models\User;
7-
use Illuminate\Contracts\Auth\Authenticatable;
87
use Illuminate\Database\Eloquent\Model;
98
use Illuminate\Support\Arr;
109
use Illuminate\Support\Facades\Config;
@@ -17,7 +16,7 @@ trait ImportsUsers
1716
abstract public function createModel();
1817

1918
/**
20-
* Creates a local User from Active Directory.
19+
* Returns an existing or new Eloquent user from the specified Adldap user instance.
2120
*
2221
* @param User $user
2322
* @param string $password
@@ -26,7 +25,7 @@ abstract public function createModel();
2625
*/
2726
protected function getModelFromAdldap(User $user, $password)
2827
{
29-
// Get the username attributes.
28+
// Get the model key.
3029
$attributes = $this->getUsernameAttribute();
3130

3231
// Get the model key.
@@ -64,12 +63,12 @@ protected function getModelFromAdldap(User $user, $password)
6463
* Binds the Adldap User instance to the Eloquent model instance
6564
* by setting its `adldapUser` public property.
6665
*
67-
* @param User $user
68-
* @param Authenticatable $model
66+
* @param User $user
67+
* @param Model $model
6968
*
70-
* @return Authenticatable
69+
* @return Model
7170
*/
72-
protected function bindAdldapToModel(User $user, Authenticatable $model)
71+
protected function bindAdldapToModel(User $user, Model $model)
7372
{
7473
$model->adldapUser = $user;
7574

@@ -79,12 +78,12 @@ protected function bindAdldapToModel(User $user, Authenticatable $model)
7978
/**
8079
* Fills a models attributes by the specified Users attributes.
8180
*
82-
* @param User $user
83-
* @param Authenticatable $model
81+
* @param User $user
82+
* @param Model $model
8483
*
85-
* @return Authenticatable
84+
* @return Model
8685
*/
87-
protected function syncModelFromAdldap(User $user, Authenticatable $model)
86+
protected function syncModelFromAdldap(User $user, Model $model)
8887
{
8988
foreach ($this->getSyncAttributes() as $modelField => $adField) {
9089
if ($this->isAttributeCallback($adField)) {
@@ -96,20 +95,18 @@ protected function syncModelFromAdldap(User $user, Authenticatable $model)
9695
$model->{$modelField} = $value;
9796
}
9897

99-
$model->save();
100-
10198
return $model;
10299
}
103100

104101
/**
105102
* Syncs the models password with the specified password.
106103
*
107-
* @param Authenticatable $model
108-
* @param string $password
104+
* @param Model $model
105+
* @param string $password
109106
*
110-
* @return Authenticatable
107+
* @return Model
111108
*/
112-
protected function syncModelPassword(Authenticatable $model, $password)
109+
protected function syncModelPassword(Model $model, $password)
113110
{
114111
// If the developer doesn't want to synchronize AD passwords,
115112
// we'll set the password to a random 16 character string.
@@ -124,6 +121,18 @@ protected function syncModelPassword(Authenticatable $model, $password)
124121
return $model;
125122
}
126123

124+
/**
125+
* Saves the specified model.
126+
*
127+
* @param Model $model
128+
*
129+
* @return bool
130+
*/
131+
protected function saveModel(Model $model)
132+
{
133+
return $model->save();
134+
}
135+
127136
/**
128137
* Returns true / false if the specified string
129138
* is a callback for an attribute handler.
@@ -230,6 +239,50 @@ protected function getAdldap($provider = null)
230239
return $ad->getManager()->get($provider);
231240
}
232241

242+
/**
243+
* Returns the configured username from the specified AD user.
244+
*
245+
* @param User $user
246+
*
247+
* @return string
248+
*/
249+
protected function getUsernameFromAdUser(User $user)
250+
{
251+
$username = $user->{$this->getLoginAttribute()};
252+
253+
if (is_array($username)) {
254+
// We'll make sure we retrieve the users first username
255+
// attribute if it's contained in an array.
256+
$username = Arr::get($username, 0);
257+
}
258+
259+
return $username;
260+
}
261+
262+
/**
263+
* Returns the configured username key.
264+
*
265+
* For example: 'email' or 'username'.
266+
*
267+
* @return string
268+
*/
269+
protected function getUsernameKey()
270+
{
271+
return key($this->getUsernameAttribute());
272+
}
273+
274+
/**
275+
* Returns the configured username value.
276+
*
277+
* For example: 'samaccountname' or 'mail'.
278+
*
279+
* @return string
280+
*/
281+
protected function getUsernameValue()
282+
{
283+
return Arr::get($this->getUsernameAttribute(), $this->getUsernameKey());
284+
}
285+
233286
/**
234287
* Returns the configured select attributes when performing
235288
* queries for authentication and binding for users.

0 commit comments

Comments
 (0)