问题
We are using the new authentication and authorization framework offered by Apache-2.4 and need to close the entire site (Location /) to unauthorized access except for one subdirectory (Location /foo), where there authorizing cookie can be obtained. It would seem, that AuthMerging is the directive to use, but things do not work:
<Location />
AuthType form
AuthFormProvider foo
Session On
SessionCookieName ti2f
Include conf/sessionpw.conf
AuthName TI
<RequireAll>
Require foo ipaddress
Require foo expiration
</RequireAll>
ErrorDocument 401 /foo/
</Location>
<Location /foo>
AuthMerging Or
Require all granted
DirectoryIndex index.php
</Location>
Unfortunately, access to /foo remains blocked -- 401 Unauthorized. With LogLevel cranked up I can see the following messages logged by mod_authz_core:
authorization result of Require all granted: granted
authorization result of <RequireAny>: granted
authorization result of AuthMerging Any: granted
authorization result of Require all granted: granted
authorization result of <RequireAny>: granted
authorization result of AuthMerging Any: granted
authorization result of Require foo ipaddress: denied (no authenticated user yet)
authorization result of Require foo expiration: denied (no authenticated user yet)
authorization result of <RequireAll>: denied (no authenticated user yet)
authorization result of <RequireAny>: denied (no authenticated user yet)
With AuthMerging set to "Or" for sublocation /foo, why is Apache examining the parent location's require-directives at all after "Require all granted" grants?
回答1:
Use LocationMatch instead:
<LocationMatch "!^/foo">
# lock down everything EXCEPT /foo
</LocationMatch>
回答2:
After some debugging, I was able to figure things out. The odd thing about Apache's authorization core (and, reportedly, it was even worse in Apache-2.2) is that the rules, if any, may be applied multiple time per hit. For example, in the case above, this happened three times for the same request -- for "/foo/"
- For the actual "/foo/". This was processed according to the rules for Location /foo/ and granted as expected.
- For "/foo/index.php". This was also processed according to the rules for Location /foo/ and granted incidentally. This explains, why I saw two such grants logged for each hit.
- Because we use PHP FPM to process PHP-files, the request was passed through the authz rules yet again -- as "/php-fpm/foo/index.php". This time it had to go through the top-level Location /, because it never occured to us, we need to have a separate Location /php-fpm/ as well...
Whether the current Apache's behavior is buggy or merely odd is still being debated, but my solution was to describe my sublocation thus:
<LocationMatch ^(/php-fpm)?/foo/>
Require all granted
DirectoryIndex index.php
</LocationMatch>
AuthMerging is not even necessary in this case. Or I could also just add another Location -- for /php-fpm/. Either way, once the problem is understood, solutions are available...
来源:https://stackoverflow.com/questions/17974096/apache-2-4-how-to-close-entire-site-except-one-subdirectory