将 403 Forbidden 重定向到 404 Not Found 时出现问题
我的 .htaccess 的相关部分如下所示:
Options -Indexes
<FilesMatch include>
Order allow,deny
Deny from all
</FilesMatch>
RedirectMatch 404 ^/include(/.*)$
它正在生成以下响应:
- /include 403
- /include/ 404
- /include/config.inc 403
通过查看我的模式,我可以看出问题可能出现在 (/.* )部分,但我尝试过的一切都给了我相同的结果; 我不是一直得到 404,而是在一种情况下得到 404,而在其他情况下得到 403。 我使用的表达有什么问题? 或者,由于我必须对几个目录执行此操作,是否有一种通用方法可以让我将所有 403 响应转换为 404?
更新: 我发现通过删除 FileMatch我得到了更好的结果,所以我的 .htaccess 现在看起来像这样:
Options -Indexes
RedirectMatch 404 ^/include(/.*)?$ # Added dlamblin's first suggestion
并生成以下响应:
- /include 404
- /include/ 404
- /include/config.inc 403
更新: 有趣的是,我发现以下产生不同的输出:
RedirectMatch 404 ^/include(/?|/.*)$
RedirectMatch 404 ^/template(/?|/.*)$
模板模式适用于所有情况,但是 include 仍然为 include 中的所有文件生成 403(例如 /include/config.inc) 这可能是目录名称的问题,而不是目录名称的问题.htaccess 文件本身?
更新: 访问 /include/config.inc 时,我的 .htaccess 中的以下内容与重定向冲突。
<FilesMatch config>
Order allow,deny
Deny from all
</FilesMatch>
The pertinent part of my .htaccess looks like this:
Options -Indexes
<FilesMatch include>
Order allow,deny
Deny from all
</FilesMatch>
RedirectMatch 404 ^/include(/.*)$
And it's generating the following responses:
- /include 403
- /include/ 404
- /include/config.inc 403
I can tell by looking at my pattern that problem is likely in the (/.*) part but everything I have tried gives me the same results; instead of consistently getting 404 I get a 404 for the one case and 403 for everything else. What is wrong with the expression I'm using? Alternatively since I have to do this for a few directories is there a blanket approach that would allow me to convert all 403 responses to 404?
UPDATE: I've found that by removing the FileMatch I get better results, so my .htaccess now looks like this:
Options -Indexes
RedirectMatch 404 ^/include(/.*)?$ # Added dlamblin's first suggestion
And generates the following responses:
- /include 404
- /include/ 404
- /include/config.inc 403
UPDATE: Interestingly enough I have discovered that the following produces different output:
RedirectMatch 404 ^/include(/?|/.*)$
RedirectMatch 404 ^/template(/?|/.*)$
The template pattern works on all cases however include is still generating 403 for all files in include (e.g. /include/config.inc) Could this be an issue with the directory name and not a problem with the .htaccess file itself?
UPDATE: The following in my .htaccess was conflicting with redirect when accessing /include/config.inc.
<FilesMatch config>
Order allow,deny
Deny from all
</FilesMatch>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
我可以理解为什么 /include 没有被您的 RedirectMatch 捕获,您没有将结尾的“/”设为可选,但是 /include/config.inc 部分有点令人费解。
以下是我在 Apache 2.2 上所做的工作:
这可以处理这些情况:
我必须更改 FilesMatch 部分才能使 /include 部分正常工作。
编辑:
匹配线在没有的情况下也可以工作。 .htaccess 中的部分并给出了预期结果。
I can understand why the /include isn't caught by your RedirectMatch, you aren't making the end '/' optional, however the /include/config.inc part is a bit on the puzzling side.
Here is what I got to work on Apache 2.2:
This handles these cases:
I had to change the FilesMatch part in order for the /include part to work properly.
EDIT:
The match line also works without the <FilesMatch> section in .htaccess and gives the expected results.
另一种可能性是不必费心匹配整个路径:
如果存在可能以“/include”开头的公开可见的 URL 路径(例如“/includeMe”),则添加一个小内容即可将私有 URL 与公共 URL 分开:
Another possibility is not to bother matching the whole path:
If there are publicly visible URL paths that might start with "/include" (say, "/includeMe"), a small addition will separate the private from the public URLs:
使用重写模式:
每个以点开头的文件或目录都将被重定向到 404。
或者要将所有 403,400 错误更改为 404 错误,请将其放在 /etc/apache2/conf.d/localized-error 的末尾-pages 或 .htaccess
With rewrite mod:
Every file or dir who begin with a dot will be redirected to 404.
Or to change all 403,400 errors into 404 errors, put this at the end of /etc/apache2/conf.d/localized-error-pages OR into a .htaccess
难道你不想要 '^/include(/.*)?$'
这部分是猜测,但是如果你将 RedirectMatch 放在块上方会发生什么。 这样,在将请求重定向到 404 之前,您就不会拒绝(禁止)对请求的访问。
Don't you want '^/include(/.*)?$'
This part is a guess, but what would happen if you put the RedirectMatch above the block. That way you wouldn't by denying (forbidding) access to a request before you redirect that request to 404.
一个更好和简单的方法如下:
1 - 插入你的主conf(即外部VHOST世界):
与myDirectory = css,js,images ...
2 - 您可以设置每个目录的索引如下:
允许您的“ DirectoryIndex”要提供的 Apache 指令内容:
并拒绝其他人的目录索引:
使用 myDirectory = *, css, images, js, Secret, ... 根据您的需要。
A better and simple way is as follow :
1 - Insert in your main conf (ie Outside VHOST world) :
with myDirectory = css, js, images ...
2 - You can set a per directory -Indexes as follow :
Allow your "DirectoryIndex" Apache directive content to be served :
and Deny directory index for others :
with myDirectory = *, css, images, js, secret, ... following your needs.
对于名称以点开头的所有文件/目录,即使在子目录中,此操作也按预期工作:
This one works as expected for all files/dirs with name started by dot even in subdirectories:
在这种情况下,您不需要使用
Options -Indexes
我停止将目录内容显示为列表并显示 404 错误的解决方案很简单。 在项目的根目录中创建 .htaccess 文件并写入应保护哪些目录。
目录结构
.htaccess
ErrorDocument 404 /your_root_directory/404.html
.htaccess 的第二行禁止访问应用程序目录及其所有子目录中的列表项。
.htaccess 的第三行禁止访问 models 目录及其所有子目录中的列表项。
.htaccess 行的第四行设置我们自己的 404 错误(如果您不想显示 apache 默认错误)。
使用 htaccess 时请记住清除浏览器上的缓存。
In that case you do not need to use
Options -Indexes
My solution to stop displaying directory's content as list and display 404 error is simple. Create .htaccess file in root directory of your project and write which directories should be protected.
Directories structure
.htaccess
ErrorDocument 404 /your_root_directory/404.html
The second line of .htaccess disallow access to list items in app directory and all its subridectories.
The third line of .htaccess disallow access to list items in models directory and all its subridectories.
The fourth of .htaccess line sets our own 404 error (if you do not want to show apache default error).
Remember to clear cache on your browser when you work with htaccess.
我尝试了这个解决方案,但遇到了另一个问题:
此外,尝试使用 ErrorDocument 处理请求时遇到 403 Forbidden 错误:
I tried this solution, but I met another issue:
Additionally, a 403 Forbidden error was encountered while trying to use an ErrorDocument to handle the request: