Apache-AuthCookie
view release on metacpan or search on metacpan
lib/Apache2/AuthCookie.pm view on Meta::CPAN
package Apache2::AuthCookie;
$Apache2::AuthCookie::VERSION = '3.32';
# ABSTRACT: Perl Authentication and Authorization via cookies
use strict;
use Carp;
use base 'Apache2::AuthCookie::Base';
use Apache2::Const qw(OK DECLINED SERVER_ERROR HTTP_FORBIDDEN);
use Apache::AuthCookie::Util qw(is_blank);
sub authorize {
my ($auth_type, $r) = @_;
my $debug = $r->dir_config("AuthCookieDebug") || 0;
$r->server->log_error('authorize() for '.$r->uri()) if $debug >= 3;
return OK unless $r->is_initial_req; #only the first internal request
if ($r->auth_type ne $auth_type) {
$r->server->log_error("auth type mismatch $auth_type != ".$r->auth_type)
if $debug >= 3;
return DECLINED;
}
my $reqs_arr = $auth_type->decoded_requires($r) or return DECLINED;
my $user = $auth_type->decoded_user($r);
$r->server->log_error("authorize user=$user type=$auth_type") if $debug >=3;
if (is_blank($user)) {
# the authentication failed
$r->server->log_error("No user authenticated", $r->uri);
return HTTP_FORBIDDEN;
}
my $satisfy = $auth_type->get_satisfy($r);
return SERVER_ERROR unless $auth_type->satisfy_is_valid($r,$satisfy);
my $satisfy_all = $satisfy eq 'all';
my ($forbidden);
foreach my $req (@$reqs_arr) {
my ($requirement, $args) = split /\s+/, $req->{requirement}, 2;
$args = '' unless defined $args;
$r->server->log_error("requirement := $requirement, $args") if $debug >= 2;
if (lc($requirement) eq 'valid-user') {
if ($satisfy_all) {
next;
}
else {
return OK;
}
}
if ($requirement eq 'user') {
if ($args =~ m/\b$user\b/) {
next if $satisfy_all;
return OK; # satisfy any
}
$forbidden = 1;
next;
}
# Call a custom method
my $ret_val = $auth_type->$requirement($r, $args);
$r->server->log_error("$auth_type->$requirement returned $ret_val") if $debug >= 3;
if ($ret_val == OK) {
next if $satisfy_all;
return OK; # satisfy any
}
# Nothing succeeded, deny access to this user.
$forbidden = 1;
}
return $forbidden ? HTTP_FORBIDDEN : OK;
}
sub get_satisfy {
my ($auth_type, $r) = @_;
my $auth_name = $r->auth_name;
return lc( $r->dir_config("${auth_name}Satisfy") || 'all' );
lib/Apache2/AuthCookie.pm view on Meta::CPAN
=head2 custom_errors($r,@_): int
Note: this interface is experimental.
This method handles the server response when you wish to access the Apache
custom_response method. Any suitable response can be used. this is
particularly useful when implementing 'by directory' access control using
the user authentication information. i.e.
/restricted
/one user is allowed access here
/two not here
/three AND here
The authen_ses_key method would return a normal response when the user attempts
to access 'one' or 'three' but return (NOT_FOUND, 'File not found') if an
attempt was made to access subdirectory 'two'. Or, in the case of expired
credentials, (AUTH_REQUIRED,'Your session has timed out, you must login
again').
example 'custom_errors'
sub custom_errors {
my ($self,$r,$CODE,$msg) = @_;
# return custom message else use the server's standard message
$r->custom_response($CODE, $msg) if $msg;
return($CODE);
}
where CODE is a valid code from Apache2::Const
=head1 ENCODING AND CHARACTER SETS
=head2 Encoding
AuthCookie provides support for decoding POST/GET data if you tell it what the
client encoding is. You do this by setting the C<< ${auth_name}Encoding >>
setting in C<httpd.conf>. E.g.:
PerlSetVar WhateEverEncoding UTF-8
# and you also need to arrange for charset=UTF-8 at the end of the
# Content-Type header with something like:
AddDefaultCharset UTF-8
Note that you B<can> use charsets other than C<UTF-8>, however, you need to
arrange for the browser to send the right encoding back to the server.
If you have turned on Encoding support by setting C<< ${auth_name}Encoding >>,
this has the following effects:
=over 4
=item *
The internal pure-perl params processing subclass will be used, even if
libapreq2 is installed. libapreq2 does not have any support for encoding or
unicode.
=item *
POST/GET data intercepted by AuthCookie will be decoded to perl's internal
format using L<Encode/decode>.
=item *
The value stored in C<< $r-E<gt>user >> will be encoded as B<bytes>, not
characters using the configured encoding name. This is because the value
stored by mod_perl is a C API string, and not a perl string. You can use
L<decoded_user()> to get user string encoded using B<character> semantics.
=back
This does has some caveats:
=over 4
=item *
your L<authen_cred()> and L<authen_ses_key()> function is expected to return
a decoded username, either by passing it through L<Encode/decode()>, or, by
turning on the UTF8 flag if appropriate.
=item *
Due to the way HTTP works, cookies cannot contain non-ASCII characters.
Because of this, if you are including the username in your generated session
key, you will need to escape any non-ascii characters in the session key
returned by L<authen_cred()>.
=item *
Similarly, you must reverse this escaping process in L<authen_ses_key()> and
return a L<Encode/decode()> decoded username. If your L<authen_cred()>
function already only generates ASCII-only session keys then you do not need to
worry about any of this.
=item *
The value stored in C<< $r-E<gt>user >> will be encoded using bytes semantics
using the configured B<Encoding>. If you want the decoded user value, use
L<decoded_user()> instead.
=back
=head2 Requires
You can also specify what the charset is of the Apache C<< $r-E<gt>requires >>
data is by setting C<< ${auth_name}RequiresEncoding >> in httpd.conf.
E.g.:
PerlSetVar WhatEverRequiresEncoding UTF-8
This will make it so that AuthCookie will decode your C<requires> directives
using the configured character set. You really only need to do this if you
have used non-ascii characters in any of your C<requires> directives in
httpd.conf. e.g.:
requires user programmør
=head1 EXAMPLE
For an example of how to use Apache2::AuthCookie, you may want to check
out the test suite, which runs AuthCookie through a few of its paces.
The documents are located in t/eg/, and you may want to peruse
t/real.t to see the generated httpd.conf file (at the bottom of
real.t) and check out what requests it's making of the server (at the
top of real.t).
=head1 THE LOGIN SCRIPT
You will need to create a login script (called login.pl above) that
generates an HTML form for the user to fill out. You might generate
the page using a ModPerl::Registry script, a HTML::Mason component, an Apache
handler, or perhaps even using a static HTML page. It's usually useful to
generate it dynamically so that you can define the 'destination' field
correctly (see below).
The following fields must be present in the form:
=over 4
=item 1.
The ACTION of the form must be /LOGIN (or whatever you defined in your
server configuration as handled by the ->login() method - see example
in the SYNOPSIS section).
=item 2.
The various user input fields (username, passwords, etc.) must be
named 'credential_0', 'credential_1', etc. on the form. These will
get passed to your authen_cred() method.
=item 3.
You must define a form field called 'destination' that tells
AuthCookie where to redirect the request after successfully logging
in. Typically this value is obtained from C<$r-E<gt>prev-E<gt>uri>.
See the login.pl script in t/eg/.
( run in 1.940 second using v1.01-cache-2.11-cpan-39bf76dae61 )