【问题标题】:Missing authorization headers with ApacheApache 缺少授权标头
【发布时间】:2021-06-23 17:03:22
【问题描述】:

我希望 Apache 默认将授权标头传递给 PHP。所以我将 Apache/2.4.29 (Ubuntu) 与 mod_php 一起使用,它允许“默认情况下通过 Apache 身份验证标头”。

这里是安装的 apache 模块。

核心mod_so mod_watchdog http_core mod_log_config mod_logio mod_version mod_unixd mod_access_compat mod_alias中mod_auth_basic mod_authn_core mod_authn_file模块mod_authz_core mod_authz_host mod_authz_user mod_autoindex mod_deflate模块mod_dir mod_env mod_filter mod_headers中mod_mime prefork的mod_negotiation模块mod_php7的mod_proxy的mod_proxy_ajp mod_proxy_balancer的mod_proxy_connect mod_proxy_html mod_proxy_http mod_proxy_wstunnel mod_reqtimeout mod_rewrite的mod_setenvif mod_slotmem_shm mod_socache_shmcb mod_ssl的mod_status的mod_xml2enc P>

这是我的虚拟主机配置。

<IfModule mod_ssl.c>
        <VirtualHost _default_:443>
                ServerAdmin webmaster@localhost
                ServerName piwal-elgg.com
                DocumentRoot /xxxx/xxxx/xxxx/WEB/piwal

                ErrorLog ${APACHE_LOG_DIR}/error.log
                CustomLog ${APACHE_LOG_DIR}/access.log combined

                SSLEngine on
                SSLCertificateFile      /xxx/xxx/certs/ssl-cert-snakeoil.pem
                SSLCertificateKeyFile   /xxx/xxx/private/ssl-cert-snakeoil.key

                <Directory /xxx/xxx/xxx/WEB/piwal>
                        Options Indexes FollowSymLinks
                        AllowOverride All
                        Require all granted
                </Directory>
        </VirtualHost>
</IfModule>

我已经阅读了很多关于这个主题的文档,其中一些要求我在 .htaccess 文件中添加额外的规则。

其中一些角色如下。

1- .htaccess

RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]

2- .htaccess

RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

3- .htaccess 或 apache 虚拟主机

SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

4- .htaccess 或 apache 虚拟主机

SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0

5-.htaccess

RewriteEngine on
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]

以上设置均无效。 “默认情况下不传递 Apache 身份验证标头”。

但是当我将 RequestHeader set Authorization "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" 添加到我的 virtualHost 配置时。在这种情况下,标头已被服务器正确处理。

有人可以帮我解决这个问题吗?

这是我的 $_SERVER supergloble 数组的输出

Array
(
    [REDIRECT_SCRIPT_URL] => /webdav/virtual/
    [REDIRECT_SCRIPT_URI] => https://xxxx-xxxx.com/webdav/virtual/
    [REDIRECT_HTTP_AUTHORIZATION] => 
    [REDIRECT_HTTPS] => on
    [REDIRECT_SSL_TLS_SNI] => xxxx-xxxx.com
    [REDIRECT_STATUS] => 200
    [SCRIPT_URL] => /webdav/virtual/
    [SCRIPT_URI] => https://xxxx-xxxx.com/webdav/virtual/
    [HTTP_AUTHORIZATION] => 
    [HTTPS] => on
    [SSL_TLS_SNI] => xxxx-xxxx.com
    [HTTP_HOST] => xxxx-xxxx.com
    [HTTP_USER_AGENT] => Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:86.0) Gecko/20100101 Firefox/86.0
    [HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    [HTTP_ACCEPT_LANGUAGE] => en-US,en;q=0.5
    [HTTP_ACCEPT_ENCODING] => gzip, deflate, br
    [HTTP_CONNECTION] => keep-alive
    [HTTP_COOKIE] => Elgg=or2a18jbqubrnkqk38mhhvguc5
    [HTTP_UPGRADE_INSECURE_REQUESTS] => 1
    [PATH] => /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
    [SERVER_SIGNATURE] => Apache/2.4.29 (Ubuntu) Server at xxxx-xxxx.com Port 443
    [SERVER_SOFTWARE] => Apache/2.4.29 (Ubuntu)
    [SERVER_NAME] => xxxx-xxxx.com
    [SERVER_ADDR] => 127.0.1.1
    [SERVER_PORT] => 443
    [REMOTE_ADDR] => 127.0.0.1
    [DOCUMENT_ROOT] => /xxxx/xxxx/xxxx/WEB/xxx-3-3-1
    [REQUEST_SCHEME] => https
    [CONTEXT_PREFIX] => 
    [CONTEXT_DOCUMENT_ROOT] => /xxxx/xxxx/xxxx/WEB/xxx-3-3-1
    [SERVER_ADMIN] => webmaster@localhost
    [SCRIPT_FILENAME] => /xxxx/xxxx/xxxx/WEB/xxx-3-3-1/index.php
    [REMOTE_PORT] => 41500
    [REDIRECT_URL] => /webdav/virtual/
    [GATEWAY_INTERFACE] => CGI/1.1
    [SERVER_PROTOCOL] => HTTP/1.1
    [REQUEST_METHOD] => GET
    [QUERY_STRING] => 
    [REQUEST_URI] => /webdav/virtual/
    [SCRIPT_NAME] => /index.php
    [PHP_SELF] => /index.php
    [REQUEST_TIME_FLOAT] => 1616958400.0139
    [REQUEST_TIME] => 1616958400
    [PHP_AUTH_USER] => 
    [PHP_AUTH_PW] => 
)

