Download the PHP package csun-metalab/laravel-directory-authentication without Composer
On this page you can find all versions of the php package csun-metalab/laravel-directory-authentication. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download csun-metalab/laravel-directory-authentication
More information about csun-metalab/laravel-directory-authentication
Files in csun-metalab/laravel-directory-authentication
Package laravel-directory-authentication
Short Description Composer package for Laravel 5.0 and above to allow for directory-based authentication
License MIT
Informations about the package laravel-directory-authentication
Laravel Directory Authentication
Composer package for Laravel 5.0 and above to allow for directory-based authentication.
This package adds the ability to perform both local database and LDAP-based authentication.
Once the user has been authenticated via the directory service (such as LDAP) a local database lookup is performed in order to resolve a user model instance that is accessible through Auth::user()
.
If you wish to use only local database authentication (but still leverage the functionality of the package) instead, please look at the Laravel Directory Authentication (Database Only) Readme.
NOTE: authorization was added in Laravel 5.1 and therefore there is a breaking change in the MetaUser
class. If you need to use this package for Laravel 5.0, please use any version of this package prior to 1.6.0
.
Table of Contents
- Installation
- Required Environment Variables
- Optional Environment Variables
- The HandlerLDAP class
- The MetaUser Class
- Creating a Custom User Class
- Authenticating
- Masquerading
- Adding New LDAP Records
- Modifying Existing LDAP Records
- Modifying LDAP User Passwords
Installation
NOTE: There are different configuration entries to change further down based on the Laravel version you are using.
Composer, Environment, and Service Provider
Composer
To install from Composer, use the following commands in this order:
There are two commands because tiesa/ldap
cannot be in the require
clause for this package as that dependency only exposes a dev-master
release and no versioned releases. Due to this, it evaluates to a minimum-stability
of dev
and cannot be included as a dependency of a package going into a project with the minimum-stability
of stable
.
Environment
Now, add the following line(s) to your .env
file:
You may also elect to add the following optional line(s) to your .env
file to customize the functionality further:
Service Provider
Next, add the service provider to your providers
array in config/app.php
in Laravel as follows:
Configuration (Laravel 5.2 and Above)
Next, change the driver
to ldap
and add the full classname of the user model to use for database lookups in the users
array within config/auth.php
as follows:
Configuration (Laravel 5.0 and 5.1)
Next, change the driver
to ldap
and change the model
attribute to be the full classname of the user model to use for database lookups within config/auth.php
as follows:
Publish Configuration
Finally, run the following Artisan command to publish the configuration:
Required Environment Variables
You added two environment variables to your .env
file that control the connection to the LDAP server as well as its searching subtree.
LDAP_HOST
This is the hostname or IP address of the LDAP server.
LDAP_BASE_DN
This is the base DN under which all people to be searched for reside. This may be something like the following:
ou=People,ou=Auth,o=Organization
Someone under this base DN may therefore exist with the following record:
uid=person,ou=People,ou=Auth,o=Organization
NOTE: The environment variables of LDAP_BASE_DN
and LDAP_OVERLAY_DN
are incompatible. Please use either one or the other. Ideally, you would use LDAP_OVERLAY_DN
if your LDAP server makes use of an overlay to create a logical root for multiple subtrees. Otherwise, use LDAP_BASE_DN
for the search base.
Optional Environment Variables
There are several optional environment variables that may be added to customize the functionality of the package even further.
LDAP_VERSION
The version of LDAP to use when performing operations. The default is 3
.
LDAP_ALLOW_NO_PASS
True to turn off user password validation (and therefore use the admin DN and password for searching for people). When false, binding and searching is done with the username and password passed to Auth::attempt()
.
Default is false
.
LDAP_DN
The admin DN to use when binding and searching for people. This is only used when user password validation is turned off (so searching can still happen).
LDAP_PASSWORD
The admin password to use when binding and searching for people. This is only used when user password validation is turned off (so searching can still happen).
LDAP_SEARCH_USER_ID
The field to use when looking-up a person in LDAP by their user ID; this is typically a numeric field.
Default is employeeNumber
. This is the field value that will be used when checking for a user in the associated data model and database table/view.
This can also be the same as the LDAP_SEARCH_USERNAME
value if you want to perform both the LDAP and database lookups with the same value.
LDAP_SEARCH_USERNAME
The field to use when looking-up a person in LDAP by their username; this is typically the POSIX ID.
Default is uid
. This is the value that will be used to perform the search operation as the username passed to the call to Auth::attempt()
.
If password validation is turned on, this is also the username that will be used for the bind operation when combined with the base DN.
LDAP_SEARCH_MAIL
The field to use when looking-up a person in LDAP by their email address.
Default is mail
.
LDAP_SEARCH_MAIL_ARRAY
The field to use when looking-up a person in LDAP by all valid email addresses and aliases; this is typically an array attribute.
Default is mailLocalAddress
.
LDAP_SEARCH_USER_QUERY
Optional search query that will replace the default query executed by the package during user directory searches. If not specified, the query that will be used is the equivalent of (|(uid=%s)(mail=%s)(mailLocalAddress=%s))
depending on the values of LDAP_SEARCH_USERNAME
, LDAP_SEARCH_MAIL
, and LDAP_SEARCH_MAIL_ARRAY
.
If specified, this query needs to be a vsprintf()
-compatible string and use %s
as the placeholder for the search value.
LDAP_DB_USER_ID_PREFIX
Optional prefix before the value of the employee ID primary key in the associated database table/view.
Default is blank (no prefix).
For example, LDAP might store the employee ID as numeric (XXXXXXXXX
) but your database stores it as a textual value prepended with members:
(ex: members:XXXXXXXXX
). You would then set this value to members:
and your database lookups would work.
LDAP_DB_RETURN_FAKE_USER
Determines whether to return an actual user instance if the user was found in the directory but not in the database.
If true
, a user instance will be returned with LDAP attributes that can then be used to create the user in the database.
If false
, the authentication attempt will fail outright if the user is not in the database because Auth::attempt()
will return false
.
Default is false
.
LDAP_OVERLAY_DN
Overlay DN to give a consistent logical root for the search, add and modify subtrees in the directory.
Default is a blank string.
NOTE: The environment variables of LDAP_BASE_DN
and LDAP_OVERLAY_DN
are incompatible. Please use either one or the other. Ideally, you would use LDAP_OVERLAY_DN
if your LDAP server makes use of an overlay to create a logical root for multiple subtrees. Otherwise, use LDAP_BASE_DN
for the search base.
LDAP_ADD_BASE_DN
The base DN that will be used for adding objects to a subtree.
If this value is left blank, the value of LDAP_BASE_DN
will be used instead.
Default is a blank string.
LDAP_ADD_DN
The admin DN to use when adding objects to the LDAP_ADD_BASE_DN
subtree.
If this value is left blank, the value of LDAP_DN
will be used instead.
Default is a blank string.
LDAP_ADD_PW
The password to use when adding objects to the LDAP_ADD_BASE_DN
subtree.
If this value is left blank, the value of LDAP_PASSWORD
will be used instead.
Default is a blank string.
LDAP_MODIFY_METHOD
The method that will be used for modifying objects in the subtree from the LDAP_MODIFY_BASE_DN
value. Allowed values are self
and admin
.
If the value is self
then the binding user would be able to modify his own attributes in the directory.
If the value is admin
then the bind used would be made up of the combination of LDAP_MODIFY_DN
and LDAP_MODIFY_PW
.
Default is self
.
LDAP_MODIFY_BASE_DN
The base DN that will be used for modifying objects in a subtree. If this value is left blank, the value of LDAP_ADD_BASE_DN
will be used instead.
Default is a blank string.
LDAP_MODIFY_DN
The admin DN to use when modifying objects in the LDAP_MODIFY_BASE_DN
subtree.
If this value is left blank, the value of LDAP_ADD_DN
will be used instead.
Default is a blank string.
LDAP_MODIFY_PW
The password to use when modifying objects in the LDAP_MODIFY_BASE_DN
subtree.
If this value is left blank, the value of LDAP_ADD_PW
will be used instead.
Default is a blank string.
The HandlerLDAP
Class
The core LDAP functionality is provided by the CSUNMetaLab\Authentication\Handlers\HandlerLDAP
class. This contains the connect, bind, and searching features used during authentication.
This class can also be used on its own to provide general LDAP searching functionality as well and give you a consistent interface to execute lookup operations.
You can return an instance of HandlerLDAP
by executing a call to its factory class of CSUNMetaLab\Authentication\Factories\HandlerLDAPFactory
as follows:
$ldap = HandlerLDAPFactory::fromDefaults();
You will now have an instance of the class loaded with the default configuration from config/ldap.php
. If you wanted to search for someone outside of authentication purposes you could do the following, for example:
The MetaUser
Class
This package comes with the CSUNMetaLab\Authentication\MetaUser
class that is configured to work properly with the directory authentication methods. It also supports masquerading as another user right out of the box with zero additional configuration.
It provides baseline implementations of the methods to look-up a user by both an identifier in the database as well as the combination of identifier and "Remember Me" token. Only the findForAuth()
method is invoked automatically upon successful authentication; the other findForAuthToken()
method is provided for convenience if you are implementing "Remember Me" functionality in your application.
This class expects a local database table called users
with a primary key of user_id
. You are free to use this class directly as long as you meet those two requirements.
Creating a Custom User Class
It is recommended that at the minimum you create a class that extends from CSUNMetaLab\Authentication\MetaUser
since that will give you greater control over the authentication and database functionality.
Simple Subclass
A simple subclass is the following:
This class still uses the users
table but also defines the primary key as non auto-incrementing. In addition, it defines a fillable
array and allows User
instances to be created via mass-assignment.
It still, however, relies on the implementations of findForAuth()
and findForAuthToken()
that are present in the MetaUser
class.
Comprehensive Subclass
IMPORTANT: If the primary key for your model is anything other than user_id
you need to implement a comprehensive subclass, specifically the findForAuth()
and findForAuthToken()
methods. The $identifier
parameter will be the value of the primary key for the model instance when authentication checks are performed (such as when the auth
middleware is used). Otherwise, your initial login will work but the session values will be incorrect so no subsequent login checks on the next request will go through.
A more comprehensive subclass could be the following:
A couple of additional things are happening in this subclass:
- Both the table and primary keys have been changed to use custom values
- The two post-authentication methods have been overridden to perform status checks to ensure only active users are allowed to use the application
Authenticating
Authenticating with either the MetaUser
or your custom subclass works just like regular database authentication in Laravel.
This package makes a distinction between whether a user exists only in the directory or in both the directory and the database.
Authentication Only
Without Returning a Fake User Instance
If LDAP_DB_RETURN_FAKE_USER
is set to false
, you could invoke Auth::attempt()
in the following way:
With Returning a Fake User Instance
If LDAP_DB_RETURN_FAKE_USER
is set to true
, you could invoke Auth::attempt()
in the following way:
Authentication with Provisioning
NOTE: Authentication with provisioning only functions if LDAP_DB_RETURN_FAKE_USER
has been set to true
.
Because a distinction is made between valid directory and valid database users, you have the option of provisioning the user in your local database if he exists within the directory but not yet within the database.
The user instance represented by Auth::user()
also gets an array of attributes back from LDAP. This array can be accessed as searchAttributes
. It contains the following key/value pairs:
uid
(matches the value of search attributeLDAP_SEARCH_USERNAME
)user_id
(matches the value of search attributeLDAP_SEARCH_USER_ID
)first_name
(matches the value ofgivenName
)last_name
(matches the value ofsn
)display_name
(matches the value ofdisplay_name
)email
(matches the value ofLDAP_SEARCH_MAIL
)
You can now change your authentication procedure from above to be the following:
Masquerading
This package also supports the ability for the logged-in user to become another user out of the box. This is especially useful in situations where an admin-level user may need to enter another user's account in order to triage and solve a problem directly.
Become Another User
In order to become another user, it's as simple as finding the other user and then switching the logged-in user. The previous user is maintained in the session so switching back can be seamless.
Am I Masquerading?
It may be useful to determine whether the user reported by Auth::user()
is actually a masqueraded user:
You can also retrieve the instance of the masquerading user (the original user that logged-in) in the following way:
Stop Masquerading
Finally, it's simple to stop masquerading and return to your original user account.
Calls to Auth::user()
will now once again report the original logged-in user.
Adding New LDAP Records
This package will attempt to use the information configured in the following three .env
values first when performing add operations:
LDAP_ADD_BASE_DN
: the subtree where new entries will be added. If this is left empty, the value ofLDAP_BASE_DN
will be used instead.LDAP_ADD_DN
: the admin DN to use when adding entries. If this is left empty, the value ofLDAP_DN
will be used instead.LDAP_ADD_PW
: the admin password to use when adding entries. If this is left empty, the value ofLDAP_PASSWORD
will be used instead.
You can add new records to an LDAP subtree using the HandlerLDAP
class:
Modifying Existing LDAP Records
This package will attempt to use the information configured in the following four .env
values first when performing modify operations:
LDAP_MODIFY_METHOD
: ifself
, then a user can bind as himself and modify his own attributes. Ifadmin
then the value ofLDAP_MODIFY_DN
andLDAP_MODIFY_PW
will be used when performing the modification bind.LDAP_MODIFY_BASE_DN
: the subtree where entries will be modified. If this is left empty, the value ofLDAP_ADD_BASE_DN
will be used instead.LDAP_MODIFY_DN
: the admin DN to use when modifying entries. If this is left empty, the value ofLDAP_ADD_DN
will be used instead.LDAP_MODIFY_PW
: the admin password to use when modifying entries. If this is left empty, the value ofLDAP_ADD_PW
will be used instead.
You can modify existing records in an LDAP subtree using the HandlerLDAP
class:
Modifying LDAP User Passwords
While you can perform a modifyObject()
with the userPassword
attribute and follow similar steps as those in Modifying Existing LDAP Records, the HandlerLDAP
class also provides a convenience method for changing user passwords.
The password will be generated as a SSHA hash using a cryptographically-secure salt based on the output of openssl_random_pseudo_bytes()
using a four-byte string: