Apache-AuthTicket

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

        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

Changes  view on Meta::CPAN

     ** 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

META.json  view on Meta::CPAN

{
   "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",

META.yml  view on Meta::CPAN

---
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)] },
    };

README  view on Meta::CPAN

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

t/auth.t  view on Meta::CPAN

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';

t/auth.t  view on Meta::CPAN

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';

t/auth.t  view on Meta::CPAN

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) {



( run in 1.095 second using v1.01-cache-2.11-cpan-e9199f4ba4c )