APACHE 2.4 PORTING NOTES
VERY IMPORTANT!!!
Apache 2.4 has a 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.
Changes Required to Run Under Apache 2.4
- Mod Perl
-
You need at least
mod_perlversion 2.0.9, which is the first official release to support Apache 2.4. - Apache::Test
-
You need Apache::Test version 1.39 or later. Previous versions do not define the constant
APACHE2_4which is needed for the test suite. - Your AuthCookie Subclass
-
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
Require user ...orRequire valid-userin yourhttpd.conf, then you likely do not need an authorization provider at all. Apache 2.4 handles these for you inmod_authz_user.c.Related to previous item, you must change every method that was called as a
PerlAuthzHandlerunder previous versions to return one of the following values:- Apache2::Const::AUTHZ_DENIED_NO_USER
-
return this constant if
$r->useris empty/undefined and you do not wish to allow anonymous access. - Apache2::Const::AUTHZ_DENIED
-
return this constant if
$r->useris not authorized for the current request. - Apache2::Const::AUTHZ_GRANTED
-
return this constant if
$r->useris authorized for the current request - Apache2::Const::AUTHZ_GENERAL_ERROR
-
return this constant to indicate an error processing authz requirements.
- Apache2::Const::AUTHZ_NEUTRAL
-
return this constant to indicate a neutral response. It is assumed that another authz provider will be checked in a parent/sibling scope that will return granted or denied.
- httpd.conf
-
Remove all
PerlAuthzHandlerentries.PerlAuthzHandleris not necessary in Apache 2.4. If you are doing custom authoriaztion, you need to convert these toPerlAddAuthzProviderentries:Depending on what your
Requiredirectives say, you may need to add one or more top levelPerlAddAuthzProviderentires and implement a handler for each one.If your
Requiredirectives are simplyvalid-useroruser ...then you do not need to do this. Apache already provides an authz provider that handlesuserandvalid-userrequirements for you inmod_authz_user.c.If you are
Require'ing anything other thanvalid-useroruser ...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
PerlAuthzHandlermethod. Each one implements a specific requirement. E.g.:PerlAddAuthzProvider species My::AuthCookieHandler->authz_speciesWill be called to handle a
Require species klingonDirective.
It is important to know that Authz Providers are called twice for a request. First, the authz provider is called before authentication has been processed to check for anonymous access. In this method call,
$r->useris not set (to allow for your handler to allow annonymous access). You are expected to return one of:- AUTHZ_GRANTED
-
Access is granted and no further authn/authz processing will occur for this request.
- AUTHZ_DENIED
- AUTHZ_NEUTRAL
-
The response is
HTTP_FORBIDDEN(unless neutral is overridden by another provider) - AUTHZ_DENIED_NO_USER
-
This should be returned if
$r->useris not set and you do not wish to allow anonymous access. Authentication will be processed,$r->userwill be set with the current username and your authz provider will be called again.
The second time the authz provider is called,
$r->useris set and you are expected to return one of:- AUTHZ_GRANTED
-
The request is allowed
- AUTHZ_DENIED
-
The request is forbidden
- AUTHZ_NEUTRAL
-
The request is forbidden, unless another authz provider returns
AUTHZ_GRANTED. Consult the apache documentation about authorization merging for more info.
You could also return
AUTHZ_GENERAL_ERRORfrom any of these to indicate an error processing authz directives and halt processing immediately.One way to think about these response codes what kind of Require satisfies is in effect:
- RequireAll/RequireNone
-
In this case the priority of responses is:
- AUTHZ_GENERAL_ERROR
-
Processing stops immediately
- AUTHZ_DENIED
-
Processing stops immediately, no siblings are processed. Request is denied.
- AUTHZ_DENIED_NO_USER
-
Process Authentication and try again
- AUTHZ_GRANTED
-
Continue processing siblings.
- AUTZ_NEUTRAL
-
Continue processing siblings.
- RequireAny
-
In this case the priority of responses is:
- AUTHZ_GENERAL_ERROR
-
Processing stops immediately
- AUTHZ_GRANTED
-
Processing stops immediately, no siblings are processed. Request is allowed.
- AUTHZ_DENIED_NO_USER
-
Process Authentication and try again
- AUTHZ_DENIED
-
Continue processing siblings.
- AUTZ_NEUTRAL
-
Continue processing siblings.
Important Internal API Changes for Apache 2.4
-
You need to use a
PerlAddAuthzProviderand write an appropriate handler as described above instead. Note that you do not need aPerlAddAuthzProviderforuserorvalid-userrequirements. Apache already handles those internally viamod_authz_user.c - ${auth_name}Satisfy
-
Satisfy support is removed as it is no longer needed with Apache 2.4.
You are expected to use
RequireAllorRequireAnyinstead.e.g.:
PerlAddAuthzProvider species Your::AuthCookieHandler->authz_species_handler <RequireAll> Require valid-user Require species klingon </RequireAll>see: https://httpd.apache.org/docs/2.4/howto/auth.html#reqaccessctrl
-
In Apache 2.4, in
mod_authz_core, if no authz handlers returnAUTHZ_GRANTED, thenHTTP_UNAUTHORIZEDis returned. In previous versions of Apache,HTTP_FORBIDDENwas returned. You can get the old behaviour if you want it with:# in httpd.conf AuthzSendForbiddenOnFailure On
FREQUENTLY ASKED QUESTIONS
Why is my authz method called twice per request?
This is normal behaviour under Apache 2.4. This is to accomodate for authorization of anonymous access. You are expected to return
Apache2::Const::AUTHZ_DENIED_NO_USERIF$r->userhas 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.I get an error like
Can't locate object method "requires" via package Apache2::RequestRec ...This is because you called
AuthCookie'sauthorize()method, which is illegal under Apache 2.4. This could either be because yourAuthCookiesubclass explicitly calledauthorize(), or (more likely) because yourhttpd.confcontains a line like:PerlAuthzHandler My::AuthCookie->authorizeYou should remove lines from
httpd.confthat callauthorize, and your subclass should not be calling authorize().If you need to do custom autorization, you need to write an authz provider instead.
My log shows an entry like:
authorization result of Require ...: denied (no + # authenticated user yet)These are normal. This happens because the authz provider returned
AUTHZ_DENIED_NO_USERand the authz provider will be called again after authentication happens.