Now we can proceed, in a portable manner, to build an access-control application that correlates docbase attributes with user attributes. Example 12.3 focuses on the part of the solution that compares a docbase attribute to a database of subscriptions.
Example 12-3. Authorizing Users by a Docbase Attribute
use strict; use DBI; my $dbh = DBI->connect('DBI:Solid:Subscriptions','dba','dba') # connect to subs db or die ("connect, $DBI::errstr"); my $http_authorization_header = $ENV{HTTP_AUTHORIZATION}; # extract auth header sub isBasicAuthUserForCompany { my ($http_authorization, $dbh) = @_; $http_authorization_header = m/Basic (.+)/i; # isolate credentials my $http_authorization = $1; my ($user, $password) = split (':', $1); # get name/pw my ($st) = # make query "select count(*) from cmp_users where cmp = '$company' and user = '$user'"; return ( isAuthenticated($user,$password) and # authenticate (not shown) dbSqlReturnValue ($dbh, $st) # authorize ); } sub dbSqlReturnValue { my ($dbh,$st) = @_; my $sth = $dbh->prepare($st); # prepare sql my $value; $sth->execute; # execute sql $sth->bind_col(1, $value); # bind result to value $sth->finish; # finish sql return $value; }
In this fragment, $http_authorization
gets the
value of the CGI environment variable
$ENV{HTTP_AUTHORIZATION}
. This is the
Authorization:
header sent from a browser in
response to a prior challenge issued by this (or another) script.
We’ll assume that $company
was extracted
from a docbase record, using our old friend
Docbase::Docbase::getMetadata( ).
$dbh
is a handle to the database that contains the
cmp_users table.
The isBasicAuthUserForCompany( )
function does
two checks. It sends the name/password credentials to
isAuthenticated( )
for authentication (look
ahead to Example 12.4 to see how that’s done),
and it looks up the user/company pair in
cmp_users for authorization. We’re using
Perl’s DBI interface here, so the database
could be any of those supported by a DBD module.
This code will run under Unix/Apache or NT/IIS, because Perl’s
DBI and DBD modules are
available in both environments.
For an NT-based intranet application, we could dispense with the
ISAPI filter and let NT authenticate the user against its directory.
We could then use Group::NTGroup::isMember( )
to
test whether that user was a member of the
subscribers group, but even that won’t be
necessary if we assume that only authorized subscribers are listed in
the database.
On an NT-based system that serves a nonlocal population of users,
though, we’ll need to use the filter and provide a version of
isAuthenticated( )
that does some form of
directory- or database-style authentication. The same holds true for
a system based on Apache, Netscape, or any other server that is
directory-independent in the Unix style rather than
directory-integrated in the NT style.
18.216.233.58