【问题标题】:Excluding a specific URL from HTTP Basic Auth - mod_rewrite causing problems从 HTTP 基本身份验证中排除特定 URL - mod_rewrite 导致问题
【发布时间】:2021-07-28 10:11:14
【问题描述】:

我们在我们的某个子域上有“HTTP Basic Auth”,但希望允许所有内容访问该子域上的特定 URL 而无需进行身份验证(对于点击我们的 webhook URL 的第 3 方)。

所以我尝试使用SetEnvIf Request_URI ^/webhook/ allow 来允许Allow from env=allow(下面的完整文件),但似乎因为我们有一些 mod_rewrite 规则将所有这些 URL 重写为 PHP 入口点,所以 Request_URI 实际上从来没有/webhook 一旦它到达这一点(猜测但不知道如何 100% 确认这一点。

不管 URL 是什么,它仍然要求一个基本的身份验证用户/密码。

请注意,.htaccess 文件在我们所有的域/子域上都是相同的,而 VirtualHost 可以仅针对该子域进行配置。

带有“HTTP Basic Auth”配置部分的完整 VirtualHost 配置:

<VirtualHost *:80>
  RewriteEngine on
  RewriteCond %{HTTP:X-Forwarded-Proto} !https
  RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=permanent,L]

  DocumentRoot /var/www/sub.ourdomain.co.uk/blah/www

  ServerAdmin x@ourdomain.co.uk
  ServerName sub.ourdomain.co.uk
  ServerAlias www.sub.ourdomain.co.uk

  ErrorDocument 400 /error.php
  ErrorDocument 401 /error.php
  ErrorDocument 403 /403.html
  ErrorDocument 404 /error.php
  ErrorDocument 405 /error.php
  ErrorDocument 408 /error.php
  ErrorDocument 410 /error.php
  ErrorDocument 411 /error.php
  ErrorDocument 412 /error.php
  ErrorDocument 413 /error.php
  ErrorDocument 414 /error.php
  ErrorDocument 415 /error.php
  ErrorDocument 500 /error.php
  ErrorDocument 501 /error.php
  ErrorDocument 502 /error.php
  ErrorDocument 503 /error.php
  ErrorDocument 506 /error.php

  ErrorLog /var/log/httpd/sub.ourdomain.co.uk.apache.log
  CustomLog /var/log/httpd/sub.ourdomain.co.uk.access.log combined

  <Directory "/var/www/sub.ourdomain.co.uk/blah/www">
    SetEnvIf Request_URI ^/webhook/ allow

    AuthType Basic
    AuthName "Restricted Content"
    AuthUserFile /etc/httpd/passwords/sub.ourdomain.co.uk

    # Setup a deny/allow
    Order Deny,Allow
    # Deny from everyone
    Deny from all
    # except if either of these are satisfied
    Satisfy any
    # 1. a valid authenticated user
    Require valid-user
    # or 2. the "allow" var is set
    Allow from env=allow
  </Directory>
</VirtualHost>

.htaccess mod_rewrite 规则:

RewriteCond %{REQUEST_METHOD} !(^GET|^POST|^HEAD)
RewriteRule .* - [R=405,L]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(/img|/js|/css|/fonts)

RewriteRule ^(.*)$ /boot.php

RewriteCond %{REQUEST_URI} ^/$
RewriteRule ^(.*)$ /boot.php

编辑 1 - 基于我也尝试过的 cmets:SetEnv allow trueSetEnv allow 1 以消除是否是 URL 的疑问,它仍然要求输入基本身份验证密码,所以它可能毕竟与网址无关。

编辑 2 - 添加整个 .htaccess 以确保我没有遗漏其他内容:

php_value max_input_vars 4000

RewriteEngine on

# Disallow other HTTP verbs such as PUT and DELETE
RewriteCond %{REQUEST_METHOD} !(^GET|^POST|^HEAD)
RewriteRule .* - [R=405,L]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(/img|/js|/css|/fonts|/twig|/pdf|/vendors|/server-status)

RewriteRule ^(.*)$ /boot.php

RewriteCond %{REQUEST_URI} ^/$
RewriteRule ^(.*)$ /boot.php

AddType font/ttf .ttf
AddType font/eot .eot
AddType font/otf .otf
AddType font/woff .woff

<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/css text/javascript application/x-javascript application/javascript text/x-component text/html text/richtext image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon application/json font/woff font/otf font/eot font/ttf
</IfModule>

<ifModule mod_expires.c>
  ExpiresActive On
  ExpiresDefault "access plus 1 seconds"
  ExpiresByType text/html "access plus 1 seconds"
  ExpiresByType image/gif "access plus 2592000 seconds"
  ExpiresByType image/jpeg "access plus 2592000 seconds"
  ExpiresByType image/png "access plus 2592000 seconds"
  ExpiresByType text/css "access plus 604800 seconds"
  ExpiresByType font/ttf "access plus 604800 seconds"
  ExpiresByType font/eot "access plus 604800 seconds"
  ExpiresByType font/otf "access plus 604800 seconds"
  ExpiresByType font/woff "access plus 604800 seconds"
  ExpiresByType text/javascript "access plus 604800 seconds"
  ExpiresByType application/x-javascript "access plus 604800 seconds"
