view release on metacpan or search on metacpan
Revision history for Apache::AuthCookie
3.32 2024-08-17
- Fix small typo in documentation (github #18, thanks Damyan Ivanov)
- Capitalize Apache in POD (thanks Ed Sabol)
- Fix warning due to quoted version in import under Perl 5.40
3.31 2022-01-05
- Fix uninitialized variable warning if "Satisfy" was not set (github #15, thanks yewtc)
3.30 2020-04-14
PerlSetVar MyAuthDefaultDestination /protected/user/
3.28 2019-11-19
- Add support for SameSite cookie property (can be strict/lax).
- Minor POD updates.
3.27 2017-07-28
- Fix POD spelling error [#118545].
3.26 2016-09-30
- remove unused module Apache::AuthCookie::Autobox from dist
- remove CGI.pm dependency. CGI.pm has been removed from perl core, which
was the primary reason we used it in the first place. Replaced with
dependency on lighter weight set of three modules:
* HTTP::Body
* WWW::Form::UrlEncoded
* Hash::MultiValue
Also recommended (but not required) is WWW::Form::UrlEncoded::XS
- Add optional support for charset encoding. If you have something like
PerlSetVar MyAuthNameEncoding UTF-8
Then AuthCookie with now automatically decode parameters using the given
encoding now. AuthCookie params() data will be decoded automatically if
this is on. See details in AuthCookie module documentation. In addition
r->user will be encoded (using byte semantics) using this encoding.
***** IMPORTANT *****
If you turn this on, this could break your code. r->user() will now be
byte encoded using the given encoding. If you use usernames that contain
non-ascii characters you either need to use decoded_user(), or decode
r->user() yourself in your subclasses.
See the AuthCookie docs for more details.
- add optional support for decoding httpd.conf requires directives. This is
enabled with a RequiresEncoding setting:
PerlSetVar MyAuthNameRequiresEncoding UTF-8
Then decoded_requires($r) will return the decoded value of $r->requires
You only need this if you have non-ascii characters in your requires
directives such as:
Requires user programmør
- add encoding($r): string which returns the value of the Encoding directive
that is in effect for the current request.
3.25 2016-08-30
- 2.4: fix POD typo and add missing ABSTRACT
- reorganize real.t tests into subtests
- make sure signature test ignores generated files
- remove autobox dependency
- fix authenticate so that r->user is copied from r->main on subrequests.
Previously this was only done for internal redirects (r->prev is defined).
This fixes DirectoryIndexes on AuthCookie enabled directories under apache
2.4.
3.24 2016-01-13
- Update Apache 2.4 README, flesh out guts of Authz Provider notes.
- Improve Apache 2.4 README's AuthzProvider documentation
- Add POD to Apache2_4::AuthCookie
- Add FAQ to Apache2_4::AuthCookie documenation
- 2.4: document that PerlAddAuthzProvider is only needed for *custom* Requires directives.
- 2.4: make authz_handler recognize multiple usernames in the directive like
mod_authz_user does.
- add test case for internal authz_handler
- explicitly require Apache::Test 1.39 so that APACHE2_4 defines are set
3.23 2015-09-10
- Improve CGI mode param() handling to avoi CGI.pm's "param() called in list context" warning.
- add support for Apache 2.4 via mod_perl 1.09.
***** IMPORTANT *****
- Bad release - deleted
3.20 2013-12-09
- login_form: return OK for mobile IE 10, which also ignores content for
FORBIDDEN response.
- test .pl registry scripts: do not try to load mod_perl.pm
- escape html tags in destination.
- fix abstract in FAQ pod.
3.19 2012-12-28
- split out CGI data handling into ::AuthCookie::Params modules
- use Apache::Request/Apache2::Request from libapreq if available. Otherwise,
fall back to CGI.pm for handling CGI data.
- improve "removed cookie" debug log message
- add dependencies: autobox, Class::Load
- allow username to be '0'
- login_form: return OK for SymbianOS, which ignores content for FORBIDDEN responses.
- add login_form_status() to override HTTP status returned by login form
- recognize_user: return DECLINED if user is not recognized
3.18 2011-01-24
- remove 3.17's test skip hacks, and bump Apache::Test prerequisite to v1.35
which fixes this issue.
- fix MANIFEST.SKIP to ignore generated t/conf/mime.types
- remove dist.ini, weaver.ini from dists
- fixed t/real.t to use correct -withtestmore import syntax
- rename sample authcookie handlers to Sample::Apache and Sample::Apache2
namespaces
3.17 2011-01-19
- skip the test suite if running as root. Apache::Test 1.34 fails the test
suite if running as root instead of skipping it. By skipping, AuthCookie
can be installed via CPAN.pm as root.
3.16 2011-01-19
- require Apache::Test 1.32 - fixes ubuntu build issue
- remove mod_perl/mod_perl2 related prereq's from META.yml. The correct mod
perl version is not known until Makefile.PL is run. CPAN.pm should not
try to install either one until it is known which one is appropriate.
(RT 64926)
3.15 2010-08-27
- enable Dist::Zilla Manifest plugin
- add FAQ
- add FAQ entry on how to protect an entire site/document root
- recognize_user: return DECLINED if user is already set
- refactor P3P header generation into send_p3p($r) so subclasses can overload it
3.14 2010-04-12
- MP2: doc updates: remove beta warnings, change Apache::AuthCookie to
Apache2::Authcookie where appopriate.
- docs: change my email to my cpan address
- docs: remove POST limitations reference (handled by POST to GET conversion)
- sign dist with Module::Signature
- add signature test
- MP1: perltidy Apache::AuthCookie sources.
- update mod_perl2 prereq version (still 2.0.0 RC5, but version number was
incorrect in Makefile.PL)
- use Dist::Zilla for building the dist
3.13 2010-04-12
- removed: bad dist
Version: 3.12
- Makefile.PL If no mod_perl version is found, just require mod_perl2.
This makes sure that CPAN testers will get the right dependencies.
login fails.
- bug fix: use of Apache2::URI::unescape_url() does not handle
'+' to ' ' conversion. This caused problems for credentials
that contain spaces.
- MP2: remove mod_perl features from "use mod_perl2" line. This is
no longer supported by mod_perl2.
- MP2: _get_form_data() - switch to CGI.pm to handle form data (fixes
several form data handling bugs)
- In a subrequest, copy $r->prev->user to $r->user (or r->connection->user
for MP1).
- remove Apache2::AuthCookie::Util - no longer necessary
- multi-valued form fields are now handled properly in POST -> GET conversion
- MP2: require CGI.pm 3.12 or later
Version: 3.08
- fix "authorize user" error log that was missing a debug level check
(thanks Barry)
- fix test cases 3, 6, 18 for Win32
- clean up t/real.t
Version: 3.07
*** mod_perl2 users: THIS RELEASE IS INCOMPATIBLE WITH PAST RELEASES ***
*** If you are running mod_perl2, you must update to at least ***
*** mod_perl 2.0.0 RC5. The mod_perl2 version of AuthCookie has been ***
*** renamed to Apache2::AuthCookie ***
** MP2: RENAME AuthCookie.pm.mp2 to Apache2::AuthCookie.
- MP2: Update module, and tests for mod_perl 2.0.0 RC5. mod_perl2 users
MUST use Apache2::AuthCookie now.
- Require Apache::Test 1.22
- Add support for ${auth_name}SessionTimeout configuration paramter
which will re-issue the ticket with the expires parameter set to the
value of this configuration setting for each request. This is useful for
idle-timeout.
- POD fixes.
- MP2: fix uninitialized warnings if no POST/GET data (RT 11371)
- make sure recognize_user() returns an Apache constant in all cases.
Returns DECLINED in cases where we were returning undef before.
(Thanks Vivek)
- Add support for MS HttpOnly cookie property.
Version: 3.06
** BUG FIX: AuthNameSatisfy (Any|All) directives were broken. AuthCookie
was using AuthCookieSatisfy rather than ${auth_name}Satisfy. If you
used this feature and had an "AuthCookieSatisfy" directive in your
config file, you MUST change this to ${auth_name}Satisfy.
E.g.: "WhateverSatisfy All"
- created better test cases for AuthNameSatisfy directives.
- when redirecting, set Location with headers_out() not err_headers_out().
apache prefers Location in headers_out, even if the status code is not
200.
- MP2: Apache::unescape_url() -> Apache::URI::unescape_url()
- check for mod_perl 1.9913 or later for Apache::URI (Frederick Moyer)
- Remove set status in login.pl which caused malformed custom error
document (Frederick Moyer)
- Add support for ${auth_name}CookieName to change the name of the cookie
used for each auth name. Default remains ${auth_name}_${auth_type} if
not set.
- make some debug log_error() calls conditional on $debug
Version: 3.05
- Fix POD documentation bug (thanks Steve van der Burg)
- login(): set Location header with err_headers_out rather than headers_out
(Casey West)
- put cookie removal code in remove_cookie() method, put cache handling
code in handle_cache() (Mark A. Hershberger)
Version: 3.02
- Add support for AuthNameSatisfy directive (can be Any/All, default: Any)
- Move cookie path setting into get_cookie_path() so that users can
overload this function if they desire (Thanks Raj Chandran)
- POST -> GET conversion was broken (r->content called twice). Fixed.
Version: 3.01
- adopted support for custom_errors() hook from michael@bizsystems.com.
- Fixed incorrect documentation in authorize() (thanks to David Young).
- login() handler changes:
o if "destination" isnt in posted data, set AuthCookieReason to
no_cookie and return to login_form (previously just returned
SERVER_ERROR).
o if authen_cred() returns false, set AuthCookieReason to
bad_credentials and return to the login form.
o try to handle POST -> GET conversion.
- CGI::Util dependency removed (these are internal subroutines for CGI.pm)
- ${AuthName}Path will default to "/" if it is not specified (MSIE 6.0
wont set cookies without path)
- fix login() handler change so that destination doesnt get lost on
subsequent login attempts (thanks Phillip Molter)
Version: 3.00
- New maintiner: Michael Schout <mschout@gkg.net>
numbers jumped a bit.)
Made some minor documentation updates.
Version: 2.009 Date: 2000/06/14 15:54:00
*** empty log message ***
Version: 2.008 Date: 2000/06/14 15:36:12
Instead of replacing the Set-Cookie header when we set the cookie, add
to it. This means we won't clobber other folks' unrelated cookies
when we set ours. It also means you need at least mod_perl version
1.24 (I think). [rlocke@infiniteinfo.com (Robert Locke)]
Version: 2.007.002.001 Date: 2000/05/14 18:06:30
Added a PerlSetVar *Cache parameter that you can set to a true value
to allow cacheing. Also removed cache control from regular requests -
cacheing still happens on login & logout. [asparks@cpd.harris.com
(Alan Sparks) and dtaylor@vialogix.com (Drew Taylor)]
[michael@bizsystems.com (Michael)]
Version: 2.006 Date: 2000/03/26 18:28:32
Added the key() method, which will return the user's current session
key, if any. This can be handy inside a method that implements a
C<require> directive check (like the C<species> method discussed
above) if you put any extra information like clearances or whatever
into the session key.
Added method-by-method documentation for each method in AuthCookie.
Version: 2.005 Date: 2000/03/24 15:20:30
Removed the deprecated methods ->authen and ->authz. If you have
configurations that use these methods, you must change to the newer
->authenticate and ->authorize methods.
Changed a couple of 'Sample's in the documentation to
'Sample::AuthCookieHandler'. [asparks@cpd.harris.com (Alan Sparks)]
Version: 2.004 Date: 2000/03/15 20:53:20
Added documentation about the ability to set cookie domains. That
ability actually appeared in 2.002, but I forgot to document it or add
notes to the Changes file.
Version: 2.003 Date: 2000/03/14 21:08:02
Now returns FORBIDDEN instead of AUTH_REQUIRED when authorization
LICENSE
MANIFEST
MANIFEST.SKIP
META.json
META.yml
Makefile.PL
README
README.apache-2.4.pod
README.modperl2
SIGNATURE
lib/Apache/AuthCookie.pm
lib/Apache/AuthCookie/FAQ.pod
lib/Apache/AuthCookie/Params.pm
lib/Apache/AuthCookie/Params/Base.pm
lib/Apache/AuthCookie/Params/CGI.pm
lib/Apache/AuthCookie/Util.pm
lib/Apache2/AuthCookie.pm
lib/Apache2/AuthCookie/Base.pm
lib/Apache2/AuthCookie/Params.pm
lib/Apache2_4/AuthCookie.pm
scripts/docker-shell
scripts/docker-smoke
scripts/dzil-build
scripts/perlbrew-smoke
scripts/run-docker-tests
t/Skeleton/AuthCookieHandler.pm
t/TEST.PL
t/author-pod-syntax.t
t/author-signature.t
t/conf/extra.conf.in
t/htdocs/docs/authall/get_me.html
t/htdocs/docs/authany/get_me.html
t/htdocs/docs/cookiename/get_me.html
t/htdocs/docs/echo-user.pl
t/htdocs/docs/echo_cookie.pl
t/htdocs/docs/index.html
t/htdocs/docs/login.pl
t/htdocs/docs/logout.pl
t/htdocs/docs/myuser/get_me.html
t/htdocs/docs/protected/echo_user.pl
t/htdocs/docs/protected/enforce-local/no-default/index.html
t/htdocs/docs/protected/enforce-local/with-default/index.html
t/htdocs/docs/protected/get_me.html
t/htdocs/docs/protected/index.html
t/htdocs/docs/stimeout/get_me.html
t/lib/Sample/Apache/AuthCookieHandler.pm
t/lib/Sample/Apache2/AuthCookieHandler.pm
t/lib/Sample/Apache2_4/AuthCookieHandler.pm
t/real.t
t/signature.t
t/startup.pl
t/util.t
],
"dynamic_config" : 1,
"generated_by" : "Dist::Zilla version 6.031, CPAN::Meta::Converter version 2.150010",
"license" : [
"perl_5"
],
"meta-spec" : {
"url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
"version" : 2
},
"name" : "Apache-AuthCookie",
"prereqs" : {
"configure" : {
"requires" : {
"Apache::Test" : "1.39",
"ExtUtils::MakeMaker" : "0"
}
},
"develop" : {
"requires" : {
"Dist::Zilla" : "5",
"WWW::Form::UrlEncoded" : "0"
}
},
"test" : {
"requires" : {
"URI::Escape" : "1.31"
}
}
},
"provides" : {
"Apache2::AuthCookie" : {
"file" : "lib/Apache2/AuthCookie.pm",
"version" : "3.32"
},
"Apache2::AuthCookie::Base" : {
"file" : "lib/Apache2/AuthCookie/Base.pm",
"version" : "3.32"
},
"Apache2::AuthCookie::Params" : {
"file" : "lib/Apache2/AuthCookie/Params.pm",
"version" : "3.32"
},
"Apache2_4::AuthCookie" : {
"file" : "lib/Apache2_4/AuthCookie.pm",
"version" : "3.32"
},
"Apache::AuthCookie" : {
"file" : "lib/Apache/AuthCookie.pm",
"version" : "3.32"
},
"Apache::AuthCookie::Params" : {
"file" : "lib/Apache/AuthCookie/Params.pm",
"version" : "3.32"
},
"Apache::AuthCookie::Params::Base" : {
"file" : "lib/Apache/AuthCookie/Params/Base.pm",
"version" : "3.32"
},
"Apache::AuthCookie::Params::CGI" : {
"file" : "lib/Apache/AuthCookie/Params/CGI.pm",
"version" : "3.32"
},
"Apache::AuthCookie::Util" : {
"file" : "lib/Apache/AuthCookie/Util.pm",
"version" : "3.32"
}
},
"release_status" : "stable",
"resources" : {
"bugtracker" : {
"web" : "https://github.com/mschout/apache-authcookie/issues"
},
"homepage" : "https://github.com/mschout/apache-authcookie",
"repository" : {
URI::Escape: '1.31'
configure_requires:
Apache::Test: '1.39'
ExtUtils::MakeMaker: '0'
dynamic_config: 1
generated_by: 'Dist::Zilla version 6.031, CPAN::Meta::Converter version 2.150010'
license: perl
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
version: '1.4'
name: Apache-AuthCookie
provides:
Apache2::AuthCookie:
file: lib/Apache2/AuthCookie.pm
version: '3.32'
Apache2::AuthCookie::Base:
file: lib/Apache2/AuthCookie/Base.pm
version: '3.32'
Apache2::AuthCookie::Params:
file: lib/Apache2/AuthCookie/Params.pm
version: '3.32'
Apache2_4::AuthCookie:
file: lib/Apache2_4/AuthCookie.pm
version: '3.32'
Apache::AuthCookie:
file: lib/Apache/AuthCookie.pm
version: '3.32'
Apache::AuthCookie::Params:
file: lib/Apache/AuthCookie/Params.pm
version: '3.32'
Apache::AuthCookie::Params::Base:
file: lib/Apache/AuthCookie/Params/Base.pm
version: '3.32'
Apache::AuthCookie::Params::CGI:
file: lib/Apache/AuthCookie/Params/CGI.pm
version: '3.32'
Apache::AuthCookie::Util:
file: lib/Apache/AuthCookie/Util.pm
version: '3.32'
recommends:
WWW::Form::UrlEncoded::XS: '0'
requires:
Carp: '0'
Class::Load: '0.03'
Encode: '0'
HTTP::Body: '0'
Hash::MultiValue: '0'
Test::More: '0.98'
Makefile.PL view on Meta::CPAN
# This Makefile.PL for Apache-AuthCookie was generated by
# Dist::Zilla::Plugin::MakeMaker::ApacheTest 0.04
# and Dist::Zilla::Plugin::MakeMaker::Awesome 0.49.
# Don't edit it but the dist.ini and plugins used to construct it.
use strict;
use warnings;
use ExtUtils::MakeMaker;
# figure out if mod_perl v1 or v2 is installed. DynamicPrereqs in the
Makefile.PL view on Meta::CPAN
# configure Apache::Test
test_configure();
my %WriteMakefileArgs = (
"ABSTRACT" => "Perl Authentication and Authorization via cookies",
"AUTHOR" => "Michael Schout <mschout\@cpan.org>",
"CONFIGURE_REQUIRES" => {
"Apache::Test" => "1.39",
"ExtUtils::MakeMaker" => 0
},
"DISTNAME" => "Apache-AuthCookie",
"LICENSE" => "perl",
"NAME" => "Apache::AuthCookie",
"PREREQ_PM" => {
"Carp" => 0,
"Class::Load" => "0.03",
"Encode" => 0,
"HTTP::Body" => 0,
"Hash::MultiValue" => 0,
"Test::More" => "0.98",
"URI" => "1.36",
"WWW::Form::UrlEncoded" => 0
},
OVERVIEW
Apache::AuthCookie allows you to intercept a user's first unauthenticated
access to a protected document. The user will be presented with a custom
form where they can enter authentication credentials. The credentials are
posted to the server where AuthCookie verifies them and returns a session
key.
The session key is returned to the user's browser as a cookie. As a cookie,
the browser will pass the session key on every subsequent accesses.
AuthCookie will verify the session key and re-authenticate the user.
All you have to do is write a custom module that inherits from AuthCookie.
See the POD documentation for more details.
INSTALLATION
This module uses the Apache::Test framework for testing. As a result, any
other Apache::Test parameters can be used when generating the Makefile.
perl Makefile.PL -apxs /usr/sbin/apxs
make
make test
README.apache-2.4.pod view on Meta::CPAN
=head1 APACHE 2.4 PORTING NOTES
=head2 VERY IMPORTANT!!!
Apache 2.4 has a B<VERY> different authentication API from previous versions.
You will not be able to simply ugrade apache and upgrade AuthCookie in order to
migrate to Apache 2.4. You will also need to port your AuthCookie subclass
over to the Apache 2.4 API, and update your Apache configuration for Apache
2.4.
This document attempts to help you understand the changes required and
how to port your module over to Apache 2.4. If your subclass stopped working
when you migrated to Apache 2.4, please make sure you have read and understand
everything in this document before filing a bug report.
=head2 Changes Required to Run Under Apache 2.4
README.apache-2.4.pod view on Meta::CPAN
=item Mod Perl
You need at least C<mod_perl> version 2.0.9, which is the first official
release to support Apache 2.4.
=item Apache::Test
You need Apache::Test version 1.39 or later. Previous versions do not define
the constant C<APACHE2_4> which is needed for the test suite.
=item Your AuthCookie Subclass
=over 4
=item *
You must not call authcookie's authorize() method. Authorization is done using
AuthzProvider's under Apache 2.4 and these work very different from previous
apache versions. If you are simply doing simple things such as
C<Require user ...> or C<Require valid-user> in your C<httpd.conf>, then you
likely do not need an authorization provider at all. Apache 2.4 handles these
README.apache-2.4.pod view on Meta::CPAN
C<user> and C<valid-user> requirements for you in C<mod_authz_user.c>.
=item *
If you are C<Require>'ing anything other than C<valid-user> or C<user ...> then
you will need to write your own Authz Provider method and register it with Apache.
Authz Providers are the Apache 2.4 equivalent of a C<PerlAuthzHandler> method.
Each one implements a specific requirement. E.g.:
PerlAddAuthzProvider species My::AuthCookieHandler->authz_species
Will be called to handle a
Require species klingon
Directive.
It is important to know that Authz Providers are called B<twice> for
a request. First, the authz provider is called before authentication has been
processed to check for anonymous access. In this method call, C<< $r->user >>
README.apache-2.4.pod view on Meta::CPAN
internally via C<mod_authz_user.c>
=item ${auth_name}Satisfy
Satisfy support is removed as it is no longer needed with Apache 2.4.
You are expected to use C<RequireAll> or C<RequireAny> instead.
e.g.:
PerlAddAuthzProvider species Your::AuthCookieHandler->authz_species_handler
<RequireAll>
Require valid-user
Require species klingon
</RequireAll>
see: L<https://httpd.apache.org/docs/2.4/howto/auth.html#reqaccessctrl>
=item Unauthorized User HTTP Response Code
README.apache-2.4.pod view on Meta::CPAN
This is normal behaviour under Apache 2.4. This is to accomodate for
authorization of anonymous access. You are expected to return
C<Apache2::Const::AUTHZ_DENIED_NO_USER> IF C<< $r->user >> has not yet been set
if you want authentication to proceed. Your authz handler will be called a
second time after the user has been authenticated.
=item *
I get an error like C<Can't locate object method "requires" via package Apache2::RequestRec ...>
This is because you called C<AuthCookie>'s C<authorize()> method, which is illegal under Apache 2.4. This could either be because your C<AuthCookie> subclass explicitly called C<authorize()>, or (more likely) because your C<httpd.conf> contains a li...
PerlAuthzHandler My::AuthCookie->authorize
You should remove lines from C<httpd.conf> that call C<authorize>, and your
subclass should not be calling authorize().
If you need to do custom autorization, you need to write an authz provider
instead.
=item *
My log shows an entry like:
README.modperl2 view on Meta::CPAN
note that in mod_perl 2.0.0 RC5 many packages were reneamed. See the mod_perl
documentation for updating your code for 2.0.0 RC5.
*****
Notes for migrating from mod_perl version 1.x to mod_perl version 2:
API changes:
In order to avoid requiring the GlobalRequest option under mod_perl 2, the
interface to several of the public AuthCookie methods needed to change. Every
method that called Apache->request internally, now expects $r to be passed in
as the first argument. The affected methods are:
modperl 1.x API modperl 2.x API
-------------- ----------------
handle_cache() handle_cache($r)
remove_cookie() remove_cookie($r)
login_form() login_form($r)
send_cookie($ses_key) send_cookie($r, $ses_key)
key() key($r)
So, for example, instead of $auth_type->login_form(), you now need to call
$auth_type->login_form($r).
Also Note that the Apache interface for retrieving the auth type and username
has changed in mod_perl 2, so you will need to update these calls in your
AuthCookie subclass as well:
modperl 1.x modperl 2.x
-------------------- ----------------
$r->auth_type $r->ap_auth_type
$r->connection->user $r->user
$Id$
SHA256 d904278d5ffc624a31088be20c19ba56989cb08e6badc5c249b95ba418c3ac7c Changes
SHA256 eaa5dc941fbfcaaf2943b5909a0f98d6c4b76cc54c1d85ec7005c9331c6263fc LICENSE
SHA256 380683698c84a3760f8772c74fdc41c7393cb09bcff092d0817be8edb227a21d MANIFEST
SHA256 2356950968e50ccff308dbfd3ff962b7d82295614376239596305108fe6dfb41 MANIFEST.SKIP
SHA256 9e407feaef0f3ca707ed5361b4d2d980295ef237e37ea288fda68a1abc7755fc META.json
SHA256 a9886ecc8997b9cfdefe5ed15ff18a9ed5fb16c7400d7c1e837d6da5354a5c93 META.yml
SHA256 b71c23cf575123ce22540f776e4ed0b78451bf406bfcb646da2e01aa4a079da4 Makefile.PL
SHA256 f494b0a37e5df7b8352400b40d5874e84e78f931e4f258150bd5d1a0895c2153 README
SHA256 6ce7dbf6d4d6ed49e1a1cb5393826e4afe23c6df28458271cbd77821803b7e53 README.apache-2.4.pod
SHA256 4d69214e14598566d2413e01f41645fec55783444d2d0f842adb7113682016bc README.modperl2
SHA256 d42f172648a42aea6e441a2f5c1207fba1d10c55644b0a0cb32abddceec04657 lib/Apache/AuthCookie.pm
SHA256 f25ba599ee6f9b2b318a73793011e5972ffa9b60e0fd0e508b49f4d36e640bba lib/Apache/AuthCookie/FAQ.pod
SHA256 194a3bf1b5d67b3c02500b67d59485918290b20b6c55eca367f62f95fbdbb4b4 lib/Apache/AuthCookie/Params.pm
SHA256 4f9980d017863a66cd0b2b0a2714de396e46c94aa40dfb0ae1d188f8253247d0 lib/Apache/AuthCookie/Params/Base.pm
SHA256 9c36757edaad85f1fc1c75e37257dcddcad6a4303e7cd1bc084253671dfc18ed lib/Apache/AuthCookie/Params/CGI.pm
SHA256 ccc52dd9ff9feefc1e5dbc92c34a8ad2d87b7ad3cb3794405a9123dc4736cc7d lib/Apache/AuthCookie/Util.pm
SHA256 430afa6d541ed8a6c48c115f6248a0ceabfbc2575b252bd38b60c488404a503f lib/Apache2/AuthCookie.pm
SHA256 dca8541e5d8e6deafa947b8c45fd0c23eb01bc465e9414c214b5534fe48e3a78 lib/Apache2/AuthCookie/Base.pm
SHA256 53a8731dc70fbdd868d4aeebaad27cd1a857edc16a03380213afef27a881fd37 lib/Apache2/AuthCookie/Params.pm
SHA256 f7fd2a20ad89874aa609ff60cbb004fe45d9dda08d93fb29a98f35b023594b17 lib/Apache2_4/AuthCookie.pm
SHA256 a0834bbd5d684bf83a0728d4974ca0dfffa58b447e9c0af17d9cac3f5ada4fce scripts/docker-shell
SHA256 dbb0cf12d53339f18f4b0fc48492f322eb6281b19b8e0aebc99a33bc8489bf37 scripts/docker-smoke
SHA256 0dbdb49718f5db2b8e48ce2711a82934558d12c0f771c90b049f8f59625a6e9b scripts/dzil-build
SHA256 44fb9c0944f5ec13ea2bcc4cb4c43016709a7e0302c087d3ed2599ba50893788 scripts/perlbrew-smoke
SHA256 5d32315e87d7c7b413bb7c0753e1f5a7ef9b1cff7c9e72b17dba5e10c44f3940 scripts/run-docker-tests
SHA256 2939b9cf6c64f08eed542e44b2c3a15fd181f8bbbcfa8a8cf5e93535453648ee t/Skeleton/AuthCookieHandler.pm
SHA256 65c85e5cdeb0322a90941de0a0e1a59ca91e78116c355997974dbd388649d022 t/TEST.PL
SHA256 305c657c6b73f10767a0ea286b8a73d693940f4cbb8b6a0a4d34e2b5a1c04635 t/author-pod-syntax.t
SHA256 9a339818bc8fe7f23595b06538321f26436cb3318c81446d88cd8af2d2ff4806 t/author-signature.t
SHA256 d4cc391a3f1e9de6c37b4ee5b7ffd233cb710fafdcc5aea30152f266fe6ddc79 t/conf/extra.conf.in
SHA256 8fbe5a29dc8cb1fcb9e70f2c1b6ff75982f7c9c2be961f00cb48b782101c7b04 t/htdocs/docs/authall/get_me.html
SHA256 8fbe5a29dc8cb1fcb9e70f2c1b6ff75982f7c9c2be961f00cb48b782101c7b04 t/htdocs/docs/authany/get_me.html
SHA256 8fbe5a29dc8cb1fcb9e70f2c1b6ff75982f7c9c2be961f00cb48b782101c7b04 t/htdocs/docs/cookiename/get_me.html
SHA256 3246637fff49f89292615d467d1bd7835b80504aaa3ad6fb778fba2ecc8cf33d t/htdocs/docs/echo-user.pl
SHA256 405148db912159960b11e6ac0b8fb70421b72f9440b13086f98024c97460db1f t/htdocs/docs/echo_cookie.pl
SHA256 40cdab7d7ba6df2974598bb41d91a26b0832a4d522d34a7eafe9cebbf2d2d5f8 t/htdocs/docs/index.html
SHA256 c1a0ed710129c5093c1d6a6ec2de438210e560d8d7e9ede55a858d3d68302749 t/htdocs/docs/login.pl
SHA256 082d40d4c9ae4c1aaf0d781467d0a598842867adbec7b3d94fbcd45f4aa2c0e6 t/htdocs/docs/logout.pl
SHA256 8fbe5a29dc8cb1fcb9e70f2c1b6ff75982f7c9c2be961f00cb48b782101c7b04 t/htdocs/docs/myuser/get_me.html
SHA256 3a6b03416abd505d212d9ab7a59412fa646818bfbd453f94620773e97b2a6e3e t/htdocs/docs/protected/echo_user.pl
SHA256 96d4b5bef3639ecd0927cb4ca573c35aa8d5138987b9499a18000e30d3b9a76c t/htdocs/docs/protected/enforce-local/no-default/index.html
SHA256 75206ec8ac9c5cb584759d920c9692bd81ac5f20dbc6e82da4c86f62fb9f4f25 t/htdocs/docs/protected/enforce-local/with-default/index.html
SHA256 8fbe5a29dc8cb1fcb9e70f2c1b6ff75982f7c9c2be961f00cb48b782101c7b04 t/htdocs/docs/protected/get_me.html
SHA256 b283bff783d9827d49fa6cfce29549b440427d424147e0b38668cdf7220baa7c t/htdocs/docs/protected/index.html
SHA256 8fbe5a29dc8cb1fcb9e70f2c1b6ff75982f7c9c2be961f00cb48b782101c7b04 t/htdocs/docs/stimeout/get_me.html
SHA256 673ad34b62a581ad8d6bf49767d7620a1422e15b7a35866f94060046da8ff6c5 t/lib/Sample/Apache/AuthCookieHandler.pm
SHA256 7193cd984b296e7faf3823ee3ac21ddd3b5f8b143430a3f19cd371283f63b202 t/lib/Sample/Apache2/AuthCookieHandler.pm
SHA256 cab902376ec346269c1730d1f8f912fd184f5f02e41cfde6fdb08e53c3c46cd5 t/lib/Sample/Apache2_4/AuthCookieHandler.pm
SHA256 48f7e5280c23e8fc8514d83e1a5b10b0ba8ec993613c047736a9cbb45aed7da7 t/real.t
SHA256 ee23dab66cb03f5c839f80d39725dc461b6f4d36c838d07451b05ae6a9aad1dd t/signature.t
SHA256 94c586ddeab7f04a4f63b0da1d06113dfa3714df51aa759ca40a7690a8787e64 t/startup.pl
SHA256 ac9cae5e46a673b730243cbfd1b77e10a8f743b3821faf3d029ff56a203bf026 t/util.t
-----BEGIN PGP SIGNATURE-----
iQJFBAEBAwAvFiEE2EtuRfhGgngE8PsARAzvLrlUzY4FAmbAurYRHG1zY2hvdXRA
Y3Bhbi5vcmcACgkQRAzvLrlUzY5uuxAAo0S+tkr6t2t0u8HtxsOu8L/Pmkd+ubd6
maeuILXY3QBEWjlu4LJVZjaJ2JJI2aM6Bh8tp2wxKs61aotyF4zl/7fkHyrCzgQM
yd1J37xjCfQQwvajD8cPi3f7LKmXSqttNhs9WEtmjW4BIczw6ZSCfyXT6J0eX0B9
lib/Apache/AuthCookie.pm view on Meta::CPAN
package Apache::AuthCookie;
$Apache::AuthCookie::VERSION = '3.32';
# ABSTRACT: Perl Authentication and Authorization via cookies
use strict;
use Carp;
use mod_perl qw(1.07 StackedHandlers MethodHandlers Authen Authz);
use Apache::Constants qw(:common M_GET FORBIDDEN OK REDIRECT);
use Apache::AuthCookie::Params;
use Apache::AuthCookie::Util qw(is_blank is_local_destination);
use Apache::Util qw(escape_uri);
use Apache::URI;
use Encode ();
sub recognize_user ($$) {
my ($self, $r) = @_;
# only check if user is not already set
return DECLINED unless is_blank($r->connection->user);
my $debug = $r->dir_config("AuthCookieDebug") || 0;
my ($auth_type, $auth_name) = ($r->auth_type, $r->auth_name);
return DECLINED if is_blank($auth_type) or is_blank($auth_name);
return DECLINED if is_blank($r->header_in('Cookie'));
my $cookie_name = $self->cookie_name($r);
my ($cookie) = $r->header_in('Cookie') =~ /$cookie_name=([^;]+)/;
$r->log_error("cookie $cookie_name is $cookie") if $debug >= 2;
return DECLINED unless $cookie;
my ($user, @args) = $auth_type->authen_ses_key($r, $cookie);
if (!is_blank($user) and scalar @args == 0) {
$r->log_error("user is $user") if $debug >= 2;
# if SessionTimeout is on, send new cookie with new Expires.
if (my $expires = $r->dir_config("${auth_name}SessionTimeout")) {
$self->send_cookie($cookie, { expires => $expires });
lib/Apache/AuthCookie.pm view on Meta::CPAN
return is_blank($user) ? DECLINED : OK;
}
sub cookie_name {
my ($self, $r) = @_;
my $auth_type = $r->auth_type;
my $auth_name = $r->auth_name;
my $cookie_name = $r->dir_config("${auth_name}CookieName")
|| "${auth_type}_${auth_name}";
return $cookie_name;
}
sub encoding {
my ($self, $r) = @_;
my $auth_name = $r->auth_name;
lib/Apache/AuthCookie.pm view on Meta::CPAN
$r->err_header_out(Pragma => 'no-cache');
}
}
sub remove_cookie {
my $self = shift;
my $r = Apache->request;
my $debug = $r->dir_config("AuthCookieDebug") || 0;
my $cookie_name = $self->cookie_name($r);
my $str = $self->cookie_string(
request => $r,
key => $cookie_name,
value => '',
expires => 'Mon, 21-May-1971 00:00:00 GMT'
);
$r->err_headers_out->add("Set-Cookie" => "$str");
$r->log_error("removed cookie $cookie_name") if $debug >= 2;
}
# convert current request to GET
sub _convert_to_get {
my ($self, $r) = @_;
return unless $r->method eq 'POST';
my $debug = $r->dir_config("AuthCookieDebug") || 0;
$r->log_error("Converting POST -> GET") if $debug >= 2;
my $args = $self->params($r);
my @pairs = ();
for my $name ($args->param) {
# we dont want to copy login data, only extra data
next if $name eq 'destination'
lib/Apache/AuthCookie.pm view on Meta::CPAN
$r->method('GET');
$r->method_number(M_GET);
$r->headers_in->unset('Content-Length');
}
sub params {
my ($self, $r) = @_;
return Apache::AuthCookie::Params->new($r);
}
sub login ($$) {
my ($self, $r) = @_;
my $debug = $r->dir_config("AuthCookieDebug") || 0;
my ($auth_type, $auth_name) = ($r->auth_type, $r->auth_name);
my $params = $self->params($r);
$self->_convert_to_get($r) if $r->method eq 'POST';
my $destination = $params->param('destination');
my $default_destination = $r->dir_config("${auth_name}DefaultDestination");
if (is_blank($destination)) {
if (!is_blank($default_destination)) {
$destination = $default_destination;
$r->log_error("destination set to $destination");
}
else {
$r->log_error("No key 'destination' found in form data");
$r->subprocess_env('AuthCookieReason', 'no_cookie');
return $auth_type->login_form;
}
}
if ($r->dir_config("${auth_name}EnforceLocalDestination")) {
my $current_url = Apache::URI->parse($r)->unparse;
unless (is_local_destination($destination, $current_url)) {
$r->log_error("non-local destination $destination detected for uri ",$r->uri);
if (is_local_destination($default_destination, $current_url)) {
$destination = $default_destination;
$r->log_error("destination changed to $destination");
}
else {
$r->log_error("Returning login form: non local destination: $destination");
$r->subprocess_env('AuthCookieReason', 'no_cookie');
return $auth_type->login_form($r);
}
}
}
# Get the credentials from the data posted by the client
my @credentials;
for (my $i = 0 ; defined $params->param("credential_$i") ; $i++) {
my $key = "credential_$i";
my $val = $params->param("credential_$i");
lib/Apache/AuthCookie.pm view on Meta::CPAN
push @credentials, $val;
}
# save creds in pnotes in case login form script wants to use them.
$r->pnotes("${auth_name}Creds", \@credentials);
# Exchange the credentials for a session key.
my $ses_key = $self->authen_cred($r, @credentials);
unless ($ses_key) {
$r->log_error("Bad credentials") if $debug >= 2;
$r->subprocess_env('AuthCookieReason', 'bad_credentials');
$r->uri($self->untaint_destination($destination));
return $auth_type->login_form;
}
if ($debug >= 2) {
if (defined $ses_key) {
$r->log_error("ses_key $ses_key");
}
else {
$r->log_error("ses_key undefined");
lib/Apache/AuthCookie.pm view on Meta::CPAN
$r->header_out(Location => $self->untaint_destination($destination));
return REDIRECT;
}
sub untaint_destination {
my ($self, $dest) = @_;
return Apache::AuthCookie::Util::escape_destination($dest);
}
sub logout($$) {
my ($self, $r) = @_;
my $debug = $r->dir_config("AuthCookieDebug") || 0;
$self->remove_cookie;
$self->handle_cache;
#my %args = $r->args;
#if (exists $args{'redirect'}) {
# $r->err_header_out("Location" => $args{'redirect'});
# return REDIRECT;
#} else {
# $r->status(200);
# return OK;
#}
}
sub authenticate ($$) {
my ($auth_type, $r) = @_;
my $auth_user;
my $debug = $r->dir_config("AuthCookieDebug") || 0;
$r->log_error("auth_type " . $auth_type) if ($debug >= 3);
unless ($r->is_initial_req) {
if (defined $r->prev) {
# we are in a subrequest. Just copy user from previous request.
# encoding would have been handled in prev req, so do not encode here.
$r->connection->user($r->prev->connection->user);
}
return OK;
lib/Apache/AuthCookie.pm view on Meta::CPAN
# Ok, the AuthType is $auth_type which we handle, what's the authentication
# realm's name?
my $auth_name = $r->auth_name;
$r->log_error("auth_name " . $auth_name) if $debug >= 2;
unless ($auth_name) {
$r->log_reason("AuthName not set, AuthType=$auth_type", $r->uri);
return SERVER_ERROR;
}
# Get the Cookie header. If there is a session key for this realm, strip
# off everything but the value of the cookie.
my $cookie_name = $auth_type->cookie_name($r);
my ($ses_key_cookie) =
($r->header_in("Cookie") || "") =~ /$cookie_name=([^;]+)/;
$ses_key_cookie = "" unless defined($ses_key_cookie);
$r->log_error("ses_key_cookie " . $ses_key_cookie) if ($debug >= 1);
$r->log_error("uri " . $r->uri) if ($debug >= 2);
if ($ses_key_cookie) {
my ($auth_user, @args) =
$auth_type->authen_ses_key($r, $ses_key_cookie);
if (!is_blank($auth_user) and scalar @args == 0) {
lib/Apache/AuthCookie.pm view on Meta::CPAN
}
elsif (scalar @args > 0 and $auth_type->can('custom_errors')) {
return $auth_type->custom_errors($r, $auth_user, @args);
}
else {
# There was a session key set, but it's invalid for some reason. So,
# remove it from the client now so when the credential data is posted
# we act just like it's a new session starting.
$auth_type->remove_cookie;
$r->subprocess_env('AuthCookieReason', 'bad_cookie');
}
}
else {
$r->subprocess_env('AuthCookieReason', 'no_cookie');
}
# They aren't authenticated, and they tried to get a protected
# document. Send them the authen form.
return $auth_type->login_form;
}
sub login_form {
my $self = shift;
lib/Apache/AuthCookie.pm view on Meta::CPAN
return $status;
}
sub login_form_status {
my ($self, $r) = @_;
my $ua = $r->headers_in->get('User-Agent')
or return FORBIDDEN;
if (Apache::AuthCookie::Util::understands_forbidden_response($ua)) {
return FORBIDDEN;
}
else {
return OK;
}
}
sub satisfy_is_valid {
my ($auth_type, $r, $satisfy) = @_;
$satisfy = lc $satisfy;
lib/Apache/AuthCookie.pm view on Meta::CPAN
my ($auth_type, $r) = @_;
my $auth_name = $r->auth_name;
return lc $r->dir_config("${auth_name}Satisfy") || 'all';
}
sub authorize ($$) {
my ($auth_type, $r) = @_;
my $debug = $r->dir_config("AuthCookieDebug") || 0;
$r->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->log_error($auth_type . " auth type is " . $r->auth_type)
if ($debug >= 3);
return DECLINED;
}
lib/Apache/AuthCookie.pm view on Meta::CPAN
my $cookie = $self->cookie_string(
request => $r,
key => $cookie_name,
value => $ses_key,
%$cookie_args
);
# add P3P header if user has configured it.
$self->send_p3p($r);
$r->err_headers_out->add("Set-Cookie" => $cookie);
}
sub send_p3p {
my ($self, $r) = @_;
my $auth_name = $r->auth_name;
if (my $p3p = $r->dir_config("${auth_name}P3P")) {
$r->err_header_out(P3P => $p3p);
lib/Apache/AuthCookie.pm view on Meta::CPAN
my $r = $p{request};
$p{value} = '' unless defined $p{value};
my $string = sprintf '%s=%s', @p{ 'key', 'value' };
my $auth_name = $r->auth_name;
if (my $expires = $p{expires} || $r->dir_config("${auth_name}Expires")) {
$expires = Apache::AuthCookie::Util::expires($expires);
$string .= "; expires=$expires";
}
$string .= '; path=' . ($self->get_cookie_path($r) || '/');
#$r->log_error("Attribute ${auth_name}Path not set") unless $path;
if (my $domain = $r->dir_config("${auth_name}Domain")) {
$string .= "; domain=$domain";
}
lib/Apache/AuthCookie.pm view on Meta::CPAN
}
return $string;
}
sub key {
my $self = shift;
my $r = Apache->request;
my $allcook = ($r->header_in("Cookie") || "");
my $cookie_name = $self->cookie_name($r);
return ($allcook =~ /(?:^|\s)$cookie_name=([^;]*)/)[0];
}
sub get_cookie_path {
my $self = shift;
my $r = shift || Apache->request;
my $auth_name = $r->auth_name;
lib/Apache/AuthCookie.pm view on Meta::CPAN
}
1;
=pod
=encoding UTF-8
=head1 NAME
Apache::AuthCookie - Perl Authentication and Authorization via cookies
=head1 VERSION
version 3.32
=head1 SYNOPSIS
Make sure your mod_perl is at least 1.24, with StackedHandlers,
MethodHandlers, Authen, and Authz compiled in.
# In httpd.conf or .htaccess:
PerlModule Sample::Apache::AuthCookieHandler
PerlSetVar WhatEverPath /
PerlSetVar WhatEverLoginScript /login.pl
# use to alter how "require" directives are matched. Can be "Any" or "All".
# If its "Any", then you must only match Any of the "require" directives. If
# its "All", then you must match All of the require directives.
#
# Default: All
PerlSetVar WhatEverSatisfy Any
lib/Apache/AuthCookie.pm view on Meta::CPAN
# this is an MS extension. See
# http://msdn.microsoft.com/workshop/author/dhtml/httponly_cookies.asp
PerlSetVar WhatEverHttpOnly 1
# Usually documents are uncached - turn off here
PerlSetVar WhatEverCache 1
# Use this to make your cookies persistent (+2 hours here)
PerlSetVar WhatEverExpires +2h
# Use to make AuthCookie send a P3P header with the cookie
# see http://www.w3.org/P3P/ for details about what the value
# of this should be
PerlSetVar WhatEverP3P "CP=\"...\""
# optional: enforce that the destination argument from the login form is
# local to the server
PerlSetVar WhatEverEnforceLocalDestination 1
# optional: specify a default destination for when the destination argument
# of the login form is invalid or unspecified
PerlSetVar WhatEverDefaultDestination /protected/user/
# These documents require user to be logged in.
<Location /protected>
AuthType Sample::Apache::AuthCookieHandler
AuthName WhatEver
PerlAuthenHandler Sample::Apache::AuthCookieHandler->authenticate
PerlAuthzHandler Sample::Apache::AuthCookieHandler->authorize
require valid-user
</Location>
# These documents don't require logging in, but allow it.
<FilesMatch "\.ok$">
AuthType Sample::Apache::AuthCookieHandler
AuthName WhatEver
PerlFixupHandler Sample::Apache::AuthCookieHandler->recognize_user
</FilesMatch>
# This is the action of the login.pl script above.
<Files LOGIN>
AuthType Sample::Apache::AuthCookieHandler
AuthName WhatEver
SetHandler perl-script
PerlHandler Sample::Apache::AuthCookieHandler->login
</Files>
=head1 DESCRIPTION
B<Apache::AuthCookie> allows you to intercept a user's first
unauthenticated access to a protected document. The user will be
presented with a custom form where they can enter authentication
credentials. The credentials are posted to the server where AuthCookie
verifies them and returns a session key.
The session key is returned to the user's browser as a cookie. As a
cookie, the browser will pass the session key on every subsequent
accesses. AuthCookie will verify the session key and re-authenticate
the user.
All you have to do is write a custom module that inherits from
AuthCookie. Your module is a class which implements two methods:
=over 4
=item C<authen_cred()>
Verify the user-supplied credentials and return a session key. The
session key can be any string - often you'll use some string
containing username, timeout info, and any other information you need
to determine access to documents, and append a one-way hash of those
values together with some secret key.
=item C<authen_ses_key()>
Verify the session key (previously generated by C<authen_cred()>,
possibly during a previous request) and return the user ID. This user
ID will be fed to C<$r-E<gt>connection-E<gt>user()> to set Apache's
idea of who's logged in.
=back
By using AuthCookie versus Apache's built-in AuthBasic you can design
your own authentication system. There are several benefits.
=over 4
=item 1.
The client doesn't *have* to pass the user credentials on every
subsequent access. If you're using passwords, this means that the
password can be sent on the first request only, and subsequent
requests don't need to send this (potentially sensitive) information.
lib/Apache/AuthCookie.pm view on Meta::CPAN
=item 2.
When you determine that the client should stop using the
credentials/session key, the server can tell the client to delete the
cookie. Letting users "log out" is a notoriously impossible-to-solve
problem of AuthBasic.
=item 3.
AuthBasic dialog boxes are ugly. You can design your own HTML login
forms when you use AuthCookie.
=item 4.
You can specify the domain of a cookie using PerlSetVar commands. For
instance, if your AuthName is C<WhatEver>, you can put the command
PerlSetVar WhatEverDomain .yourhost.com
into your server setup file and your access cookies will span all
hosts ending in C<.yourhost.com>.
=item 5.
You can optionally specify the name of your cookie using the C<CookieName>
directive. For instance, if your AuthName is C<WhatEver>, you can put the
command
PerlSetVar WhatEverCookieName MyCustomName
into your server setup file and your cookies for this AuthCookie realm will be
named MyCustomName. Default is AuthType_AuthName.
=item 6.
By default users must satisfy ALL of the C<require> directives. If you
want authentication to succeed if ANY C<require> directives are met, use the
C<Satisfy> directive. For instance, if your AuthName is C<WhatEver>, you can
put the command
PerlSetVar WhatEverSatisfy Any
into your server startup file and authentication for this realm will succeed if
ANY of the C<require> directives are met.
=back
This is the flow of the authentication handler, less the details of the
redirects. Two REDIRECT's are used to keep the client from displaying
the user's credentials in the Location field. They don't really change
AuthCookie's model, but they do add another round-trip request to the
client.
(-----------------------) +---------------------------------+
( Request a protected ) | AuthCookie sets custom error |
( page, but user hasn't )---->| document and returns |
( authenticated (no ) | FORBIDDEN. Apache abandons |
( session key cookie) ) | current request and creates sub |
(-----------------------) | request for the error document. |<-+
| Error document is a script that | |
| generates a form where the user | |
return | enters authentication | |
^------------------->| credentials (login & password). | |
/ \ False +---------------------------------+ |
/ \ | |
/ \ | |
/ \ V |
/ \ +---------------------------------+ |
/ Pass \ | User's client submits this form | |
/ user's \ | to the LOGIN URL, which calls | |
| credentials |<------------| AuthCookie->login(). | |
\ to / +---------------------------------+ |
\authen_cred/ |
\ function/ |
\ / |
\ / |
\ / +------------------------------------+ |
\ / return | Authen cred returns a session | +--+
V------------->| key which is opaque to AuthCookie.*| |
True +------------------------------------+ |
| |
+--------------------+ | +---------------+
| | | | If we had a |
V | V | cookie, add |
+----------------------------+ r | ^ | a Set-Cookie |
| If we didn't have a session| e |T / \ | header to |
| key cookie, add a | t |r / \ | override the |
| Set-Cookie header with this| u |u / \ | invalid cookie|
| session key. Client then | r |e / \ +---------------+
| returns session key with | n | / pass \ ^
| successive requests | | / session \ |
+----------------------------+ | / key to \ return |
| +-| authen_ses_key|------------+
V \ / False
+-----------------------------------+ \ /
| Tell Apache to set Expires header,| \ /
| set user to user ID returned by | \ /
| authen_ses_key, set authentication| \ /
| to our type (e.g. AuthCookie). | \ /
+-----------------------------------+ \ /
V
(---------------------) ^
( Request a protected ) |
( page, user has a )--------------+
( session key cookie )
(---------------------)
* The session key that the client gets can be anything you want. For
lib/Apache/AuthCookie.pm view on Meta::CPAN
The only requirement is that the authen_ses_key function that you
create must be able to determine if this session_key is valid and
map it back to the originally authenticated user ID.
=head1 METHODS
=head2 authen_cred($r, @credentials)
You must define this method yourself in your subclass of
C<Apache::AuthCookie>. Its job is to create the session key that will
be preserved in the user's cookie. The arguments passed to it are:
sub authen_cred ($$\@) {
my $self = shift; # Package name (same as AuthName directive)
my $r = shift; # Apache request object
my @cred = @_; # Credentials from login form
...blah blah blah, create a session key...
return $session_key;
}
lib/Apache/AuthCookie.pm view on Meta::CPAN
look at it later and determine the user's username. You are
responsible for implementing your own session key format. A typical
format is to make a string that contains the username, an expiration
time, whatever else you need, and an MD5 hash of all that data
together with a secret key. The hash will ensure that the user
doesn't tamper with the session key. More info in the Eagle book.
=head2 authen_ses_key($r, $session_key)
You must define this method yourself in your subclass of
Apache::AuthCookie. Its job is to look at a session key and determine
whether it is valid. If so, it returns the username of the
authenticated user.
sub authen_ses_key ($$$) {
my ($self, $r, $session_key) = @_;
...blah blah blah, check whether $session_key is valid...
return $ok ? $username : undef;
}
Optionally, return an array of 2 or more items that will be passed to method
lib/Apache/AuthCookie.pm view on Meta::CPAN
=head2 handle_cache(): void
If C<${auth_name}Cache> is defined, this sets up the response so that the
client will not cache the result. This sents C<no_cache> in the apache request
object and sends the appropriate headers so that the client will not cache the
response.
=head2 remove_cookie(): void
Adds a C<Set-Cookie> header that instructs the client to delete the cookie
immediately.
=head2 params($r): Apache::AuthCookie::Params
Get the params object for this request.
=head2 login($r)
This method handles the submission of the login form. It will call
the C<authen_cred()> method, passing it C<$r> and all the submitted
data with names like C<"credential_#">, where # is a number. These will
be passed in a simple array, so the prototype is
C<$self-E<gt>authen_cred($r, @credentials)>. After calling
lib/Apache/AuthCookie.pm view on Meta::CPAN
=item *
request
The Apache request object
=item *
key
The Cookie name
=item *
value
the Cookie value
=item *
expires (optional)
When the cookie expires. See L<Apache::AuthCookie::Util/expires()>. Uses C<${auth_name}Expires> if not given.
=back
All other cookie settings come from C<PerlSetVar> settings.
=head2 key()
This method will return the current session key, if any. This can be
handy inside a method that implements a C<require> directive check
(like the C<species> method discussed above) if you put any extra
information like clearances or whatever into the session key.
=head2 get_cookie_path(): string
Returns the value of C<PerlSetVar ${auth_name}Path>.
=head1 EXAMPLE
For an example of how to use Apache::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 an Apache::Registry script, or an HTML::Mason
lib/Apache/AuthCookie.pm view on Meta::CPAN
=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/.
=back
In addition, you might want your login page to be able to tell why
the user is being asked to log in. In other words, if the user sent
bad credentials, then it might be useful to display an error message
saying that the given username or password are invalid. Also, it
might be useful to determine the difference between a user that sent
an invalid auth cookie, and a user that sent no auth cookie at all. To
cope with these situations, B<AuthCookie> will set
C<$r-E<gt>subprocess_env('AuthCookieReason')> to one of the following values.
=over 4
=item I<no_cookie>
The user presented no cookie at all. Typically this means the user is
trying to log in for the first time.
=item I<bad_cookie>
The cookie the user presented is invalid. Typically this means that the user
is not allowed access to the given page.
=item I<bad_credentials>
The user tried to log in, but the credentials that were passed are invalid.
=back
You can examine this value in your login form by examining
C<$r-E<gt>prev-E<gt>subprocess_env('AuthCookieReason')> (because it's
a sub-request).
Of course, if you want to give more specific information about why
access failed when a cookie is present, your C<authen_ses_key()>
method can set arbitrary entries in C<$r-E<gt>subprocess_env>.
=head1 THE LOGOUT SCRIPT
If you want to let users log themselves out (something that can't be
done using Basic Auth), you need to create a logout script. For an
example, see t/htdocs/docs/logout.pl. Logout scripts may want to take
advantage of AuthCookie's C<logout()> method, which will set the
proper cookie headers in order to clear the user's cookie. This
usually looks like C<$r-E<gt>auth_type-E<gt>logout($r);>.
Note that if you don't necessarily trust your users, you can't count
on cookie deletion for logging out. You'll have to expire some
server-side login information too. AuthCookie doesn't do this for
you, you have to handle it yourself.
=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.
lib/Apache/AuthCookie.pm view on Meta::CPAN
=over 4
=item *
The internal pure-perl params processing subclass will be used, even if
libapreq is installed. libapreq does not handle encoding.
=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>connection-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
lib/Apache/AuthCookie.pm view on Meta::CPAN
=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 ABOUT SESSION KEYS
Unlike the sample AuthCookieHandler, you have you verify the user's
login and password in C<authen_cred()>, then you do something
like:
my $date = localtime;
my $ses_key = MD5->hexhash(join(';', $date, $PID, $PAC));
save C<$ses_key> along with the user's login, and return C<$ses_key>.
Now C<authen_ses_key()> looks up the C<$ses_key> passed to it and
returns the saved login. I use Oracle to store the session key and
lib/Apache/AuthCookie/FAQ.pod view on Meta::CPAN
# make Dist::Zilla happy.
package Apache::AuthCookie::FAQ;
# ABSTRACT: Frequently Asked Questions about Apache::AuthCookie.
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Apache::AuthCookie::FAQ - Frequently Asked Questions about Apache::AuthCookie.
=head1 VERSION
version 3.32
=head1 DESCRIPTION
This document serves to answer the most frequently asked questions about L<Apache::AuthCookie>.
=head2 How can I protect an entire site (/) with Apache::AuthCookie?
You have to give an Apache C<require> directive that applies to all requests
for B<except> for your login handler. The easiest way to do this is to
override the auth handlers for your login script. For example, if your login
handler is C</LOGIN>, then you need to use something like the following:
<Location />
AuthType My::AuthCookieHandler
AuthName Whatever
PerlAuthenHandler My::AuthCookieHandler->authenticate
PerlAuthzHandler My::AuthCookieHandler->authorize
require valid-user
</Location>
<Location /LOGIN>
PerlAuthenHandler Apache2::Const::OK
PerlAuthzHandler Apache2::Const::OK
</Location>
...
=head1 SOURCE
lib/Apache/AuthCookie/Params.pm view on Meta::CPAN
package Apache::AuthCookie::Params;
$Apache::AuthCookie::Params::VERSION = '3.32';
# ABSTRACT: AuthCookie Params Driver for mod_perl 1.x
use strict;
use warnings;
use base 'Apache::AuthCookie::Params::Base';
use Class::Load qw(try_load_class);
sub _new_instance {
my ($class, $r) = @_;
my $debug = $r->dir_config('AuthCookieDebug') || 0;
my $obj;
if (try_load_class('Apache::Request')) {
$r->server->log_error("params: using Apache::Request") if $debug >= 3;
return Apache::Request->new($r);
}
else {
$r->server->log_error("params: using CGI") if $debug >= 3;
lib/Apache/AuthCookie/Params.pm view on Meta::CPAN
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Apache::AuthCookie::Params - AuthCookie Params Driver for mod_perl 1.x
=head1 VERSION
version 3.32
=head1 SYNOPSIS
Internal Use Only!
=head1 DESCRIPTION
This class handles CGI form data for L<Apache::AuthCookie>. It will try to use
L<Apache::Request> (from libapreq) if it is available. If not, it will fall
back to use L<CGI>.
=head1 SOURCE
The development version is on github at L<https://github.com/mschout/apache-authcookie>
and may be cloned from L<https://github.com/mschout/apache-authcookie.git>
=head1 BUGS
lib/Apache/AuthCookie/Params/Base.pm view on Meta::CPAN
package Apache::AuthCookie::Params::Base;
$Apache::AuthCookie::Params::Base::VERSION = '3.32';
# ABSTRACT: Internal CGI AuthCookie Params Base Class
use strict;
use warnings;
use Class::Load qw(load_class);
use Apache::AuthCookie::Util qw(is_blank);
sub new {
my ($class, $r) = @_;
my $debug = $r->dir_config("AuthCookieDebug") || 0;
# use existing params object if possible
my $obj = $r->pnotes($class);
if (defined $obj) {
return $obj;
}
# if an encoding is in effect, then always use the ::CGI interface because
# libapreq has no support for UTF-8
my $auth_name = $r->auth_name;
lib/Apache/AuthCookie/Params/Base.pm view on Meta::CPAN
}
$r->pnotes($class, $obj);
return $obj;
}
sub _new_instance {
my ($self, $r) = @_;
load_class('Apache::AuthCookie::Params::CGI');
return Apache::AuthCookie::Params::CGI->new($r);
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Apache::AuthCookie::Params::Base - Internal CGI AuthCookie Params Base Class
=head1 VERSION
version 3.32
=head1 SYNOPSIS
Internal Use Only!
=head1 DESCRIPTION
This is the base class for AuthCookie Params drivers.
=head1 METHODS
=head2 new($r)
Constructor. This will generate either an internal
L<Apache::AuthCookie::Params::CGI> object, or, if available, use libapreq2.
Note that libapreq2 will not be used if you turned on C<Encoding> support
because libapreq2 does not have any support for unicode.
=head1 SOURCE
The development version is on github at L<https://github.com/mschout/apache-authcookie>
and may be cloned from L<https://github.com/mschout/apache-authcookie.git>
=head1 BUGS
lib/Apache/AuthCookie/Params/CGI.pm view on Meta::CPAN
package Apache::AuthCookie::Params::CGI;
$Apache::AuthCookie::Params::CGI::VERSION = '3.32';
# ABSTRACT: Internal CGI Params Subclass
use strict;
use warnings;
use Carp ();
use WWW::Form::UrlEncoded qw(parse_urlencoded);
use Hash::MultiValue;
use HTTP::Body;
use Encode ();
lib/Apache/AuthCookie/Params/CGI.pm view on Meta::CPAN
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Apache::AuthCookie::Params::CGI - Internal CGI Params Subclass
=head1 VERSION
version 3.32
=head1 SYNOPSIS
Internal Use Only!
=head1 DESCRIPTION
This is a pure perl implementation of HTTP/CGI parameter processing for Apache::AuthCookie.
=head1 METHODS
=head2 new($r)
Constructor
=head2 request(): scalar
Get the apache request object
lib/Apache/AuthCookie/Util.pm view on Meta::CPAN
package Apache::AuthCookie::Util;
$Apache::AuthCookie::Util::VERSION = '3.32';
# ABSTRACT: Internal Utility Functions for AuthCookie
use strict;
use base 'Exporter';
use URI;
our @EXPORT_OK = qw(
is_blank
is_local_destination
);
lib/Apache/AuthCookie/Util.pm view on Meta::CPAN
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Apache::AuthCookie::Util - Internal Utility Functions for AuthCookie
=head1 VERSION
version 3.32
=head1 DESCRIPTION
Internal Use Only!
=for Pod::Coverage *EVERYTHING*
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;
}
lib/Apache2/AuthCookie.pm view on Meta::CPAN
}
1;
=pod
=encoding UTF-8
=head1 NAME
Apache2::AuthCookie - Perl Authentication and Authorization via cookies
=head1 VERSION
version 3.32
=head1 SYNOPSIS
Make sure your mod_perl is at least 2.0.0-RC5, with StackedHandlers,
MethodHandlers, Authen, and Authz compiled in.
# In httpd.conf or .htaccess:
PerlModule Sample::Apache2::AuthCookieHandler
PerlSetVar WhatEverPath /
PerlSetVar WhatEverLoginScript /login.pl
# use to alter how "require" directives are matched. Can be "Any" or "All".
# If its "Any", then you must only match Any of the "require" directives. If
# its "All", then you must match All of the require directives.
#
# Default: All
PerlSetVar WhatEverSatisfy Any
lib/Apache2/AuthCookie.pm view on Meta::CPAN
# to enable the SameSite cookie property, set SameSite to "lax" or "strict".
# See: https://www.owasp.org/index.php/SameSite
PerlSetVar WhatEverSameSite strict
# Usually documents are uncached - turn off here
PerlSetVar WhatEverCache 1
# Use this to make your cookies persistent (+2 hours here)
PerlSetVar WhatEverExpires +2h
# Use to make AuthCookie send a P3P header with the cookie
# see http://www.w3.org/P3P/ for details about what the value
# of this should be
PerlSetVar WhatEverP3P "CP=\"...\""
# optional: enable decoding of intercepted GET/POST params:
PerlSetVar WhatEverEncoding UTF-8
# optional: enable decoding of httpd.conf "Requires" directives
PerlSetVar WhatEverRequiresEncoding UTF-8
# optional: enforce that the destination argument from the login form is
# local to the server
PerlSetVar WhatEverEnforceLocalDestination 1
# optional: specify a default destination for when the destination argument
# of the login form is invalid or unspecified
PerlSetVar WhatEverDefaultDestination /protected/user/
# These documents require user to be logged in.
<Location /protected>
AuthType Sample::Apache2::AuthCookieHandler
AuthName WhatEver
PerlAuthenHandler Sample::Apache2::AuthCookieHandler->authenticate
PerlAuthzHandler Sample::Apache2::AuthCookieHandler->authorize
require valid-user
</Location>
# These documents don't require logging in, but allow it.
<FilesMatch "\.ok$">
AuthType Sample::Apache2::AuthCookieHandler
AuthName WhatEver
PerlFixupHandler Sample::Apache2::AuthCookieHandler->recognize_user
</FilesMatch>
# This is the action of the login.pl script above.
<Files LOGIN>
AuthType Sample::Apache2::AuthCookieHandler
AuthName WhatEver
SetHandler perl-script
PerlResponseHandler Sample::Apache2::AuthCookieHandler->login
</Files>
=head1 DESCRIPTION
This module is for mod_perl version 2. If you are running mod_perl version 1,
you should be using B<Apache::AuthCookie> instead.
B<Apache2::AuthCookie> allows you to intercept a user's first
unauthenticated access to a protected document. The user will be
presented with a custom form where they can enter authentication
credentials. The credentials are posted to the server where AuthCookie
verifies them and returns a session key.
The session key is returned to the user's browser as a cookie. As a
cookie, the browser will pass the session key on every subsequent
accesses. AuthCookie will verify the session key and re-authenticate
the user.
All you have to do is write a custom module that inherits from
AuthCookie. Your module is a class which implements two methods:
=over 4
=item C<authen_cred()>
Verify the user-supplied credentials and return a session key. The
session key can be any string - often you'll use some string
containing username, timeout info, and any other information you need
to determine access to documents, and append a one-way hash of those
values together with some secret key.
=item C<authen_ses_key()>
Verify the session key (previously generated by C<authen_cred()>,
possibly during a previous request) and return the user ID. This user
ID will be fed to C<$r-E<gt>user()> to set Apache's idea of who's logged in.
=back
By using AuthCookie versus Apache's built-in AuthBasic you can design
your own authentication system. There are several benefits.
=over 4
=item 1.
The client doesn't *have* to pass the user credentials on every
subsequent access. If you're using passwords, this means that the
password can be sent on the first request only, and subsequent
requests don't need to send this (potentially sensitive) information.
lib/Apache2/AuthCookie.pm view on Meta::CPAN
=item 2.
When you determine that the client should stop using the
credentials/session key, the server can tell the client to delete the
cookie. Letting users "log out" is a notoriously impossible-to-solve
problem of AuthBasic.
=item 3.
AuthBasic dialog boxes are ugly. You can design your own HTML login
forms when you use AuthCookie.
=item 4.
You can specify the domain of a cookie using PerlSetVar commands. For
instance, if your AuthName is C<WhatEver>, you can put the command
PerlSetVar WhatEverDomain .yourhost.com
into your server setup file and your access cookies will span all
hosts ending in C<.yourhost.com>.
=item 5.
You can optionally specify the name of your cookie using the C<CookieName>
directive. For instance, if your AuthName is C<WhatEver>, you can put the
command
PerlSetVar WhatEverCookieName MyCustomName
into your server setup file and your cookies for this AuthCookie realm will be
named MyCustomName. Default is AuthType_AuthName.
=item 6.
By default users must satisfy ALL of the C<require> directives. If you
want authentication to succeed if ANY C<require> directives are met, use the
C<Satisfy> directive. For instance, if your AuthName is C<WhatEver>, you can
put the command
PerlSetVar WhatEverSatisfy Any
into your server startup file and authentication for this realm will succeed if
ANY of the C<require> directives are met.
=back
This is the flow of the authentication handler, less the details of the
redirects. Two HTTP_MOVED_TEMPORARILY's are used to keep the client from
displaying the user's credentials in the Location field. They don't really
change AuthCookie's model, but they do add another round-trip request to the
client.
(-----------------------) +---------------------------------+
( Request a protected ) | AuthCookie sets custom error |
( page, but user hasn't )---->| document and returns |
( authenticated (no ) | HTTP_FORBIDDEN. Apache abandons |
( session key cookie) ) | current request and creates sub |
(-----------------------) | request for the error document. |<-+
| Error document is a script that | |
| generates a form where the user | |
return | enters authentication | |
^------------------->| credentials (login & password). | |
/ \ False +---------------------------------+ |
/ \ | |
/ \ | |
/ \ V |
/ \ +---------------------------------+ |
/ Pass \ | User's client submits this form | |
/ user's \ | to the LOGIN URL, which calls | |
| credentials |<------------| AuthCookie->login(). | |
\ to / +---------------------------------+ |
\authen_cred/ |
\ function/ |
\ / |
\ / |
\ / +------------------------------------+ |
\ / return | Authen cred returns a session | +--+
V------------->| key which is opaque to AuthCookie.*| |
True +------------------------------------+ |
| |
+--------------------+ | +---------------+
| | | | If we had a |
V | V | cookie, add |
+----------------------------+ r | ^ | a Set-Cookie |
| If we didn't have a session| e |T / \ | header to |
| key cookie, add a | t |r / \ | override the |
| Set-Cookie header with this| u |u / \ | invalid cookie|
| session key. Client then | r |e / \ +---------------+
| returns session key with | n | / pass \ ^
| successive requests | | / session \ |
+----------------------------+ | / key to \ return |
| +-| authen_ses_key|------------+
V \ / False
+-----------------------------------+ \ /
| Tell Apache to set Expires header,| \ /
| set user to user ID returned by | \ /
| authen_ses_key, set authentication| \ /
| to our type (e.g. AuthCookie). | \ /
+-----------------------------------+ \ /
V
(---------------------) ^
( Request a protected ) |
( page, user has a )--------------+
( session key cookie )
(---------------------)
* The session key that the client gets can be anything you want. For
lib/Apache2/AuthCookie.pm view on Meta::CPAN
Get the value of C<${auth_name}Satisfy>, or C<all> if it is not set.
=head2 satisfy_is_valid(): bool
return true if the configured C<${auth_name}Satisfy> is valid, false otherwise.
=head2 authen_cred(): string
You must define this method yourself in your subclass of
C<Apache2::AuthCookie>. Its job is to create the session key that will
be preserved in the user's cookie. The arguments passed to it are:
sub authen_cred ($$\@) {
my $self = shift; # Package name (same as AuthName directive)
my $r = shift; # Apache request object
my @cred = @_; # Credentials from login form
...blah blah blah, create a session key...
return $session_key;
}
lib/Apache2/AuthCookie.pm view on Meta::CPAN
look at it later and determine the user's username. You are
responsible for implementing your own session key format. A typical
format is to make a string that contains the username, an expiration
time, whatever else you need, and an MD5 hash of all that data
together with a secret key. The hash will ensure that the user
doesn't tamper with the session key. More info in the Eagle book.
=head2 authen_ses_key($r, $session_key): string
You must define this method yourself in your subclass of
Apache2::AuthCookie. Its job is to look at a session key and determine
whether it is valid. If so, it returns the username of the
authenticated user.
sub authen_ses_key ($$$) {
my ($self, $r, $session_key) = @_;
...blah blah blah, check whether $session_key is valid...
return $ok ? $username : undef;
}
Optionally, return an array of 2 or more items that will be passed to method
lib/Apache2/AuthCookie.pm view on Meta::CPAN
$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.
lib/Apache2/AuthCookie.pm view on Meta::CPAN
=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
lib/Apache2/AuthCookie.pm view on Meta::CPAN
=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
lib/Apache2/AuthCookie.pm view on Meta::CPAN
=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/.
=back
In addition, you might want your login page to be able to tell why
the user is being asked to log in. In other words, if the user sent
bad credentials, then it might be useful to display an error message
saying that the given username or password are invalid. Also, it
might be useful to determine the difference between a user that sent
an invalid auth cookie, and a user that sent no auth cookie at all. To
cope with these situations, B<AuthCookie> will set
C<$r-E<gt>subprocess_env('AuthCookieReason')> to one of the following values.
=over 4
=item I<no_cookie>
The user presented no cookie at all. Typically this means the user is
trying to log in for the first time.
=item I<bad_cookie>
The cookie the user presented is invalid. Typically this means that the user
is not allowed access to the given page.
=item I<bad_credentials>
The user tried to log in, but the credentials that were passed are invalid.
=back
You can examine this value in your login form by examining
C<$r-E<gt>prev-E<gt>subprocess_env('AuthCookieReason')> (because it's
a sub-request).
Of course, if you want to give more specific information about why
access failed when a cookie is present, your C<authen_ses_key()>
method can set arbitrary entries in C<$r-E<gt>subprocess_env>.
=head1 THE LOGOUT SCRIPT
If you want to let users log themselves out (something that can't be
done using Basic Auth), you need to create a logout script. For an example,
see t/htdocs/docs/logout.pl. Logout scripts may want to take advantage of
AuthCookie's C<logout()> method, which will set the proper cookie headers in
order to clear the user's cookie. This usually looks like
C<$r-E<gt>auth_type-E<gt>logout($r);>.
Note that if you don't necessarily trust your users, you can't count
on cookie deletion for logging out. You'll have to expire some
server-side login information too. AuthCookie doesn't do this for
you, you have to handle it yourself.
=head1 ABOUT SESSION KEYS
Unlike the sample AuthCookieHandler, you have you verify the user's
login and password in C<authen_cred()>, then you do something
like:
my $date = localtime;
my $ses_key = MD5->hexhash(join(';', $date, $PID, $PAC));
save C<$ses_key> along with the user's login, and return C<$ses_key>.
Now C<authen_ses_key()> looks up the C<$ses_key> passed to it and
returns the saved login. I use Oracle to store the session key and
lib/Apache2/AuthCookie.pm view on Meta::CPAN
=head1 COPYRIGHT
Copyright (c) 2000 Ken Williams. All rights reserved.
This program is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.
=head1 SEE ALSO
L<Apache2::AuthCookie::Base>
=head1 SOURCE
The development version is on github at L<https://github.com/mschout/apache-authcookie>
and may be cloned from L<https://github.com/mschout/apache-authcookie.git>
=head1 BUGS
Please report any bugs or feature requests on the bugtracker website
L<https://github.com/mschout/apache-authcookie/issues>
lib/Apache2/AuthCookie/Base.pm view on Meta::CPAN
package Apache2::AuthCookie::Base;
$Apache2::AuthCookie::Base::VERSION = '3.32';
# ABSTRACT: Common Methods Shared by Apache2 and Apache2_4 AuthCookie Subclasses.
use strict;
use mod_perl2 1.99022;
use Carp;
use Apache::AuthCookie::Util qw(is_blank is_local_destination);
use Apache2::AuthCookie::Params;
use Apache2::RequestRec;
use Apache2::RequestUtil;
use Apache2::Log;
use Apache2::Access;
use Apache2::Response;
use Apache2::URI;
use Apache2::Util;
use APR::Table;
use Apache2::Const qw(OK DECLINED SERVER_ERROR M_GET HTTP_FORBIDDEN HTTP_MOVED_TEMPORARILY HTTP_OK);
use Encode ();
sub authenticate {
my ($auth_type, $r) = @_;
my $debug = $r->dir_config("AuthCookieDebug") || 0;
$r->server->log_error("authenticate() entry") if ($debug >= 3);
$r->server->log_error("auth_type " . $auth_type) if ($debug >= 3);
if (my $prev = ($r->prev || $r->main)) {
# we are in a subrequest or internal redirect. Just copy user from the
# previous or main request if its is present
if (defined $prev->user) {
$r->server->log_error('authenticate() is in a subrequest or internal redirect.') if $debug >= 3;
# encoding would have been handled in prev req, so do not encode here.
lib/Apache2/AuthCookie/Base.pm view on Meta::CPAN
# Ok, the AuthType is $auth_type which we handle, what's the authentication
# realm's name?
my $auth_name = $r->auth_name;
$r->server->log_error("auth_name $auth_name") if $debug >= 2;
unless ($auth_name) {
$r->server->log_error("AuthName not set, AuthType=$auth_type", $r->uri);
return SERVER_ERROR;
}
# Get the Cookie header. If there is a session key for this realm, strip
# off everything but the value of the cookie.
my $ses_key_cookie = $auth_type->key($r) || '';
$r->server->log_error("ses_key_cookie " . $ses_key_cookie) if $debug >= 1;
$r->server->log_error("uri " . $r->uri) if $debug >= 2;
if ($ses_key_cookie) {
my ($auth_user, @args) = $auth_type->authen_ses_key($r, $ses_key_cookie);
if (!is_blank($auth_user) and scalar @args == 0) {
lib/Apache2/AuthCookie/Base.pm view on Meta::CPAN
return OK;
}
elsif (scalar @args > 0 and $auth_type->can('custom_errors')) {
return $auth_type->custom_errors($r, $auth_user, @args);
}
else {
# There was a session key set, but it's invalid for some reason. So,
# remove it from the client now so when the credential data is posted
# we act just like it's a new session starting.
$auth_type->remove_cookie($r);
$r->subprocess_env('AuthCookieReason', 'bad_cookie');
}
}
else {
$r->subprocess_env('AuthCookieReason', 'no_cookie');
}
# This request is not authenticated, but tried to get a protected
# document. Send client the authen form.
return $auth_type->login_form($r);
}
sub cookie_name {
my ($self, $r) = @_;
my $auth_type = $r->auth_type;
my $auth_name = $r->auth_name;
my $cookie_name = $r->dir_config("${auth_name}CookieName") ||
"${auth_type}_${auth_name}";
return $cookie_name;
}
sub cookie_string {
my $self = shift;
my %p = @_;
for (qw/request key/) {
lib/Apache2/AuthCookie/Base.pm view on Meta::CPAN
my $r = $p{request};
$p{value} = '' unless defined $p{value};
my $string = sprintf '%s=%s', @p{'key','value'};
my $auth_name = $r->auth_name;
if (my $expires = $p{expires} || $r->dir_config("${auth_name}Expires")) {
$expires = Apache::AuthCookie::Util::expires($expires);
$string .= "; expires=$expires";
}
$string .= '; path=' . ( $self->get_cookie_path($r) || '/' );
if (my $domain = $r->dir_config("${auth_name}Domain")) {
$string .= "; domain=$domain";
}
if ($r->dir_config("${auth_name}Secure")) {
lib/Apache2/AuthCookie/Base.pm view on Meta::CPAN
$r->err_headers_out->set(Pragma => 'no-cache');
}
}
sub key {
my ($self, $r) = @_;
my $cookie_name = $self->cookie_name($r);
my $allcook = ($r->headers_in->get("Cookie") || "");
return ($allcook =~ /(?:^|\s)$cookie_name=([^;]*)/)[0];
}
sub login {
my ($self, $r) = @_;
my $debug = $r->dir_config("AuthCookieDebug") || 0;
my $auth_type = $r->auth_type;
my $auth_name = $r->auth_name;
my $params = $self->params($r);
if ($r->method eq 'POST') {
$self->_convert_to_get($r);
}
my $default_destination = $r->dir_config("${auth_name}DefaultDestination");
my $destination = $params->param('destination');
if (is_blank($destination)) {
if (!is_blank($default_destination)) {
$destination = $default_destination;
$r->server->log_error("destination set to $destination");
}
else {
$r->server->log_error("No key 'destination' found in form data");
$r->subprocess_env('AuthCookieReason', 'no_cookie');
return $auth_type->login_form($r);
}
}
if ($r->dir_config("${auth_name}EnforceLocalDestination")) {
my $current_url = $r->construct_url;
unless (is_local_destination($destination, $current_url)) {
$r->server->log_error("non-local destination $destination detected for uri ",$r->uri);
if (is_local_destination($default_destination, $current_url)) {
$destination = $default_destination;
$r->server->log_error("destination changed to $destination");
}
else {
$r->server->log_error("Returning login form: non local destination: $destination");
$r->subprocess_env('AuthCookieReason', 'no_cookie');
return $auth_type->login_form($r);
}
}
}
# Get the credentials from the data posted by the client
my @credentials;
for (my $i = 0; defined $params->param("credential_$i"); $i++) {
my $key = "credential_$i";
my $val = $params->param($key);
lib/Apache2/AuthCookie/Base.pm view on Meta::CPAN
push @credentials, $val;
}
# save creds in pnotes so login form script can use them if it wants to
$r->pnotes("${auth_name}Creds", \@credentials);
# Exchange the credentials for a session key.
my $ses_key = $self->authen_cred($r, @credentials);
unless ($ses_key) {
$r->server->log_error("Bad credentials") if $debug >= 2;
$r->subprocess_env('AuthCookieReason', 'bad_credentials');
$r->uri($self->untaint_destination($destination));
return $auth_type->login_form($r);
}
if ($debug >= 2) {
defined $ses_key ? $r->server->log_error("ses_key $ses_key")
: $r->server->log_error("ses_key undefined");
}
$self->send_cookie($r, $ses_key);
lib/Apache2/AuthCookie/Base.pm view on Meta::CPAN
return $status;
}
sub login_form_status {
my ($self, $r) = @_;
my $ua = $r->headers_in->get('User-Agent')
or return HTTP_FORBIDDEN;
if (Apache::AuthCookie::Util::understands_forbidden_response($ua)) {
return HTTP_FORBIDDEN;
}
else {
return HTTP_OK;
}
}
sub logout {
my ($self,$r) = @_;
my $debug = $r->dir_config("AuthCookieDebug") || 0;
$self->remove_cookie($r);
$self->handle_cache($r);
}
sub params {
my ($self, $r) = @_;
return Apache2::AuthCookie::Params->new($r);
}
sub recognize_user {
my ($self, $r) = @_;
# only check if user is not already set
return DECLINED unless is_blank($r->user);
my $debug = $r->dir_config("AuthCookieDebug") || 0;
my $auth_type = $r->auth_type;
my $auth_name = $r->auth_name;
return DECLINED if is_blank($auth_type) or is_blank($auth_name);
return DECLINED if is_blank($r->headers_in->get('Cookie'));
my $cookie = $self->key($r);
my $cookie_name = $self->cookie_name($r);
$r->server->log_error("cookie $cookie_name is $cookie")
if $debug >= 2;
return DECLINED if is_blank($cookie);
my ($user,@args) = $auth_type->authen_ses_key($r, $cookie);
lib/Apache2/AuthCookie/Base.pm view on Meta::CPAN
return is_blank($user) ? DECLINED : OK;
}
sub remove_cookie {
my ($self, $r) = @_;
my $cookie_name = $self->cookie_name($r);
my $debug = $r->dir_config("AuthCookieDebug") || 0;
my $str = $self->cookie_string(
request => $r,
key => $cookie_name,
value => '',
expires => 'Mon, 21-May-1971 00:00:00 GMT'
);
$r->err_headers_out->add("Set-Cookie" => "$str");
$r->server->log_error("removed cookie $cookie_name") if $debug >= 2;
}
sub requires_encoding {
my ($self, $r) = @_;
my $auth_name = $r->auth_name;
return $r->dir_config("${auth_name}RequiresEncoding");
lib/Apache2/AuthCookie/Base.pm view on Meta::CPAN
my $cookie = $self->cookie_string(
request => $r,
key => $cookie_name,
value => $ses_key,
%$cookie_args
);
$self->send_p3p($r);
$r->err_headers_out->add("Set-Cookie" => $cookie);
}
sub send_p3p {
my ($self, $r) = @_;
my $auth_name = $r->auth_name;
if (my $p3p = $r->dir_config("${auth_name}P3P")) {
$r->err_headers_out->set(P3P => $p3p);
}
}
sub untaint_destination {
my ($self, $dest) = @_;
return Apache::AuthCookie::Util::escape_destination($dest);
}
# convert current request to GET
sub _convert_to_get {
my ($self, $r) = @_;
return unless $r->method eq 'POST';
my $debug = $r->dir_config("AuthCookieDebug") || 0;
$r->server->log_error("Converting POST -> GET") if $debug >= 2;
my $args = $self->params($r);
my @pairs = ();
for my $name ($args->param) {
# we dont want to copy login data, only extra data
next if $name eq 'destination'
lib/Apache2/AuthCookie/Base.pm view on Meta::CPAN
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Apache2::AuthCookie::Base - Common Methods Shared by Apache2 and Apache2_4 AuthCookie Subclasses.
=head1 VERSION
version 3.32
=head1 DESCRIPTION
This module contains common code shared by AuthCookie for Apache 2.x and Apache 2.4.
=head1 METHODS
=head2 authenticate($r): int
This method is one you'll use in a server config file (httpd.conf, .htaccess,
...) as a PerlAuthenHandler. If the user provided a session key in a cookie,
the C<authen_ses_key()> method will get called to check whether the key is
valid. If not, or if there is no key provided, we redirect to the login form.
=head2 cookie_name($r): string
Return the name of the auth cookie for this request. This is either
C<${auth_name}CookieName>, or AuthCookie's self generated name.
=head2 cookie_string(%args): string
Generate a cookie string. C<%args> are:
=over 4
=item *
request
The Apache request object
=item *
key
The Cookie name
=item *
value
the Cookie value
=item *
expires (optional)
When the cookie expires. See L<Apache::AuthCookie::Util/expires()>. Uses C<${auth_name}Expires> if not giv
=back
All other cookie settings come from C<PerlSetVar> settings.
=head2 decoded_requires($r): arrayref
This method returns the C<< $r->requires >> array, with the C<requirement>
values decoded if C<${auth_name}RequiresEncoding> is in effect for this
request.
lib/Apache2/AuthCookie/Base.pm view on Meta::CPAN
Note that HTTP_FORBIDDEN is the most correct code to return as the given
request was not authorized to view the requested page. You should only change
this if HTTP_FORBIDDEN does not work.
=head2 logout($r): void
This is simply a convenience method that unsets the session key for you. You
can call it in your logout scripts. Usually this looks like
C<$r-E<gt>auth_type-E<gt>logout($r)>.
=head2 params($r): Apache2::AuthCookie::Params
Get the GET/POST params object for this request.
=head2 recognize_user($r): int
If the user has provided a valid session key but the document isn't protected,
this method will set C<$r-E<gt>user> anyway. Use it as a PerlFixupHandler,
unless you have a better idea.
=head2 remove_cookie($r): void
Adds a C<Set-Cookie> header that instructs the client to delete the cookie
immediately.
=head2 requires_encoding($r): string
Return the ${auth_name}RequiresEncoding setting that is in effect for this request.
=head2 send_cookie($r, $ses_key, $args): void
By default this method simply sends out the session key you give it. If you
need to change the default behavior (perhaps to update a timestamp in the key)
lib/Apache2/AuthCookie/Params.pm view on Meta::CPAN
package Apache2::AuthCookie::Params;
$Apache2::AuthCookie::Params::VERSION = '3.32';
# ABSTRACT: AuthCookie Params Driver for mod_perl 2.x
use strict;
use warnings;
use base 'Apache::AuthCookie::Params::Base';
use Class::Load qw(try_load_class);
sub _new_instance {
my ($class, $r) = @_;
my $debug = $r->dir_config('AuthCookieDebug') || 0;
my $obj;
if (try_load_class('Apache2::Request')) {
$r->server->log_error("params: using Apache2::Request") if $debug >= 3;
return Apache2::Request->new($r);
}
else {
$r->server->log_error("params: using CGI") if $debug >= 3;
lib/Apache2/AuthCookie/Params.pm view on Meta::CPAN
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Apache2::AuthCookie::Params - AuthCookie Params Driver for mod_perl 2.x
=head1 VERSION
version 3.32
=head1 SYNOPSIS
Internal Use Only!
=head1 DESCRIPTION
This class handles CGI form data for L<Apache2::AuthCookie>. It will try to use
L<Apache2::Request> (from libapreq2) if it is available. If not, it will fall
back to use L<CGI>.
=head1 SOURCE
The development version is on github at L<https://github.com/mschout/apache-authcookie>
and may be cloned from L<https://github.com/mschout/apache-authcookie.git>
=head1 BUGS
lib/Apache2_4/AuthCookie.pm view on Meta::CPAN
package Apache2_4::AuthCookie;
$Apache2_4::AuthCookie::VERSION = '3.32';
# ABSTRACT: Perl Authentication and Authorization via cookies for Apache 2.4
use strict;
use base 'Apache2::AuthCookie::Base';
use Apache2::Log;
use Apache2::Const -compile => qw(AUTHZ_GRANTED AUTHZ_DENIED AUTHZ_DENIED_NO_USER);
use Apache::AuthCookie::Util qw(is_blank);
# You really do not need this provider at all. This provides an implementation
# for "Require user ..." directives, that is compatible with mod_authz_core
# (with the exception that expressions are not supported). You should really
# just let mod_authz_core be your "user" authz provider. Nevertheless, due to
# the fact that AuthCookie was released for Apache 2.4 with documentation that
# shows this is needed, we leave this implementation for backwards
# compatibility.
sub authz_handler {
my ($auth_type, $r, $requires) = @_;
my $user = $r->user;
if (is_blank($user)) {
# user is not yet authenticated
return Apache2::Const::AUTHZ_DENIED_NO_USER;
}
if (is_blank($requires)) {
$r->server->log_error(q[Your 'Require user ...' config does not specify any users]);
return Apache2::Const::AUTHZ_DENIED;
}
my $debug = $r->dir_config("AuthCookieDebug") || 0;
$r->server->log_error("authz user=$user type=$auth_type req=$requires") if $debug >=3;
for my $valid_user (split /\s+/, $requires) {
if ($user eq $valid_user) {
return Apache2::Const::AUTHZ_GRANTED;
}
}
# log a message similar to mod_authz_user
lib/Apache2_4/AuthCookie.pm view on Meta::CPAN
}
1;
=pod
=encoding UTF-8
=head1 NAME
Apache2_4::AuthCookie - Perl Authentication and Authorization via cookies for Apache 2.4
=head1 VERSION
version 3.32
=head1 SYNOPSIS
Make sure your mod_perl is at least 2.0.9, with StackedHandlers,
MethodHandlers, Authen, and Authz compiled in.
# In httpd.conf or .htaccess:
PerlModule Sample::Apache2::AuthCookieHandler
PerlSetVar WhatEverPath /
PerlSetVar WhatEverLoginScript /login.pl
# The following line is optional - it allows you to set the domain
# scope of your cookie. Default is the current domain.
PerlSetVar WhatEverDomain .yourdomain.com
# Use this to only send over a secure connection
PerlSetVar WhatEverSecure 1
lib/Apache2_4/AuthCookie.pm view on Meta::CPAN
# to enable the SameSite cookie property, set SameSite to "lax" or "strict".
# See: https://www.owasp.org/index.php/SameSite
PerlSetVar WhatEverSameSite strict
# Usually documents are uncached - turn off here
PerlSetVar WhatEverCache 1
# Use this to make your cookies persistent (+2 hours here)
PerlSetVar WhatEverExpires +2h
# Use to make AuthCookie send a P3P header with the cookie
# see http://www.w3.org/P3P/ for details about what the value
# of this should be
PerlSetVar WhatEverP3P "CP=\"...\""
# optional: enable decoding of intercepted GET/POST params:
PerlSetVar WhatEverEncoding UTF-8
# optional: enable decoding of httpd.conf "Requires" directives
PerlSetVar WhatEverRequiresEncoding UTF-8
# These documents require user to be logged in.
<Location /protected>
AuthType Sample::Apache2::AuthCookieHandler
AuthName WhatEver
PerlAuthenHandler Sample::Apache2::AuthCookieHandler->authenticate
Require valid-user
</Location>
# How to handle a custom requirement (non-user).
PerlAddAuthzProvider species Sample::Apache2::AuthCookieHandler->authz_species
<Location /protected/species>
Require species klingon
</Location>
# These documents don't require logging in, but allow it.
<FilesMatch "\.ok$">
AuthType Sample::Apache2::AuthCookieHandler
AuthName WhatEver
PerlFixupHandler Sample::Apache2::AuthCookieHandler->recognize_user
</FilesMatch>
# This is the action of the login.pl script above.
<Files LOGIN>
AuthType Sample::Apache2::AuthCookieHandler
AuthName WhatEver
SetHandler perl-script
PerlResponseHandler Sample::Apache2::AuthCookieHandler->login
</Files>
=head1 DESCRIPTION
This module is for C<mod_perl> version 2 for C<Apache> version 2.4.x. If you
are running mod_perl version 1, you need B<Apache::AuthCookie> instead. If you
are running C<Apache> 2.0.0-2.2.x, you need B<Apache2::AuthCookie> instead.
B<Apache2_4::AuthCookie> allows you to intercept a user's first unauthenticated
access to a protected document. The user will be presented with a custom form
where they can enter authentication credentials. The credentials are posted to
the server where AuthCookie verifies them and returns a session key.
The session key is returned to the user's browser as a cookie. As a cookie, the
browser will pass the session key on every subsequent accesses. AuthCookie will
verify the session key and re-authenticate the user.
All you have to do is write a custom module that inherits from AuthCookie.
Your module is a class which implements two methods:
=over 4
=item C<authen_cred()>
Verify the user-supplied credentials and return a session key. The session key
can be any string - often you'll use some string containing username, timeout
info, and any other information you need to determine access to documents, and
append a one-way hash of those values together with some secret key.
=item C<authen_ses_key()>
Verify the session key (previously generated by C<authen_cred()>, possibly
during a previous request) and return the user ID. This user ID will be fed to
C<$r-E<gt>user()> to set Apache's idea of who's logged in.
=back
By using AuthCookie versus Apache's built-in AuthBasic you can design your own
authentication system. There are several benefits.
=over 4
=item 1.
The client doesn't *have* to pass the user credentials on every subsequent
access. If you're using passwords, this means that the password can be sent on
the first request only, and subsequent requests don't need to send this
(potentially sensitive) information. This is known as "ticket-based"
lib/Apache2_4/AuthCookie.pm view on Meta::CPAN
=item 2.
When you determine that the client should stop using the credentials/session
key, the server can tell the client to delete the cookie. Letting users "log
out" is a notoriously impossible-to-solve problem of AuthBasic.
=item 3.
AuthBasic dialog boxes are ugly. You can design your own HTML login forms when
you use AuthCookie.
=item 4.
You can specify the domain of a cookie using C<PerlSetVar> commands. For
instance, if your AuthName is C<WhatEver>, you can put the command
PerlSetVar WhatEverDomain .yourhost.com
into your server setup file and your access cookies will span all hosts ending
in C<.yourhost.com>.
=item 5.
You can optionally specify the name of your cookie using the C<CookieName>
directive. For instance, if your AuthName is C<WhatEver>, you can put the
command
PerlSetVar WhatEverCookieName MyCustomName
into your server setup file and your cookies for this AuthCookie realm will be
named MyCustomName. Default is AuthType_AuthName.
=back
This is the flow of the authentication handler, less the details of the
redirects. Two HTTP_MOVED_TEMPORARILY's are used to keep the client from
displaying the user's credentials in the Location field. They don't really
change AuthCookie's model, but they do add another round-trip request to the
client.
(-----------------------) +---------------------------------+
( Request a protected ) | AuthCookie sets custom error |
( page, but user hasn't )---->| document and returns |
( authenticated (no ) | HTTP_FORBIDDEN. Apache abandons |
( session key cookie) ) | current request and creates sub |
(-----------------------) | request for the error document. |<-+
| Error document is a script that | |
| generates a form where the user | |
return | enters authentication | |
^------------------->| credentials (login & password). | |
/ \ False +---------------------------------+ |
/ \ | |
/ \ | |
/ \ V |
/ \ +---------------------------------+ |
/ Pass \ | User's client submits this form | |
/ user's \ | to the LOGIN URL, which calls | |
| credentials |<------------| AuthCookie->login(). | |
\ to / +---------------------------------+ |
\authen_cred/ |
\ function/ |
\ / |
\ / |
\ / +------------------------------------+ |
\ / return | Authen cred returns a session | +--+
V------------->| key which is opaque to AuthCookie.*| |
True +------------------------------------+ |
| |
+--------------------+ | +---------------+
| | | | If we had a |
V | V | cookie, add |
+----------------------------+ r | ^ | a Set-Cookie |
| If we didn't have a session| e |T / \ | header to |
| key cookie, add a | t |r / \ | override the |
| Set-Cookie header with this| u |u / \ | invalid cookie|
| session key. Client then | r |e / \ +---------------+
| returns session key with | n | / pass \ ^
| successive requests | | / session \ |
+----------------------------+ | / key to \ return |
| +-| authen_ses_key|------------+
V \ / False
+-----------------------------------+ \ /
| Tell Apache to set Expires header,| \ /
| set user to user ID returned by | \ /
| authen_ses_key, set authentication| \ /
| to our type (e.g. AuthCookie). | \ /
+-----------------------------------+ \ /
V
(---------------------) ^
( Request a protected ) |
( page, user has a )--------------+
( session key cookie )
(---------------------)
* The session key that the client gets can be anything you want. For
lib/Apache2_4/AuthCookie.pm view on Meta::CPAN
The only requirement is that the authen_ses_key function that you
create must be able to determine if this session_key is valid and
map it back to the originally authenticated user ID.
=head1 METHODS
=head2 authen_cred()
You must define this method yourself in your subclass of
C<Apache2_4::AuthCookie>. Its job is to create the session key that will be
preserved in the user's cookie. The arguments passed to it are:
sub authen_cred ($$\@) {
my $self = shift; # Package name (same as AuthName directive)
my $r = shift; # Apache request object
my @cred = @_; # Credentials from login form
...blah blah blah, create a session key...
return $session_key;
}
lib/Apache2_4/AuthCookie.pm view on Meta::CPAN
The only limitation on the session key is that you should be able to look at it
later and determine the user's username. You are responsible for implementing
your own session key format. A typical format is to make a string that
contains the username, an expiration time, whatever else you need, and an MD5
hash of all that data together with a secret key. The hash will ensure that
the user doesn't tamper with the session key.
=head2 authen_ses_key()
You must define this method yourself in your subclass of
C<Apache2_4::AuthCookie>. Its job is to look at a session key and determine
whether it is valid. If so, it returns the username of the authenticated user.
sub authen_ses_key ($$$) {
my ($self, $r, $session_key) = @_;
...blah blah blah, check whether $session_key is valid...
return $ok ? $username : undef;
}
Optionally, return an array of 2 or more items that will be passed to method
custom_errors. It is the responsibility of this method to return the correct
lib/Apache2_4/AuthCookie.pm view on Meta::CPAN
# 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 EXAMPLE
For an example of how to use C<Apache2_4::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 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.
lib/Apache2_4/AuthCookie.pm view on Meta::CPAN
=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
lib/Apache2_4/AuthCookie.pm view on Meta::CPAN
=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 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
lib/Apache2_4/AuthCookie.pm view on Meta::CPAN
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 C<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/.
=back
In addition, you might want your login page to be able to tell why the user is
being asked to log in. In other words, if the user sent bad credentials, then
it might be useful to display an error message saying that the given username
or password are invalid. Also, it might be useful to determine the difference
between a user that sent an invalid auth cookie, and a user that sent no auth
cookie at all. To cope with these situations, B<AuthCookie> will set
C<$r-E<gt>subprocess_env('AuthCookieReason')> to one of the following values.
=over 4
=item I<no_cookie>
The user presented no cookie at all. Typically this means the user is
trying to log in for the first time.
=item I<bad_cookie>
The cookie the user presented is invalid. Typically this means that the user
is not allowed access to the given page.
=item I<bad_credentials>
The user tried to log in, but the credentials that were passed are invalid.
=back
You can examine this value in your login form by examining
C<$r-E<gt>prev-E<gt>subprocess_env('AuthCookieReason')> (because it's a
sub-request).
Of course, if you want to give more specific information about why access
failed when a cookie is present, your C<authen_ses_key()> method can set
arbitrary entries in C<$r-E<gt>subprocess_env>.
=head1 THE LOGOUT SCRIPT
If you want to let users log themselves out (something that can't be done using
Basic Auth), you need to create a logout script. For an example, see
t/htdocs/docs/logout.pl. Logout scripts may want to take advantage of
AuthCookie's C<logout()> method, which will set the proper cookie headers in
order to clear the user's cookie. This usually looks like
C<$r-E<gt>auth_type-E<gt>logout($r);>.
Note that if you don't necessarily trust your users, you can't count on cookie
deletion for logging out. You'll have to expire some server-side login
information too. AuthCookie doesn't do this for you, you have to handle it
yourself.
=head1 ABOUT SESSION KEYS
Unlike the sample AuthCookieHandler, you have you verify the user's login and
password in C<authen_cred()>, then you do something like:
my $date = localtime;
my $ses_key = Digest::SHA::sha256_hex(join(';', $date, $PID, $PAC));
save C<$ses_key> along with the user's login, and return C<$ses_key>.
Now C<authen_ses_key()> looks up the C<$ses_key> passed to it and returns the
saved login. I use a database to store the session key and retrieve it later.
=head1 FREQUENTLY ASKED QUESTIONS
=over 4
=item *
I upgraded to Apache 2.4 and now AuthCookie doesn't work!
Apache 2.4 radically changed the authentication and authorization API. You will
need to port your AuthCookie subclass over to the Apache 2.4 API. See the POD
documentation in L<README.apache-2.4> for more information, but the quick
rundown is you need to:
=over 4
=item *
Inherit from C<Apache2_4::AuthCookie>
=item *
Remove all C<PerlAuthzHandler> configuration entries.
=item *
Write Authz Provider methods for any C<Requires> directives that you are using
that Apache does not provide for already (e.g. Apache already handles C<user>
and C<valid-user>) and register them with something like.
PerlAddAuthzProvier species Sample::AuthCookieHandler->authz_species
=item *
Replace instances of C<${AuthName}Satistfy> with either C<RequireAll> or
C<RequireAny> blocks.
=back
=item *
Why is my authz method called twice per request?
This is normal behaviour under Apache 2.4. This is to accommodate for
authorization of anonymous access. You are expected to return
C<Apache2::Const::AUTHZ_DENIED_NO_USER> IF C<< $r->user >> has not yet been set
if you want authentication to proceed. Your authz handler will be called a
second time after the user has been authenticated.
=item *
AuthCookie authenticates, but the authorization handler is returning
C<UNAUTHORIZED> instead of C<FORBIDDEN>!
In Apache 2.4, in C<mod_authz_core>, if no authz handlers return C<AUTHZ_GRANTED>,
then C<HTTP_UNAUTHORIZED> is returned. In previous versions of Apache,
C<HTTP_FORBIDDEN> was returned. You can get the old behaviour if you want it
with:
AuthzSendForbiddenOnFailure On
=item *
lib/Apache2_4/AuthCookie.pm view on Meta::CPAN
=head1 COPYRIGHT
Copyright (c) 2015 Michael Schout. All rights reserved.
This program is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.
=head1 SEE ALSO
L<Apache2::AuthCookie::Base>
=for Pod::Coverage AUTHZ_GRANTED
AUTHZ_DENIED
AUTHZ_DENIED_NO_USER
=head1 SOURCE
The development version is on github at L<https://github.com/mschout/apache-authcookie>
and may be cloned from L<https://github.com/mschout/apache-authcookie.git>
scripts/run-docker-tests view on Meta::CPAN
mschout/modperl:apache-2.0.53-perl-5.14.4-mp-2.0.9\
mschout/modperl:apache-2.2.31-perl-5.20.3-mp-2.0.9\
mschout/modperl:apache-2.4.38-perl-5.20.3-mp-2.0.11\
"
set -eo pipefail
builddir=$1
if [ -z "$builddir" ]; then
echo "Usage: $0 ./path/to/Apache-AuthCookie-X.YY"
exit 1
fi
test_in_docker_image() {
local docker_image=$1
echo ">>> Testing in image $docker_image"
docker run --rm -v $builddir:/app -it $docker_image /app/scripts/docker-smoke
}
t/Skeleton/AuthCookieHandler.pm view on Meta::CPAN
package Skeleton::AuthCookieHandler;
use strict;
use Apache;
use Apache::Constants qw(:common);
use Apache::AuthCookie;
use vars qw($VERSION @ISA);
$VERSION = substr(q$Revision$, 10);
@ISA = qw(Apache::AuthCookie);
sub authen_cred ($$\@) {
my $self = shift;
my $r = shift;
my @creds = @_;
# This would really authenticate the credentials
# and return the session key.
# Here I'm just using setting the session
# key to the credentials and delaying authentication.
t/conf/extra.conf.in view on Meta::CPAN
PerlRequire @ServerRoot@/startup.pl
AddDefaultCharset UTF-8
<IfDefine APACHE1>
PerlModule Sample::Apache::AuthCookieHandler
PerlModule Apache::Registry
</IfDefine>
<IfDefine APACHE2>
PerlSwitches -I@ServerRoot@/lib
PerlModule Sample::Apache2::AuthCookieHandler
PerlModule ModPerl::Registry
<IfDefine APACHE2_4>
PerlModule Sample::Apache2_4::AuthCookieHandler
PerlAddAuthzProvider dwarf Sample::Apache2_4::AuthCookieHandler->dwarf
PerlAddAuthzProvider myuser Sample::Apache2_4::AuthCookieHandler->authz_handler
</IfDefine>
</IfDefine>
PerlSetVar WhatEverPath /
PerlSetVar WhatEverLoginScript /docs/login.pl
PerlSetVar AuthCookieDebug 3
PerlSetVar WhatEverCookieName Sample::AuthCookieHandler_WhatEver
PerlSetVar WhatEverEncoding UTF-8
PerlSetVar WhatEverRequiresEncoding UTF-8
<Directory @ServerRoot@>
AllowOverride All
</Directory>
<IfDefine APACHE2_4>
<Location /docs>
AuthzSendForbiddenOnFailure On
</Location>
</IfDefine>
# These documents require user to be logged in.
<Location /docs/protected>
AuthName WhatEver
<IfDefine APACHE1>
AuthType Sample::Apache::AuthCookieHandler
PerlAuthenHandler Sample::Apache::AuthCookieHandler->authenticate
PerlAuthzHandler Sample::Apache::AuthCookieHandler->authorize
</IfDefine>
<IfDefine APACHE2>
<IfDefine !APACHE2_4>
AuthType Sample::Apache2::AuthCookieHandler
PerlAuthenHandler Sample::Apache2::AuthCookieHandler->authenticate
PerlAuthzHandler Sample::Apache2::AuthCookieHandler->authorize
</IfDefine>
<IfDefine APACHE2_4>
AuthType Sample::Apache2_4::AuthCookieHandler
PerlAuthenHandler Sample::Apache2_4::AuthCookieHandler->authenticate
</IfDefine>
</IfDefine>
Require user programmer
DirectoryIndex index.html
</Location>
# must satisfy any requirement
<Location /docs/authany>
PerlSetVar WhatEverSatisfy Any
AuthName WhatEver
<IfDefine APACHE1>
AuthType Sample::Apache::AuthCookieHandler
PerlAuthenHandler Sample::Apache::AuthCookieHandler->authenticate
PerlAuthzHandler Sample::Apache::AuthCookieHandler->authorize
</IfDefine>
<IfDefine APACHE2>
<IfDefine !APACHE2_4>
AuthType Sample::Apache2::AuthCookieHandler
PerlAuthenHandler Sample::Apache2::AuthCookieHandler->authenticate
PerlAuthzHandler Sample::Apache2::AuthCookieHandler->authorize
</IfDefine>
<IfDefine APACHE2_4>
AuthType Sample::Apache2_4::AuthCookieHandler
PerlAuthenHandler Sample::Apache2_4::AuthCookieHandler->authenticate
</IfDefine>
</IfDefine>
Require user some-user programmer ç¨åºå
Require user 0
</Location>
# must satisfy all requirements
<Location /docs/authall>
PerlSetVar WhatEverSatisfy All
AuthName WhatEver
<IfDefine APACHE1>
AuthType Sample::Apache::AuthCookieHandler
PerlAuthenHandler Sample::Apache::AuthCookieHandler->authenticate
PerlAuthzHandler Sample::Apache::AuthCookieHandler->authorize
</IfDefine>
<IfDefine APACHE2>
<IfDefine !APACHE2_4>
PerlAuthenHandler Sample::Apache2::AuthCookieHandler->authenticate
AuthType Sample::Apache2::AuthCookieHandler
PerlAuthzHandler Sample::Apache2::AuthCookieHandler->authorize
</IfDefine>
<IfDefine APACHE2_4>
PerlAuthenHandler Sample::Apache2_4::AuthCookieHandler->authenticate
AuthType Sample::Apache2_4::AuthCookieHandler
</IfDefine>
</IfDefine>
<IfDefine !APACHE2_4>
# apache 1.x, apache 2.0, apache 2.2
Require dwarf
Require user programmer
</IfDefine>
<IfDefine APACHE2_4>
# apache 2.4
t/conf/extra.conf.in view on Meta::CPAN
Require dwarf
</RequireAll>
</IfDefine>
</Location>
# test our internal authz_handler for apache 2.4
<Location /docs/myuser>
AuthName WhatEver
<IfDefine APACHE1>
AuthType Sample::Apache::AuthCookieHandler
PerlAuthenHandler Sample::Apache::AuthCookieHandler->authenticate
PerlAuthzHandler Sample::Apache::AuthCookieHandler->authorize
</IfDefine>
<IfDefine APACHE2>
<IfDefine !APACHE2_4>
PerlAuthenHandler Sample::Apache2::AuthCookieHandler->authenticate
AuthType Sample::Apache2::AuthCookieHandler
PerlAuthzHandler Sample::Apache2::AuthCookieHandler->authorize
</IfDefine>
<IfDefine APACHE2_4>
PerlAuthenHandler Sample::Apache2_4::AuthCookieHandler->authenticate
AuthType Sample::Apache2_4::AuthCookieHandler
</IfDefine>
</IfDefine>
<IfDefine !APACHE2_4>
# apache 1.x, apache 2.0, apache 2.2
Require user programmer
</IfDefine>
<IfDefine APACHE2_4>
# apache 2.4
<RequireAll>
Require myuser dopey programmer
</RequireAll>
</IfDefine>
</Location>
<Location /docs/stimeout>
PerlSetVar WhatEverSessionTimeout +10m
AuthName WhatEver
<IfDefine APACHE1>
AuthType Sample::Apache::AuthCookieHandler
PerlAuthenHandler Sample::Apache::AuthCookieHandler->authenticate
PerlAuthzHandler Sample::Apache::AuthCookieHandler->authorize
</IfDefine>
<IfDefine APACHE2>
<IfDefine !APACHE2_4>
AuthType Sample::Apache2::AuthCookieHandler
PerlAuthenHandler Sample::Apache2::AuthCookieHandler->authenticate
PerlAuthzHandler Sample::Apache2::AuthCookieHandler->authorize
</IfDefine>
<IfDefine APACHE2_4>
AuthType Sample::Apache2_4::AuthCookieHandler
PerlAuthenHandler Sample::Apache2_4::AuthCookieHandler->authenticate
</IfDefine>
</IfDefine>
Require user some-user
Require user programmer
</Location>
# These documents don't require logging in, but allow it.
<FilesMatch "\.cgi$">
AuthName WhatEver
<IfDefine APACHE1>
AuthType Sample::Apache::AuthCookieHandler
PerlFixupHandler Sample::Apache::AuthCookieHandler->recognize_user
</IfDefine>
<IfDefine APACHE2>
<IfDefine !APACHE2_4>
PerlFixupHandler Sample::Apache2::AuthCookieHandler->recognize_user
AuthType Sample::Apache2::AuthCookieHandler
</IfDefine>
<IfDefine APACHE2_4>
PerlFixupHandler Sample::Apache2_4::AuthCookieHandler->recognize_user
AuthType Sample::Apache2_4::AuthCookieHandler
Require all granted
</IfDefine>
</IfDefine>
</FilesMatch>
<FilesMatch "\.pl$">
SetHandler perl-script
Options +ExecCGI
AuthName WhatEver
<IfDefine APACHE1>
PerlHandler Apache::Registry
AuthType Sample::Apache::AuthCookieHandler
PerlFixupHandler Sample::Apache::AuthCookieHandler->recognize_user
</IfDefine>
<IfDefine APACHE2>
PerlResponseHandler ModPerl::Registry
<IfDefine !APACHE2_4>
PerlFixupHandler Sample::Apache2::AuthCookieHandler->recognize_user
AuthType Sample::Apache2::AuthCookieHandler
</IfDefine>
<IfDefine APACHE2_4>
PerlFixupHandler Sample::Apache2_4::AuthCookieHandler->recognize_user
AuthType Sample::Apache2_4::AuthCookieHandler
Require all granted
</IfDefine>
</IfDefine>
</FilesMatch>
# This is the action of the login.pl script above.
<Files LOGIN>
AuthName WhatEver
SetHandler perl-script
<IfDefine APACHE1>
AuthType Sample::Apache::AuthCookieHandler
PerlHandler Sample::Apache::AuthCookieHandler->login
</IfDefine>
<IfDefine APACHE2>
<IfDefine !APACHE2_4>
AuthType Sample::Apache2::AuthCookieHandler
</IfDefine>
<IfDefine APACHE2_4>
AuthType Sample::Apache2_4::AuthCookieHandler
Require all granted
</IfDefine>
PerlResponseHandler Sample::Apache2::AuthCookieHandler->login
</IfDefine>
</Files>
<Files LOGIN-WITHDEFAULT>
AuthName WhatEver
SetHandler perl-script
PerlSetVar WhatEverDefaultDestination /docs/protected/index.html
<IfDefine APACHE1>
AuthType Sample::Apache::AuthCookieHandler
PerlHandler Sample::Apache::AuthCookieHandler->login
</IfDefine>
<IfDefine APACHE2>
<IfDefine !APACHE2_4>
AuthType Sample::Apache2::AuthCookieHandler
</IfDefine>
<IfDefine APACHE2_4>
AuthType Sample::Apache2_4::AuthCookieHandler
Require all granted
</IfDefine>
PerlResponseHandler Sample::Apache2::AuthCookieHandler->login
</IfDefine>
</Files>
<Files LOGIN-ENFORCELOCAL-WITHDEFAULT>
AuthName WhatEver
SetHandler perl-script
PerlSetVar WhatEverEnforceLocalDestination On
PerlSetVar WhatEverDefaultDestination /docs/protected/index.html
<IfDefine APACHE1>
AuthType Sample::Apache::AuthCookieHandler
PerlHandler Sample::Apache::AuthCookieHandler->login
</IfDefine>
<IfDefine APACHE2>
<IfDefine !APACHE2_4>
AuthType Sample::Apache2::AuthCookieHandler
</IfDefine>
<IfDefine APACHE2_4>
AuthType Sample::Apache2_4::AuthCookieHandler
Require all granted
</IfDefine>
PerlResponseHandler Sample::Apache2::AuthCookieHandler->login
</IfDefine>
</Files>
<Files LOGIN-ENFORCELOCAL-REMOTEDEFAULT>
AuthName WhatEver
SetHandler perl-script
PerlSetVar WhatEverEnforceLocalDestination On
PerlSetVar WhatEverDefaultDestination http://metacpan.org
<IfDefine APACHE1>
AuthType Sample::Apache::AuthCookieHandler
PerlHandler Sample::Apache::AuthCookieHandler->login
</IfDefine>
<IfDefine APACHE2>
<IfDefine !APACHE2_4>
AuthType Sample::Apache2::AuthCookieHandler
</IfDefine>
<IfDefine APACHE2_4>
AuthType Sample::Apache2_4::AuthCookieHandler
Require all granted
</IfDefine>
PerlResponseHandler Sample::Apache2::AuthCookieHandler->login
</IfDefine>
</Files>
<Files LOGIN-ENFORCELOCAL-NODEFAULT>
AuthName WhatEver
SetHandler perl-script
PerlSetVar WhatEverEnforceLocalDestination On
<IfDefine APACHE1>
AuthType Sample::Apache::AuthCookieHandler
PerlHandler Sample::Apache::AuthCookieHandler->login
</IfDefine>
<IfDefine APACHE2>
<IfDefine !APACHE2_4>
AuthType Sample::Apache2::AuthCookieHandler
</IfDefine>
<IfDefine APACHE2_4>
AuthType Sample::Apache2_4::AuthCookieHandler
Require all granted
</IfDefine>
PerlResponseHandler Sample::Apache2::AuthCookieHandler->login
</IfDefine>
</Files>
# login action that sets HttpOnly
<Files LOGIN-HTTPONLY>
PerlSetVar WhatEverHttpOnly On
AuthName WhatEver
SetHandler perl-script
<IfDefine APACHE1>
AuthType Sample::Apache::AuthCookieHandler
PerlHandler Sample::Apache::AuthCookieHandler->login
</IfDefine>
<IfDefine APACHE2>
<IfDefine !APACHE2_4>
AuthType Sample::Apache2::AuthCookieHandler
PerlResponseHandler Sample::Apache2::AuthCookieHandler->login
</IfDefine>
<IfDefine APACHE2_4>
AuthType Sample::Apache2_4::AuthCookieHandler
PerlResponseHandler Sample::Apache2_4::AuthCookieHandler->login
Require all granted
</IfDefine>
</IfDefine>
</Files>
# login action that sets SameSite
<Files LOGIN-SAMESITE>
PerlSetVar WhatEverSameSite strict
AuthName WhatEver
SetHandler perl-script
<IfDefine APACHE1>
AuthType Sample::Apache::AuthCookieHandler
PerlHandler Sample::Apache::AuthCookieHandler->login
</IfDefine>
<IfDefine APACHE2>
<IfDefine !APACHE2_4>
AuthType Sample::Apache2::AuthCookieHandler
PerlResponseHandler Sample::Apache2::AuthCookieHandler->login
</IfDefine>
<IfDefine APACHE2_4>
AuthType Sample::Apache2_4::AuthCookieHandler
PerlResponseHandler Sample::Apache2_4::AuthCookieHandler->login
Require all granted
</IfDefine>
</IfDefine>
</Files>
<Files logout.pl>
AuthName WhatEver
<IfDefine APACHE1>
AuthType Sample::Apache::AuthCookieHandler
</IfDefine>
<IfDefine APACHE2>
<IfDefine !APACHE2_4>
AuthType Sample::Apache2::AuthCookieHandler
</IfDefine>
<IfDefine APACHE2_4>
AuthType Sample::Apache2_4::AuthCookieHandler
</IfDefine>
</IfDefine>
</Files>
<IfDefine APACHE1>
<Location /perl-status>
SetHandler perl-script
PerlHandler Apache::Status
</Location>
</IfDefine>
t/htdocs/docs/authall/get_me.html view on Meta::CPAN
<HTML>
<HEAD>
<TITLE>Congratulations</TITLE>
</HEAD>
<BODY>
<H1>Congratulations, you got past AuthCookie</H1>
<P><A HREF="../logout.pl">Log Out</A></P>
</BODY>
</HTML>
t/htdocs/docs/authany/get_me.html view on Meta::CPAN
<HTML>
<HEAD>
<TITLE>Congratulations</TITLE>
</HEAD>
<BODY>
<H1>Congratulations, you got past AuthCookie</H1>
<P><A HREF="../logout.pl">Log Out</A></P>
</BODY>
</HTML>
t/htdocs/docs/cookiename/get_me.html view on Meta::CPAN
<HTML>
<HEAD>
<TITLE>Congratulations</TITLE>
</HEAD>
<BODY>
<H1>Congratulations, you got past AuthCookie</H1>
<P><A HREF="../logout.pl">Log Out</A></P>
</BODY>
</HTML>
t/htdocs/docs/login.pl view on Meta::CPAN
my $uri = $r->prev->uri;
my $creds = $r->prev->pnotes("WhatEverCreds");
# if there are args, append that to the uri
my $args = $r->prev->args;
if ($args) {
$uri .= "?$args";
}
my $reason = $r->prev->subprocess_env("AuthCookieReason");
my $form = <<HERE;
<HTML>
<HEAD>
<TITLE>Enter Login and Password</TITLE>
</HEAD>
<BODY onLoad="document.forms[0].credential_0.focus();">
HERE
# output creds in a comment so the test case can see them.
t/htdocs/docs/myuser/get_me.html view on Meta::CPAN
<HTML>
<HEAD>
<TITLE>Congratulations</TITLE>
</HEAD>
<BODY>
<H1>Congratulations, you got past AuthCookie</H1>
<P><A HREF="../logout.pl">Log Out</A></P>
</BODY>
</HTML>
t/htdocs/docs/protected/get_me.html view on Meta::CPAN
<HTML>
<HEAD>
<TITLE>Congratulations</TITLE>
</HEAD>
<BODY>
<H1>Congratulations, you got past AuthCookie</H1>
<P><A HREF="../logout.pl">Log Out</A></P>
</BODY>
</HTML>
t/htdocs/docs/stimeout/get_me.html view on Meta::CPAN
<HTML>
<HEAD>
<TITLE>Congratulations</TITLE>
</HEAD>
<BODY>
<H1>Congratulations, you got past AuthCookie</H1>
<P><A HREF="../logout.pl">Log Out</A></P>
</BODY>
</HTML>
t/lib/Sample/Apache/AuthCookieHandler.pm view on Meta::CPAN
package Sample::Apache::AuthCookieHandler;
use strict;
use utf8;
use base 'Apache::AuthCookie';
use Apache;
use Apache::Constants qw(:common);
use Apache::AuthCookie;
use Apache::Util;
use URI::Escape qw(uri_escape_utf8 uri_unescape);
use Encode;
sub authen_cred ($$\@) {
my $self = shift;
my $r = shift;
my @creds = @_;
return if $creds[0] eq 'fail'; # simulate bad_credentials