Show Contents Previous Page Next Page Chapter 6 - Authentication and Authorization In this section...
This section shows you how to write a simple access control handler in A Simple Access Control Module Show Contents Go to Top Previous Page Next Page
To create an access control module, you'll install a handler for the access control phase by adding a PerlAccessHandler directive to one of Apache's configuration files or to a per-directory .htaccess file. The access control handler has the job of giving thumbs up or down for each attempted access to the URI. The handler indicates its decision in the result code it returns to the server. We begin with the simplest type of access control, a stern module called Apache::GateKeeper
(Example 6-1). Apache::GateKeeper recognizes
a single configuration variable named Gate. If the value of Gate
is The code is straightforward. It begins in the usual way by importing the common Apache and HTTP constants from Apache::Constants: package Apache::GateKeeper; # file: Apache/GateKeeper.pm use strict; use Apache::Constants qw(:common); sub handler { my $r = shift; my $gate = $r->dir_config("Gate"); return DECLINED unless defined $gate; return OK if lc($gate) eq 'open';
When the handler is executed, it fetches the value of the Gate configuration variable. If the variable is absent, the handler declines to handle the transaction, deferring the decision to other handlers that may be installed. If the variable is present, the handler checks its value, and returns a value of if (lc $gate eq 'closed') { $r->log_reason("Access forbidden unless the gate is open", $r->filename); return FORBIDDEN; } $r->log_error($r->uri, ": Invalid value for Gate ($gate)"); return SERVER_ERROR; } On the other hand, if the value of Gate is "closed" the handler returns
a Example 6.1 Simple Access Control package Apache::GateKeeper; # file: Apache/GateKeeper.pm use strict; use Apache::Constants qw(:common); sub handler { my $r = shift; my $gate = $r->dir_config("Gate"); return DECLINED unless defined $gate; return OK if lc $gate eq 'open'; if (lc $gate eq 'closed') { $r->log_reason("Access forbidden unless the gate is open", $r->filename); return FORBIDDEN; } $r->log_error($r->uri, ": Invalid value for Gate ($gate)"); return SERVER_ERROR; } 1; __END__ # .htaccess file entry PerlAccessHandler Apache::GateKeeper PerlSetVar Gate closed
The bottom of the listing shows the two-line .htaccess entry required to turn on Apache::GateKeeper for a particular directory (you could also use a <Location> or <Directory> entry for this purpose). It uses the PerlAccessHandler directive to install Apache::GateKeeper as the access handler for this directory, then calls PerlSetVar to set the Perl configuration variable Gate to
How does the GateKeeper access control handler interact with other aspects of Apache access control, authentication, and authorization? If an authentication handler is also installed--for example, by including a require valid-user directive in the .htaccess file--then Apache::GateKeeper is called as only the first step in the process. If Apache::GateKeeper returns
However, this behavior can be modified by placing the line Satisfy any in the .htaccess file or directory configuration section. When this directive is in effect, Apache will try access control first and then try authentication/authorization. If either returns Now consider a .htaccess file like this one: PerlAccessHandler Apache::GateKeeper PerlSetVar Gate open order deny,allow deny from all allow from 192.168.2 This configuration installs two access control handlers: one implemented by the standard mod_access module (which defines the order, allow, and deny directives) and Apache::GateKeeper. The two handlers are potentially in conflict. The IP-based restrictions implemented by mod_access forbid access from any address but those in a privileged 192.168.2 subnet. Apache::GateKeeper, in contrast, is set to allow access to the subdirectory from anyone. Who wins?
The Apache server's method for resolving these situations is to call each handler in turn in the reverse order of installation. If the handler returns The Satisfy any directive has no effect on this situation. Show Contents Go to Top Previous Page Next PageFor a slightly more interesting access handler, consider Example 6-2, which implements access control based on the day of the week. URIs protected by this handler will only be accessible on the days listed in a variable named ReqDay. This could be useful for a web site that observes the Sabbath, or, more plausibly, it might form the basis for a generic module that implements time-based access control. Many sites perform routine maintenance at scheduled times of the day, and it's often helpful to keep visitors out of directories while they're being updated.
The handler, Apache::DayLimit, begins by fetching the ReqDay configuration variable. If not present, it declines the transaction and gives some other handler a chance to consider it. Otherwise, the handler splits out the day names, which are assumed to be contained in a space- or comma-delimited list, and compares them to the current day obtained from the localtime() function. If there's a match, the handler allows the access by returning Example 6.2 Access Control by the Day of Week package Apache::DayLimit; use strict; use Apache::Constants qw(:common); use Time::localtime; my @wday = qw(sunday monday tuesday wednesday thursday friday saturday); sub handler { my $r = shift; my $requires = $r->dir_config("ReqDay"); return DECLINED unless $requires; my $day = $wday[localtime->wday]; return OK if $requires =~ /$day([,\s]+|$)/i; $r->log_reason(qq{Access forbidden on weekday "$day"}, $r->uri); return FORBIDDEN; } 1; __END__ A <Location> section to go with Apache::DayLimit: <Location /weekends_only> PerlSetVar ReqDay saturday,sunday PerlAccessHandler Apache::DayLimit </Location>Show Contents Go to Top Previous Page Next Page Copyright © 1999 by O'Reilly & Associates, Inc. |
HIVE: All information for read only. Please respect copyright! |