Do not have access to all folders except a specific folder by .htaccess
With Apache you can negate a regex (or expression) by simply prefixing it with !
(exclamation mark).
For example, to block every URL, except those that start /project/web/
, you can use the following in the /project/.htaccess
file:
RewriteRule !^web/ - [F]
Providing the .htaccess
file is inside the /project
subdirectory then you do not need to specify the project/
prefix, since the URL-path matched by the RewriteRule
pattern is relative to the location of the .htaccess
file.
This needs to go near the top of the .htaccess
file.
RewriteRule (?!web)(/.*)?$ - [F,NC]
Alternatively, using a negative lookahead in the regex (NB: Apache uses PCRE, not the "Java 8" flavour of regex).
You are missing the start of string anchor. But then the slash won't match since the negative-lookahead assertion does not actually match anything (and the URL-path matched by the RewriteRule
pattern does not start with a slash).
You could use the following instead:
RewriteRule ^(?!web($|/)) - [F]
We don't need to actually match anything, the regex just needs to be "successful" in order to trigger the directive and block the request. For example
Alternatively, you can use mod_authz_core instead. For example:
# /project/.htaccess
# Block access to everything
Require all denied
Create an additional access file in the /web
sudirectory:
# /project/web/.htaccess
# Allow access
Require all granted
Or, you can do this all in /project/.htaccess
with an Apache <If>
expression (Apache 2.4). Although this is made a little more complex because it could be accessed by either the project
subdomain or subdirectory and we are matching against the entire URL-path. For example:
# /project/.htaccess
# Block everything except the "/web" subdirectory
<If "%{REQUEST_URI} !~ m#^(/[^/]+)?/web($|/)#">
Require all denied
</If>
The operator !~
does not match the regex.