Mailing List Archive

Apache 2.4 Authentication/Authorization
Hi.

I am trying to figure out what Apache2::Const return codes /can/ be returned by a mod_perl
/authentication/ method under Apache 2.4+, and what consequences each of these return
codes has, in terms of what Apache does next.
(And also, where to find a commented list of the Apache "AHxxxx" error messages)

Does anyone know where I could find this information, other than perhaps the Apache httpd
source code ? (and if only there, where ?)

I have done multiple searches in Google, but nothing really relevant shows up (lots of
"receipes" there for specific cases, but no general explanation).
I have also consulted :
- the cpan Apache2::Const documentation which lists all the return codes, but without
comments as to what they're used for or where they are applicable.
- the mod_perl2 documentation
(http://perl.apache.org/docs/2.0/user/handlers/http.html#PerlAuthenHandler) /may/ be
somewhat outdated, as it is in other respects for the Apache 2.4 AAA API.

Thanks in advance

(long) Context:

With a lot of inspiration and cut-and-paste from Apache2::AuthCookie (thanks Michael
Schout, also for the 2.4 doc add-on), I have written a mod_perl AAA framework
(aka "PerlAddAuthzProvider xxx Our::Own::Module->authz_user" ),
adapted to the particular needs of our applications, and which is/should be able to work
in conjunction with most built-in or third-party add-on Apache authentication modules
(such as mod_authnz_ldap, mod_shib2, etc). (This because each of our corporate customers
each have their own web-AAA infrastructure, and we need to be compatible with all of them).

Now I have the case where the authentication method itself (aka "PerlAuthenHandler
Our::Own::Module::XXX->authenticate") is one which we need to develop ourselves, because
the customer's corporate framework is somewhat "non-standard" itself.
Thus, our authenticate() method calls the customer's back-end method, and looks at what it
returns.
The back-end external framework can sometimes fail to authenticate a user, and returns a
specific response in such a case. Our authenticate() method catches this, and should then
itself return an appropriate return code, such that Apache 2.4 next calls the (our)
authz_user() method again, which can then e.g. deny/allow access to the resource.

If authenticate() returns Apache2::Const::HTTP_UNAUTHORIZED, then it seems that Apache
immediately aborts the request and returns a 401 Unauthorised response to the browser.
(In any case, it does /not/ call the perl AuthzProvider again).
(That is not really what I want; I'd like it to call authz_user() anyway, and let
authz_user() decide what happens next).

If authenticate() returns Apache2::Const::OK, then there is no Apache log message; but
when it calls authz_user() next, that authz_user() should be able to find out that the
authentication failed.
Or should I just leave $r->user empty in that case and check on that ? is that what the
other (standard) authentication modules do ?

If authenticate() returns Apache2::Const::DECLINE, Apache subsequently prints a message in
the server error log, such as :
[Thu May 09 20:52:31.197841 2019] [authn_core:error] [pid 9139] [client xxxx:4038]
AH01796: AuthType OUR::OWN::MOD configured without corresponding module ..
(and it does not call the AuthzProvider again either).
(I think that I understand why it does that, since the only authentication method
configured is mine, and it returns DECLINED)

Or else, what could authenticate() return ?

I can of course do several trials returning different things and see what works, but I
would prefer to know the official do's and don'ts and the Apache 2.4 logic behind them.
Re: Apache 2.4 Authentication/Authorization [ In reply to ]
Additional info, from the mod_perl 2 documentation and elsewhere :

1) mod_perl :
http://perl.apache.org/docs/2.0/user/handlers/http.html#PerlAuthenHandler
says that this phase is of type RUN_FIRST,
and
http://perl.apache.org/docs/2.0/user/handlers/intro.html#C_RUN_FIRST_
says "If the return value is Apache2::Const::DECLINED, the next handler in the chain will
be run. If the return value is Apache2::Const::OK the next phase will start. In all other
cases the execution will be aborted."

/If that information is still valid for Apache 2.4/, then it seems that the only way to
achieve what I want (and which in my views matches the 2.4 general AAA logic), would be to
let the authentication method return Apache2::Const::OK, /even if the user is not
authenticated/ by the configured authentication method.

2) from https://metacpan.org/pod/distribution/Apache-AuthCookie/README.apache-2.4.pod
(the httpd.conf section)
This may well be the most explicit information readily available, about how the Apache 2.4
authentication/authorization logic really works "underneath". At any rate, I have not
been able to find a better documentation anywhere.