</ifModule>

<ifModule mod_headers.c>
  <filesMatch "\\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$">
    Header set Cache-Control "max-age=2592000, public, proxy-revalidate"
  </filesMatch>
  <filesMatch "\\.(js|css|ttf|eot|otf|woff)$">
    Header set Cache-Control "max-age=604800, public, proxy-revalidate"
  </filesMatch>
  <filesMatch "\\.(xml|txt)$">
    Header set Cache-Control "max-age=216000, public, must-revalidate"
  </filesMatch>
</ifModule>

编辑 3 - 抱歉,应该提到我们现在停留在 Apache 2.2 上。

【问题讨论】:

  • “猜测但不知道如何 100% 确认。” - 简单,使用SetEnv 而不是SetEnvIf,在任何情况下设置变量,独立于请求 URI,然后查看您的拒绝/要求/允许设置是否允许您在没有凭据的情况下访问。如果确实如此,那么您知道 SetEnvIf 没有按预期工作,如果没有,那么您知道错误出现在该设置的其余部分。
  • 有趣,谢谢!情节变厚了。我刚试过SetEnv allow trueSetEnv allow 1,它仍然要求输入密码。
  • 您的auth 代码看起来不错,应该可以正常工作。您的 htaccess 中是否还有其他规则或指令?还可以尝试清除浏览器缓存并尝试重新启动服务器,看看是否有帮助。
  • 我将用我的整个 .htaccess 更新问题,但看不到其他相关内容。我已经清除了缓存并重新启动了服务器,但同样的问题仍然存在。现在使用 docker 在本地测试它并完全重建了容器。

标签: apache .htaccess mod-rewrite basic-authentication


【解决方案1】:

使用 Apache 2.4+,您可以使用 &lt;If&gt; 表达式禁用身份验证或使用 allow from all 指令使用 THE_REQUEST 变量的 URI。 THE_REQUEST 表示发送到 Apache 的原始请求,它不会在单个请求的上下文中更新:

AuthType Basic
AuthName "Restricted Content"
AuthUserFile /etc/httpd/passwords/sub.ourdomain.co.uk
Require valid-user
Satisfy any
Order   deny,allow
Deny from  all

<If "%{THE_REQUEST} =~ /webhook/">
Satisfy any
Allow from all
</If>

# your current mod_rewrite rules can appear below this line:
DirectoryIndex boot.php
RewriteEngine on

# Disallow other HTTP verbs such as PUT and DELETE
RewriteCond %{REQUEST_METHOD} !^(GET|POST|HEAD)
RewriteRule ^ - [R=405,L]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(/img|/js|/css|/fonts|/twig|/pdf|/vendors|/server-status)
RewriteRule ^ boot.php [L]

更新:这是一个使用 &lt;FilesMatch&gt; 指令在 Apache 2.2 上工作的解决方法

DirectoryIndex boot.php
RewriteEngine on

# Disallow other HTTP verbs such as PUT and DELETE
RewriteCond %{REQUEST_METHOD} !^(GET|POST|HEAD)
RewriteRule ^ - [R=405,L]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(/img|/js|/css|/fonts|/twig|/pdf|/vendors|/server-status)
RewriteRule ^ boot.php [L]

SetEnvIfNoCase Request_URI ^/webhook/ allow

<FilesMatch "^(?!boot\.php$).*$">
   AuthType Basic
   AuthName "Restricted Content"
   AuthUserFile /etc/httpd/passwords/sub.ourdomain.co.uk
   Require valid-user
   Order   Deny,Allow
   Deny from  all
   Allow from env=allow
   Satisfy any
</FilesMatch>

【讨论】:

  • 不幸的是,我们现在被困在 2.2 上。升级计划超出了我的控制(但已经表示我们应该这样做!)。不过感谢您的回答。
  • 所以我们需要把它放在 vhost 配置中而不是使用 .htaccess?不确定我是否完全遵循。理想情况下,希望将重写条件保留在 htaccess 中,并将基本身份验证保留在 vhost 中。你猜这是不可能的?
  • 我们想避免使用 htaccess,因为它在我们的应用程序中(提交给 git)并在所有环境之间共享 - 所以我们必须在部署期间做一些时髦的事情来说“如果 env == this , 使用这个 htaccess 文件,否则使用这个”。只有几个环境需要具有此基本身份验证,这就是为什么能够将其添加到需要它的虚拟主机的原因。
  • 如果这个答案包含在 vhost 配置中,它将以同样的方式工作。当然,每次进行更改时都需要重新启动。在你的虚拟主机配置中测试它,让我知道它是怎么回事。顺便说一句,如果您不想在那里使用 .htaccess 标签,您应该从问题中删除它。
  • 在 vhost 配置中除了我们网站的根目录之外的所有内容都收到“错误请求”响应。我们将关闭基本身份验证并依赖应用程序中的其他身份验证方法。时间已经用完了,所以有一段时间不能再研究它了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-09
  • 2011-04-21
  • 1970-01-01
  • 2016-02-04
  • 1970-01-01
  • 2012-08-25
相关资源
最近更新 更多