view release on metacpan or search on metacpan
that may have been added to the ticket by a subclass are included in
the signature.
0.91 2011-05-13
added SIGNATURE support to make dist
added signature test
added META_MERGE bugtracker, repository to Makefile.PL
cleanup Makefile.PL a bit
fixed uninitialized warning in _unpack_ticket() [51138]
fixed Odd number of elements warning in _unpack_ticket() [51136]
POD: explain difference between "TicketExpires" and inherited AuthCookie
"Expire" directive.
MP1: synchronize with MP2 version.
abstract common MP1/MP2 code into ::Base package.
Move ::Util code into ::Base
use Class::Accessor::Fast to generate accessors
combine user/pass lookup into single SQL query (one less query per request)
added get_config() for fetching config values
added user_table(), ticket_table(), secret_table() methods to simplify
table lookups
eliminate need for _get_max_secret_version() - consolidated into
** NOTE ** MD5 passwords that worked with previous versions will not work
with this version due to the fact that md5_hex() was used incorrectly.
Upgrading from previous versions will also invalidate any current tickets
because the ticket generation routines also were using md5_hex
incorrectly.
Release 0.20
o Renamed module from Apache::TicketAccess to Apache::AuthTicket after
discovering that Apache::TicketAccess is distributed with the mod_perl
book examples.
o Adapted module to Apache::AuthCookie v2.011. This module now
subclasses Apache::AuthCookie and relies on AuthCookie for all of the
cookie login logic. This was basically a complete rewrite.
o Split up query to fetch the server secret so that the LIMIT clause is
not needed (for Sybase ASE backends, thanks to Eivind Trondsen)
o Made DBI commit() only be called if AutoCommit is off.
(silences a warn() for MySQL)
o Added support for md5 style passwords.
o Added support for crypt() style passwords.
o Added way to retrieve reason for login using
$r->subprocess_env("AuthTicketReason").
o Added support for Idle Timeout logouts via TicketIdleTimeout
configuration.
o Added "sample" directory with sql examples for setting up pgsql and mysql
backends, as well as httpd.conf samples.
o Removed libapreq dependency (AuthCookie does this stuff now)
Relaese 0.10
o Initial public release: Apache::TicketAccess 0.10
{
"abstract" : "Cookie Based Access and Authorization Module",
"author" : [
"Michael Schout <mschout@cpan.org>"
],
"dynamic_config" : 0,
"generated_by" : "Dist::Zilla version 6.009, CPAN::Meta::Converter version 2.150005",
"license" : [
"perl_5"
],
"meta-spec" : {
"url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
---
abstract: 'Cookie Based Access and Authorization Module'
author:
- 'Michael Schout <mschout@cpan.org>'
build_requires: {}
dynamic_config: 0
generated_by: 'Dist::Zilla version 6.009, CPAN::Meta::Converter version 2.150005'
license: perl
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
version: '1.4'
name: Apache-AuthTicket
Makefile.PL view on Meta::CPAN
'Test::More' => 0
},
clean => {
FILES => \@CLEAN_FILES
}
);
if ($mp_version == 2) {
# MP2 deps
$conf{PREREQ_PM}{'mod_perl2'} = '1.9922'; # 2.0 RC5 (Apache -> Apache2)
$conf{PREREQ_PM}{'Apache2::AuthCookie'} = '3.0';
}
else {
# MP1 deps
$conf{PREREQ_PM}{'mod_perl'} = '1.27';
$conf{PREREQ_PM}{'Apache::AuthCookie'} = '3.0';
}
if (MM->can('signature_target')) {
$conf{SIGN} = 1;
}
if ($ExtUtils::MakeMaker::VERSION >= 6.48) {
$conf{META_MERGE} = {
no_index => { directory => [qw(t)] },
};
Apache::AuthCookie is Copyright (C) 2000-2009, Michael Schout.
WHAT IS THIS?
This package contains the Apache::AuthTicket module and the
Apache2::AuthTicket module. These modules implement a cookie based
authentication system similar to the ticket access system described in the
mod_perl eagle book.
Apache::AuthTicket is for mod_perl version 1
Apache2::AuthTicket is for mod_perl version 2
HOW DO I INSTALL IT?
You need perl 5.6.0 or better to install this package. In addition, you
should also have the following packages installed:
Apache::AuthCookie 2.011 or later.
mod_perl 1.22 or later
DBI
Digest::MD5
SQL::Abstract
All of these modules are available from your favorite CPAN mirror.
Installation of this module is as usual:
perl Makefile.PL
make
make test
make install
Most of the tests are skipped unless you have DBD::SQLite and Apache::Test
installed. Install those modules from CPAN if you have trouble and want
useful output from "make test"
SEE ALSO
Apache::AuthCookie, Apache2::AuthCookie
AUTHOR
Michael Schout, <mschout@gkg.net>
COPYRIGHT AND LICENSE
Copyright (C) 2000-2008 by Michael Schout
This program is free software; you can redistribute it and/or modify it
under the terms of either:
README.apache-2.4.pod view on Meta::CPAN
This would be configured with something like:
PerlAddAuthzProvider species My::AuthTicket->authz_species
This would call C<My::AuthTicket::authz_species()> for any
C<Require species kilingon> type directives. Again, if you are just requring
C<user> or C<valid-user> you do not need to do this. Apache supplies an authz
provider that handles those for you.
See the C<README.apache-2.4.pod> in the L<Apache2::AuthCookie> distribution for
details on how to write an authz provider method.
=back
lib/Apache/AuthTicket.pm view on Meta::CPAN
package Apache::AuthTicket;
$Apache::AuthTicket::VERSION = '0.94';
# ABSTRACT: Cookie Based Access and Authorization Module
use strict;
use base qw(Apache::AuthTicket::Base Apache::AuthCookie);
use Apache::Constants;
use Apache::Log;
use MRO::Compat;
sub push_handler {
my ($class, $phase, $handler) = @_;
return Apache->push_handlers($phase, $handler);
}
lib/Apache/AuthTicket.pm view on Meta::CPAN
}
1;
__END__
=pod
=head1 NAME
Apache::AuthTicket - Cookie Based Access and Authorization Module
=head1 VERSION
version 0.94
=head1 SYNOPSIS
# in httpd.conf
PerlModule Apache::AuthTicket
PerlSetVar FooTicketDB DBI:mysql:database=mschout;host=testbed
lib/Apache/AuthTicket.pm view on Meta::CPAN
SetHandler perl-script
PerlHandler Apache::AuthTicket->logout
</Location>
=head1 DESCRIPTION
This module provides ticket based access control. The theory behind this is
similar to the system described in the eagle book.
This module works using HTTP cookies to check if a user is authorized to view a
page. I<Apache::AuthCookie> is used as the underlying mechanism for managing
cookies.
This module was designed to be as extensible as possible. Its quite likely
that you will want to create your own subclass of I<Apache::AuthTicket> in
order to customize various aspects of this module (show your own versions of
the forms, override database methods etc).
This system uses cookies to authenticate users. When a user is authenticated
through this system, they are issued a cookie consisting of the time, the
username of the user, the expriation time of the cookie, a "secret" version
lib/Apache/AuthTicket.pm view on Meta::CPAN
The actual contents and length of secret data is left to the site
administrator. A good choice might be to read data from /dev/random, unpack it
into a hex string and save that.
This system should be reasonably secure becuase the IP address of the end user
is incorporated into the cryptographic signature. If the ticket were
intercepted, then an attacker would have to steal the user's IP address in
order to be able to use the ticket. Plus, since the tickets can expire
automatically, we can be sure that the ticket is not valid for a long period of
time. Finally, by using the I<Secure> mode of I<Apache::AuthCookie>, the
ticket is not passed over unencrypted connections. In order to attack this
system, an attacker would have to exploit both the MD5 algorightm as well as
SSL. Chances are, by the time the user could break both of these, the ticket
would no longer be valid.
=head1 CONFIGURATION
There are two things you must do in order to configure this module:
1) configure your mod_perl apache server
lib/Apache/AuthTicket.pm view on Meta::CPAN
=head2 Apache Configuration - startup.pl
Any I<Apache::AuthTicket> configuration items can be set in startup.pl. You
can configure an AuthName like this:
Apache::AuthTicket->configure(String auth_name, *Hash config)
Note that when configuring this way you dont prefix the configuration items
with the AuthName value like you do when using PerlSetVar directives.
Note: You must still include I<Apache::AuthCookie> configuration directives in
httpd.conf when configuring the server this way. These items include:
PerlSetVar FooPath /
PerlSetVar FooDomain .foo.com
PerlSetVar FooSecure 1
PerlSetVar FooLoginScript /foologinform
example:
Apache::AuthTicket->configure('Foo', {
TicketDB => 'DBI:mysql:database=test;host=foo',
lib/Apache/AuthTicket.pm view on Meta::CPAN
Format: table_name:data_column:version_column
Example: ticketsecrets:sec_data:sec_version
=item B<TicketExpires>
This directive specifys the number of minutes that tickets should remain
valid for. If a user exceeds this limit, they will be forced to log in
again.
This should not be confused with the inherited AuthCookie setting C<Expire>,
which is the I<cookie> expiration time. C<TicketExpires> controls the
expiration of the ticket, not the cookie.
=item B<TicketIdleTimeout>
This directive specifys the number of minutes of inactivity before a ticket
is considered invalid. Setting this value to 5 for example would force a
re-login if no requests are recieved from the user in a 5 minute period.
The default for this value is 0, which disables this feature. If this number
lib/Apache/AuthTicket.pm view on Meta::CPAN
=over 3
=item void make_login_screen($r, String action, String destination)
This method creats the "login" screen that is shown to the user. You can
overload this method to create your own login screen. The log in screen only
needs to contain a hidden field called "destination" with the contents of
I<destination> in it, a text field named I<credential_0> and a password field
named I<credential_1>. You are responsible for sending the http header as well
as the content. See I<Apache::AuthCookie> for the description of what each of
these fields are for.
I<action> contains the action URL for the form. You must set the action of
your form to this value for it to function correctly.
I<Apache::AuthTicket> also provides a mechanism to determine why the login for
is being displayed. This can be used in conjunction with
I<Apache::AuthCookie>'s "AuthCookieReason" setting to determine why the user is
being asked to log in. I<Apache::AuthCookie> sets
$r->prev->subprocess_env("AuthCookieReason") to either "no_cookie" or
"bad_cookie" when this page is loaded. If the value is "no_cookie" then the
user is being asked to log in for the first time, or they are logging in after
they previously logged out. If this value is "bad_cookie" then
I<Apache::AuthTicket> is asking them to re-login for some reason. To determine
what this reason is, you must examine
$r->prev->subprocess_env("AuthTicketReason"). I<AuthTicketReason> can take the
following values:
=over 3
lib/Apache/AuthTicket.pm view on Meta::CPAN
Note that you can also adjust the DBI connection settings by setting TicketDB,
TicketDBUser, and TicketDBPassword in httpd.conf.
=back
=head1 CREDITS
The idea for this module came from the Ticket Access system in the eagle book,
along with several ideas discussed on the mod_perl mailing list.
Thanks to Ken Williams for his wonderful I<Apache::AuthCookie> module, and for
putting in the necessary changes to I<Apache::AuthCookie> to make this module
work!
=head1 SEE ALSO
L<perl>, L<mod_perl>, L<Apache>, L<Apache::AuthCookie>
=head1 SOURCE
The development version is on github at L<http://github.com/mschout/apache-authticket>
and may be cloned from L<git://github.com/mschout/apache-authticket.git>
=head1 BUGS
Please report any bugs or feature requests to bug-apache-authticket@rt.cpan.org or through the web interface at:
http://rt.cpan.org/Public/Dist/Display.html?Name=Apache-AuthTicket
lib/Apache/AuthTicket/Base.pm view on Meta::CPAN
$class->make_login_screen($r, $action, $destination);
return $class->apache_const('OK');
}
sub make_login_screen {
my ($self, $r, $action, $destination) = @_;
if (DEBUGGING) {
# log what we think is wrong.
my $reason = $r->prev->subprocess_env("AuthCookieReason");
$r->log_error("REASON FOR AUTH NEEDED: $reason");
$reason = $r->prev->subprocess_env("AuthTicketReason");
$r->log_error("AUTHTICKET REASON: $reason");
}
$r->content_type('text/html');
$r->send_http_header if ModPerl::VersionUtil->is_mp1;
$r->print(
lib/Apache/AuthTicket/Base.pm view on Meta::CPAN
return $self->apache_const('OK');
}
sub logout ($$) {
my ($class, $r) = @_;
my $self = $class->new($r);
$self->delete_ticket($r);
$self->next::method($r); # AuthCookie logout
$r->headers_out->add(Location => $self->get_config('TicketLogoutURI'));
return $class->apache_const('REDIRECT');
}
##################### END STATIC METHODS ###########################3
sub new {
my ($class, $r) = @_;
lib/Apache2/AuthTicket.pm view on Meta::CPAN
package Apache2::AuthTicket;
$Apache2::AuthTicket::VERSION = '0.94';
# ABSTRACT: Cookie Based Access and Authorization Module
use strict;
use base qw(Apache::AuthTicket::Base Apache2::AuthCookie);
use Apache2::Const;
use Apache2::RequestIO;
use Apache2::Connection;
use Apache2::ServerUtil;
use MRO::Compat;
sub push_handler {
my ($class, $phase, $handler) = @_;
Apache2::ServerUtil->server->push_handlers($phase, $handler);
lib/Apache2/AuthTicket.pm view on Meta::CPAN
}
1;
__END__
=pod
=head1 NAME
Apache2::AuthTicket - Cookie Based Access and Authorization Module
=head1 VERSION
version 0.94
=head1 SYNOPSIS
# in httpd.conf
PerlModule Apache2::AuthTicket
PerlSetVar FooTicketDB DBI:mysql:database=mschout;host=testbed
lib/Apache2/AuthTicket.pm view on Meta::CPAN
SetHandler perl-script
PerlResponseHandler Apache2::AuthTicket->logout
</Location>
=head1 DESCRIPTION
This module provides ticket based access control. The theory behind this is
similar to the system described in the eagle book.
This module works using HTTP cookies to check if a user is authorized to view a
page. I<Apache2::AuthCookie> is used as the underlying mechanism for managing
cookies.
This module was designed to be as extensible as possible. Its quite likely
that you will want to create your own subclass of I<Apache2::AuthTicket> in
order to customize various aspects of this module (show your own versions of
the forms, override database methods etc).
This system uses cookies to authenticate users. When a user is authenticated
through this system, they are issued a cookie consisting of the time, the
username of the user, the expriation time of the cookie, a "secret" version
lib/Apache2/AuthTicket.pm view on Meta::CPAN
The actual contents and length of secret data is left to the site
administrator. A good choice might be to read data from /dev/random, unpack it
into a hex string and save that.
This system should be reasonably secure becuase the IP address of the end user
is incorporated into the cryptographic signature. If the ticket were
intercepted, then an attacker would have to steal the user's IP address in
order to be able to use the ticket. Plus, since the tickets can expire
automatically, we can be sure that the ticket is not valid for a long period of
time. Finally, by using the I<Secure> mode of I<Apache2::AuthCookie>, the
ticket is not passed over unencrypted connections. In order to attack this
system, an attacker would have to exploit both the MD5 algorightm as well as
SSL. Chances are, by the time the user could break both of these, the ticket
would no longer be valid.
=head1 CONFIGURATION
There are two things you must do in order to configure this module:
1) configure your mod_perl apache server
lib/Apache2/AuthTicket.pm view on Meta::CPAN
=head2 Apache Configuration - startup.pl
Any I<Apache2::AuthTicket> configuration items can be set in startup.pl. You
can configure an AuthName like this:
Apache2::AuthTicket->configure(String auth_name, *Hash config)
Note that when configuring this way you dont prefix the configuration items
with the AuthName value like you do when using PerlSetVar directives.
Note: You must still include I<Apache2::AuthCookie> configuration directives in
httpd.conf when configuring the server this way. These items include:
PerlSetVar FooPath /
PerlSetVar FooDomain .foo.com
PerlSetVar FooSecure 1
PerlSetVar FooLoginScript /foologinform
example:
Apache2::AuthTicket->configure('Foo', {
TicketDB => 'DBI:mysql:database=test;host=foo',
lib/Apache2/AuthTicket.pm view on Meta::CPAN
Format: table_name:data_column:version_column
Example: ticketsecrets:sec_data:sec_version
=item B<TicketExpires>
This directive specifys the number of minutes that tickets should remain
valid for. If a user exceeds this limit, they will be forced to log in
again.
This should not be confused with the inherited AuthCookie setting C<Expire>,
which is the I<cookie> expiration time. C<TicketExpires> controls the
expiration of the ticket, not the cookie.
=item B<TicketIdleTimeout>
This directive specifys the number of minutes of inactivity before a ticket
is considered invalid. Setting this value to 5 for example would force a
re-login if no requests are recieved from the user in a 5 minute period.
The default for this value is 0, which disables this feature. If this number
lib/Apache2/AuthTicket.pm view on Meta::CPAN
=over 3
=item void make_login_screen($r, String action, String destination)
This method creats the "login" screen that is shown to the user. You can
overload this method to create your own login screen. The log in screen only
needs to contain a hidden field called "destination" with the contents of
I<destination> in it, a text field named I<credential_0> and a password field
named I<credential_1>. You are responsible for sending the http header as well
as the content. See I<Apache2::AuthCookie> for the description of what each of
these fields are for.
I<action> contains the action URL for the form. You must set the action of
your form to this value for it to function correctly.
I<Apache2::AuthTicket> also provides a mechanism to determine why the login for
is being displayed. This can be used in conjunction with
I<Apache2::AuthCookie>'s "AuthCookieReason" setting to determine why the user is
being asked to log in. I<Apache2::AuthCookie> sets
$r->prev->subprocess_env("AuthCookieReason") to either "no_cookie" or
"bad_cookie" when this page is loaded. If the value is "no_cookie" then the
user is being asked to log in for the first time, or they are logging in after
they previously logged out. If this value is "bad_cookie" then
I<Apache2::AuthTicket> is asking them to re-login for some reason. To determine
what this reason is, you must examine
$r->prev->subprocess_env("AuthTicketReason"). I<AuthTicketReason> can take the
following values:
=over 3
lib/Apache2/AuthTicket.pm view on Meta::CPAN
=back
=head1 CREDITS
The idea for this module came from the Ticket Access system in the eagle book,
along with several ideas discussed on the mod_perl mailing list.
=head1 SEE ALSO
L<perl>, L<mod_perl>, L<Apache2::AuthCookie>
=head1 SOURCE
The development version is on github at L<http://github.com/mschout/apache-authticket>
and may be cloned from L<git://github.com/mschout/apache-authticket.git>
=head1 BUGS
Please report any bugs or feature requests to bug-apache-authticket@rt.cpan.org or through the web interface at:
http://rt.cpan.org/Public/Dist/Display.html?Name=Apache-AuthTicket
elsif (not have_module('LWP::UserAgent')) {
plan skip_all => 'LWP::UserAgent is not installed';
}
else {
plan tests => 34;
}
# must match value in SQLite DB
my $Secret = 'mvkj39vek@#$R*njdea9@#';
my $CookieFormat = qr/[0-9a-f]{32}\-\-[A-Za-z0-9+\/]+/;
use_ok('Apache::AuthTicket::Base');
Apache::TestRequest::user_agent(
cookie_jar => {},
reset => 1,
requests_redirectable => 0);
# get login form
my $r = GET '/protected/index.html';
like $r->content, qr/credential_0/, 'content contains credential_1';
# login
$r = POST '/login', [
destination => '/protected/index.html',
credential_0 => 'programmer',
credential_1 => 'secret' ];
isa_ok $r, 'HTTP::Response';
is $r->code, 302, 'got 302 response';
is $r->header('Location'), '/protected/index.html', 'Location header';
like $r->header('Set-Cookie'), qr/$CookieFormat/, 'response sets cookie';
# get the protected page.
$r = GET '/protected/index.html';
isa_ok $r, 'HTTP::Response';
is $r->code, 200, 'got 200 response';
like $r->content, qr/congratulations, you got the protected page/;
# logout
$r = GET '/protected/logout';
isa_ok $r, 'HTTP::Response';
is $r->code, 302, 'got 302 response from logout';
like $r->header('Set-Cookie'), qr/::AuthTicket_Protected=;\s+/, 'Cookie was cleared';
is $r->header('Location'), '/protected/index.html', 'Logout sets location header';
# make sure we really logged out.
$r = GET '/protected/index.html';
isa_ok $r, 'HTTP::Response';
is $r->code, 403, 'got 403 response';
### /secure auth area tests.
$r = GET '/secure/protected/index.html';
isa_ok $r, 'HTTP::Response';
like $r->content, qr/credential_0/, 'content contains credential_1';
# login
$r = POST '/secure/login', [
destination => '/secure/protected/index.html',
credential_0 => 'programmer',
credential_1 => 'secret' ];
isa_ok $r, 'HTTP::Response';
is $r->code, 302, 'got 302 response';
is $r->header('Location'), '/secure/protected/index.html', 'Location header';
my $cookie = $r->header('Set-Cookie');
like $cookie, qr/AuthTicket_Sec=$CookieFormat/, 'response sets cookie';
ok cookie_has_field($cookie, 'secure'), 'cookie has secure flag set';
ok cookie_has_field($cookie, 'path=/secure'), 'cookie path = /secure';
ok cookie_has_field($cookie, 'domain=.local'), 'cookie domain is .local';
ok check_hash($cookie, ip => 0, browser => 1), 'hash users browser, not ip';
# we have to manually send the cookie here because of secure/domain fields.
$r = GET '/secure/protected/index.html', Cookie => $cookie;
isa_ok $r, 'HTTP::Response';
is $r->code, 200, 'got 200 response';
# lets tamper with the cookie. should get 403
{
my ($data) = $cookie =~ /--(.*?);/;
my $ticket = Apache::AuthTicket::Base->unserialize_ticket($data);
$$ticket{expires} += 1;
my $new_data = Apache::AuthTicket::Base->serialize_ticket($ticket);
$cookie =~ s/$data/$new_data/;
$r = GET '/secure/protected/index.html', Cookie => $cookie;
isa_ok $r, 'HTTP::Response';
is $r->code, 403, 'tampered cookie got 403 response';
}
sub cookie_has_field {
my ($cookie, $expected) = @_;
my @parts = split /;\s+/, $cookie;
for my $part (@parts) {