17.9.1 Problem
You want to
restrict parts of your site to authenticated users. Instead of verifying people
against a database or using HTTP Basic authorization, you want to use an LDAP
server. Holding all user information in an LDAP server makes centralized user
administration easier.
17.9.2 Solution
$options = array('host' => 'ldap.example.com',
'port' => '389',
'base' => 'o=Example Inc., c=US',
'userattr' => 'uid');
$auth = new Auth('LDAP', $options);
// begin validation
// print login screen for anonymous users
$auth->start();
if ($auth->getAuth()) {
// content for validated users
} else {
// content for anonymous users
}
// log users out
$auth->logout();
17.9.3 Discussion
LDAP servers are designed for address storage, lookup, and
retrieval, and so are better to use than standard databases like MySQL or
Oracle. LDAP servers are very fast, you can easily implement access control by
granting different permissions to different groups of users, and many different
programs can query the server. For example, most email clients can use an LDAP
server as an address book, so if you address a message to "John Smith," the
server replies with John's email address, jsmith@example.com.
PEAR's Auth class allows you to validate users against
files, databases, and LDAP servers. The first parameter is the type of
authentication to use, and the second is an array of information on how to
validate users. For example:
$options = array('host' => 'ldap.example.com',
'port' => '389',
'base' => 'o=Example Inc., c=US',
'userattr' => 'uid');
$auth = new Auth('LDAP', $options);
This creates a new Auth object that validates against
an LDAP server located at ldap.example.com and
communicates over port 389. The base directory name is o=Example
Inc., c=US, and usernames are checked against the uid attribute.
The uid field stands for user identifier. This is normally a username
for a web site or a login name for a general account. If your server doesn't
store uid attributes for each user, you can
substitute the cn attribute. The common name field holds a user's full
name, such as "John Q. Smith."
The Auth::auth( ) method also
takes an optional third parameter — the name of a function that displays the
sign-in form. This form can be formatted however you wish; the only requirement
is that the form input fields must be called username and
password. Also, the form must submit the data using POST.
$options = array('host' => 'ldap.example.com',
'port' => '389',
'base' => 'o=Example Inc., c=US',
'userattr' => 'uid');
function pc_auth_ldap_signin() {
print<<<_HTML_
<form method="post" action="$_SERVER[PHP_SELF]">
Name: <input name="username" type="text"><br />
Password: <input name="password" type="password"><br />
<input type="submit" value="Sign In">
</form>
_HTML_;
}
$auth = new Auth('LDAP', $options, 'pc_auth_ldap_signin');
$auth->start();
If the user is already signed in, nothing happens. If the user
is anonymous, the sign-in form is printed. To validate a user, Auth::start(
) connects to the LDAP server, does an anonymous bind, and searches for an
address in which the user attribute specified in the constructor matches the
username passed in by the form:
$options['userattr'] = = $_POST['username']
If Auth::start( ) finds exactly one person that fits
this criteria, it retrieves the designated name for the user, and attempts to do
an authenticated bind, using the designated name and password from the form as
the login credentials. The LDAP server then compares the password to the
userPassword attribute associated with the designated name. If it
matches, the user is authenticated.
if ($auth->getAuth( )) {
print 'Welcome member! Nice to see you again.';
} else {
print 'Welcome guest. First time visiting?';
}
The Auth class uses the built-in session module to
track users, so once validated, a person remains authenticated until the session
expires, or you explicitly log them out with:
$auth->logout( );