On 15.05.2019 15:42, André Warnier (tomcat) wrote:
> Hi.
>
> I am trying to figure out what Apache2::Const return codes /can/ be returned by a mod_perl
> /authentication/ method under Apache 2.4+, and what consequences each of these return
> codes has, in terms of what Apache does next.
> (And also, where to find a commented list of the Apache "AHxxxx" error messages)
>
> Does anyone know where I could find this information, other than perhaps the Apache httpd
> source code ? (and if only there, where ?)
>
> I have done multiple searches in Google, but nothing really relevant shows up (lots of
> "receipes" there for specific cases, but no general explanation).
> I have also consulted :
> - the cpan Apache2::Const documentation which lists all the return codes, but without
> comments as to what they're used for or where they are applicable.
> - the mod_perl2 documentation
> (http://perl.apache.org/docs/2.0/user/handlers/http.html#PerlAuthenHandler) /may/ be
> somewhat outdated, as it is in other respects for the Apache 2.4 AAA API.
>
> Thanks in advance
>
> (long) Context:
>
> With a lot of inspiration and cut-and-paste from Apache2::AuthCookie (thanks Michael
> Schout, also for the 2.4 doc add-on), I have written a mod_perl AAA framework
> (aka "PerlAddAuthzProvider xxx Our::Own::Module->authz_user" ),
> adapted to the particular needs of our applications, and which is/should be able to work
> in conjunction with most built-in or third-party add-on Apache authentication modules
> (such as mod_authnz_ldap, mod_shib2, etc). (This because each of our corporate customers
> each have their own web-AAA infrastructure, and we need to be compatible with all of them).
>
> Now I have the case where the authentication method itself (aka "PerlAuthenHandler
> Our::Own::Module::XXX->authenticate") is one which we need to develop ourselves, because
> the customer's corporate framework is somewhat "non-standard" itself.
> Thus, our authenticate() method calls the customer's back-end method, and looks at what it
> returns.
> The back-end external framework can sometimes fail to authenticate a user, and returns a
> specific response in such a case. Our authenticate() method catches this, and should then
> itself return an appropriate return code, such that Apache 2.4 next calls the (our)
> authz_user() method again, which can then e.g. deny/allow access to the resource.
>
> If authenticate() returns Apache2::Const::HTTP_UNAUTHORIZED, then it seems that Apache
> immediately aborts the request and returns a 401 Unauthorised response to the browser.
> (In any case, it does /not/ call the perl AuthzProvider again).
> (That is not really what I want; I'd like it to call authz_user() anyway, and let
> authz_user() decide what happens next).
>
> If authenticate() returns Apache2::Const::OK, then there is no Apache log message; but
> when it calls authz_user() next, that authz_user() should be able to find out that the
> authentication failed.
> Or should I just leave $r->user empty in that case and check on that ? is that what the
> other (standard) authentication modules do ?
>
> If authenticate() returns Apache2::Const::DECLINE, Apache subsequently prints a message in
> the server error log, such as :
> [Thu May 09 20:52:31.197841 2019] [authn_core:error] [pid 9139] [client xxxx:4038]
> AH01796: AuthType OUR::OWN::MOD configured without corresponding module ..
> (and it does not call the AuthzProvider again either).
> (I think that I understand why it does that, since the only authentication method
> configured is mine, and it returns DECLINED)
>
> Or else, what could authenticate() return ?
>
> I can of course do several trials returning different things and see what works, but I
> would prefer to know the official do's and don'ts and the Apache 2.4 logic behind them.
Re: Apache 2.4 Authentication/Authorization [ In reply to ]
On 5/15/19 8:42 AM, André Warnier (tomcat) wrote:
> (In any case, it does /not/ call the perl AuthzProvider again).
> (That is not really what I want; I'd like it to call authz_user()

Apache doesn't work that way. Everything you've described is basically
just how things work in 2.4.

your authz_user() will be called (up to) two times.

1. Before authentication where $r->user is not set. The purpose of this
is to allow you to handle *anonymous* authorization. You can return
AUTHZ_GRANTED here and no authentication will happen at all I
believe.

2. Or, you can return AUTHZ_DENIED_NO_USER, which will trigger
authentication, and *only if that succeeds*, will your authz_user()
be called a second time.

> anyway, and let authz_user() decide what happens next).

Yeah, Apache just doesn't work this way.

The only way to hack this that I can think of is for you to set
something in $r->user that indicates that the authentication failed and
authz_user could figure out what went wrong in the second call based on
the value of $r->user. That's all you have to go on. You might even be
able to use pnotes() to stash away extra stuff you need, but this feels
like a horrible hack IMO.

It's not particularly clear to me what "let authz_user() decide what
happens next" means in this context. If authorization fails, typically
you would just return an error code such as
Apache2::Const::SERVER_ERROR. If it was successful, and the user is
valid, you'd return Apache2::Const::OK. Otherwise you would typically
return Apache2::Const::UNAUTHORIZED.

If you to customize what is displayed for those messages, typically you
use $r->custom_response() (see Apache2::Response).

In today's times, when compared to modern alternatives like Plack/PSGI,
this all feels very cumbersome and antiquated IMO.

Regards,
Michael Schout
Re: Apache 2.4 Authentication/Authorization [ In reply to ]
Honestly, the best, and possibly only, source for the information you're
after is probably the httpd source code. Unless there is some high level
documentation that has more details than this does:

https://httpd.apache.org/docs/2.4/howto/auth.html

There's also this, which is supposed to be the documentation for the C
API that mod_perl is built on, but it has a gaping hole where the
information about AAA should be

https://httpd.apache.org/docs/2.4/developer/API.html

You might be able to get some help from people on the httpd list as well.

Adam



On 2019-05-16 5:43 a.m., André Warnier (tomcat) wrote:
> Additional info, from the mod_perl 2 documentation and elsewhere :
>
> 1) mod_perl :
> http://perl.apache.org/docs/2.0/user/handlers/http.html#PerlAuthenHandler
> says that this phase is of type RUN_FIRST,
> and
> http://perl.apache.org/docs/2.0/user/handlers/intro.html#C_RUN_FIRST_
> says "If the return value is Apache2::Const::DECLINED, the next handler
> in the chain will be run. If the return value is Apache2::Const::OK the
> next phase will start. In all other cases the execution will be aborted."
>
> /If that information is still valid for Apache 2.4/, then it seems that
> the only way to achieve what I want (and which in my views matches the
> 2.4 general AAA logic), would be to let the authentication method return
> Apache2::Const::OK, /even if the user is not authenticated/ by the
> configured authentication method.
>
> 2) from
> https://metacpan.org/pod/distribution/Apache-AuthCookie/README.apache-2.4.pod
>
> (the httpd.conf section)
> This may well be the most explicit information readily available, about
> how the Apache 2.4 authentication/authorization logic really works
> "underneath".  At any rate, I have not been able to find a better
> documentation anywhere.
>
>
> On 15.05.2019 15:42, André Warnier (tomcat) wrote:
>> Hi.
>>
>> I am trying to figure out what Apache2::Const return codes /can/ be
>> returned by a mod_perl
>> /authentication/ method under Apache 2.4+, and what consequences each
>> of these return
>> codes has, in terms of what Apache does next.
>> (And also, where to find a commented list of the Apache "AHxxxx" error
>> messages)
>>
>> Does anyone know where I could find this information, other than
>> perhaps the Apache httpd
>> source code ? (and if only there, where ?)
>>
>> I have done multiple searches in Google, but nothing really relevant
>> shows up (lots of
>> "receipes" there for specific cases, but no general explanation).
>> I have also consulted :
>> - the cpan Apache2::Const documentation which lists all the return
>> codes, but without
>> comments as to what they're used for or where they are applicable.
>> - the mod_perl2 documentation
>> (http://perl.apache.org/docs/2.0/user/handlers/http.html#PerlAuthenHandler)
>> /may/ be
>> somewhat outdated, as it is in other respects for the Apache 2.4 AAA API.
>>
>> Thanks in advance
>>
>> (long) Context:
>>
>> With a lot of inspiration and cut-and-paste from Apache2::AuthCookie
>> (thanks Michael
>> Schout, also for the 2.4 doc add-on), I have written a mod_perl AAA
>> framework
>> (aka "PerlAddAuthzProvider xxx Our::Own::Module->authz_user" ),
>> adapted to the particular needs of our applications, and which
>> is/should be able to work
>> in conjunction with most built-in or third-party add-on Apache
>> authentication modules
>> (such as mod_authnz_ldap, mod_shib2, etc). (This because each of our
>> corporate customers
>> each have their own web-AAA infrastructure, and we need to be
>> compatible with all of them).
>>
>> Now I have the case where the authentication method itself (aka
>> "PerlAuthenHandler
>> Our::Own::Module::XXX->authenticate") is one which we need to develop
>> ourselves, because
>> the customer's corporate framework is somewhat "non-standard" itself.
>> Thus, our authenticate() method calls the customer's back-end method,
>> and looks at what it
>> returns.
>> The back-end external framework can sometimes fail to authenticate a
>> user, and returns a
>> specific response in such a case. Our authenticate() method catches
>> this, and should then
>> itself return an appropriate return code, such that Apache 2.4 next
>> calls the (our)
>> authz_user() method again, which can then e.g. deny/allow access to
>> the resource.
>>
>> If authenticate() returns Apache2::Const::HTTP_UNAUTHORIZED, then it
>> seems that Apache
>> immediately aborts the request and returns a 401 Unauthorised response
>> to the browser.
>> (In any case, it does /not/ call the perl AuthzProvider again).
>> (That is not really what I want; I'd like it to call authz_user()
>> anyway, and let
>> authz_user() decide what happens next).
>>
>> If authenticate() returns Apache2::Const::OK, then there is no Apache
>> log message; but
>> when it calls authz_user() next, that authz_user() should be able to
>> find out that the
>> authentication failed.
>> Or should I just leave $r->user empty in that case and check on that ?
>> is that what the
>> other (standard) authentication modules do ?
>>
>> If authenticate() returns Apache2::Const::DECLINE, Apache subsequently
>> prints a message in
>> the server error log, such as :
>> [Thu May 09 20:52:31.197841 2019] [authn_core:error] [pid 9139]
>> [client xxxx:4038]
>> AH01796: AuthType OUR::OWN::MOD configured without corresponding
>> module ..
>> (and it does not call the AuthzProvider again either).
>> (I think that I understand why it does that, since the only
>> authentication method
>> configured is mine, and it returns DECLINED)
>>
>> Or else, what could authenticate() return ?
>>
>> I can of course do several trials returning different things and see
>> what works, but I
>> would prefer to know the official do's and don'ts and the Apache 2.4
>> logic behind them.
>