【问题讨论】:

    标签: php apache .htaccess http-headers authorization


    【解决方案1】:

    尝试在&lt;Directory&gt; 容器(在您的虚拟主机内)或.htaccess 中设置CGIPassAuth On (Apache 2.4.13+)。

    CGIPassAuth 允许脚本访问 HTTP 授权标头,例如 Authorization,这是实现 HTTP Basic 身份验证的脚本所必需的。通常,这些 HTTP 标头对脚本是隐藏的。这是为了在 Web 服务器中启用 HTTP Basic 身份验证时禁止脚本查看用于访问服务器的用户 ID 和密码。当允许脚本实现 HTTP Basic 身份验证时,应使用该指令。

    来源:https://httpd.apache.org/docs/2.4/mod/core.html#cgipassauth


    请注意,如果您在.htaccess 中设置环境变量HTTP_AUTHORIZATION,那么如果使用mod_rewrite 重写请求,您可能需要在PHP 脚本中检查REDIRECT_HTTP_AUTHORIZATION(注意REDIRECT_ 前缀) ,因为在第一遍中设置的任何环境变量都会在后续遍中重命名:REDIRECT_REDIRECT_HTTP_AUTHORIZATION 等等。


    除此之外: 您用于显式设置 HTTP_AUTHORIZATION 环境变量的所有 5 种方法实际上都是“相同的”——您不会期望一种方法有效而另一种方法无效。唯一的例外是#4。使用SetEnvIf,更可靠的是显式捕获组并使用$1 反向引用(正如您在#3 中所做的那样),而不是使用“应该”包含完整匹配的$0 反向引用。在某些情况下,当 regex 参数“看起来不像”1 正则表达式时,$0 反向引用未设置(尽管我不认为这会成为问题)。

    1“看起来”是指正则表达式不包含特殊元字符且仅包含拉丁字符的地方,例如。 helloworld - “看起来”是一个普通的字符串。在这种情况下,Apache/SetEnvIf 似乎进行了简单的子字符串比较,并且没有捕获正则表达式反向引用。

    【讨论】:

    • 非常感谢@MrWhite。我做到了,我在我的虚拟主机的 容器中添加了 CGIPassAuth On。但我仍然有同样的行为。这是我的测试方式。 $headers = array_change_key_case(apache_request_headers()); if(empty($headers['authorization'])){ echo "authorization not set"; } 但是当我将 RequestHeader set Authorization "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" 添加到我的 virtualHost 配置时。服务器正确处理标头。问候,
    • 检查 PHP $_SERVER 超全局数组。
    • (您应该将该信息添加到您的问题中,而不是发布 - 未格式化 - 跨多个 cmets。)该标题确实似乎缺失(或未设置)。您是否确认 Authorization 标头正在客户端的 HTTP 请求中发送?您是如何实现 HTTP 身份验证的?
    • 对不起,我刚刚将信息添加到我的问题中。我真的不知道为什么 apache 不发送 Authorization 标头。我正在使用 PHP 的 sabredav 框架实现一个 webdav 服务器。它需要 apache 发送 Authorization 标头。无论我做什么Authorization 标头都不会发送。仅当我在虚拟主机配置中手动设置时。
    猜你喜欢
    • 2017-03-21
    • 2012-10-27
    • 1970-01-01
    • 1970-01-01
    • 2023-02-01
    • 2019-06-17
    • 1970-01-01
    • 2012-11-03
    相关资源
    最近更新 更多