我遇到了一个问题,无法从一个Apache Web服务器访问另一个Web服务器上的文件,甚至无法从同一台Web服务器上访问。
首先让我给您介绍一下涉及到的两个服务器的规格。
服务器1:
Windows Server 2003
Apache 2.2 32bit
PHP 5.2.10
服务器 2:
Windows Server 2012 R2 Standard
Apache 2.4 64bit
PHP 5.6.5
为了实现单点登录,我在旧服务器上使用mod_auth_sspi模块来读取Windows远程用户。不幸的是,这个模块在Apache 2.4中不再受支持,所以我改用了mod_authnz_sspi。读取用户名的功能很好用,但如果我在旧服务器上运行一个连接到新服务器并读取文件的PHP脚本,该脚本会被拒绝,并返回HTTP状态码401(未授权)。当我在新服务器上运行同样的脚本尝试读取旧服务器上的同一文件时,它完美地工作了(希望这不太令人困惑。您可能已经注意到,英语不是我的母语)。
我使用了get_headers()函数来访问该文件,简化后的脚本如下:
<?php
print_r(get_headers("http://server1/test.txt", 1));
print_r(get_headers("http://server2/test.txt", 1));
?>
test.txt是两台服务器上的空文件。因此,脚本首先尝试在一台服务器上读取该文件,然后在另一台服务器上读取。结果在两台服务器上看起来都相同。两台服务器都可以连接到第一个服务器:
[0] => HTTP/1.1 200 OK
[Date] => Mon, 01 Jun 2015 13:18:56 GMT
[Server] => Apache/2.2.11 (Win32) mod_auth_sspi/1.0.4 PHP/5.2.10
[Last-Modified] => Mon, 01 Jun 2015 13:12:58 GMT
[Accept-Ranges] => bytes
[Content-Length] => 0
[Connection] => close
[Content-Type] => text/plain
但第二个没有任何东西:
[0] => HTTP/1.1 401 Unauthorized
[Date] => Mon, 01 Jun 2015 13:18:56 GMT
[Server] => Apache/2.4.12 (Win64) mod_authnz_sspi/0.1.0 PHP/5.6.5
[WWW-Authenticate] => Array
(
[0] => NTLM
[1] => Basic realm="mycompany_proxy.loc"
)
[Content-Length] => 381
[Connection] => close
[Content-Type] => text/html; charset=iso-8859-1
我查看了两台服务器上的Apache访问日志。对于test.txt,旧的服务器没有显示出任何问题:
[IP address server1] - - [01/Jun/2015:15:22:00 +0200] "GET /test.txt HTTP/1.0" 200 -
[IP address server2] - - [01/Jun/2015:15:18:56 +0200] "GET /test.txt HTTP/1.0" 200 -
另一方面,新的:
[IP address server1] - - [01/Jun/2015:15:22:00 +0200] "GET /test.txt HTTP/1.0" 401 381 "-" "-"
::1 - - [01/Jun/2015:15:18:56 +0200] "GET /test.txt HTTP/1.0" 401 381 "-" "-"
所以既旧服务器(server1)也新服务器(通过本地主机)都无法访问该文件。
如果我通过本地计算机上的浏览器从新服务器访问test.txt(这个方法完全可行),则日志文件中可以找到以下条目:
[Local IP address] - - [01/Jun/2015:15:47:20 +0200] "GET /test.txt HTTP/1.1" 401 381
[Local IP address] - - [01/Jun/2015:15:47:20 +0200] "GET /test.txt HTTP/1.1" 401 381
[Local IP address] - cdietzel [01/Jun/2015:15:47:20 +0200] "GET /test.txt HTTP/1.1" 200 -
mod_authnz_sspi是在httpd.conf中加载的最后一个模块。对于htdocs目录,我尝试了几种偏好设置,例如:
<Directory "c:/Apache24/htdocs">
Require all denied
Order allow,deny
Allow from all
AllowOverride All
Options None
AuthName "mycompany_proxy.loc"
AuthType SSPI
SSPIAuth On
SSPIAuthoritative On
SSPIOfferBasic On
SSPIOmitDomain On
Require valid-user
</Directory>
还有这个:
<Directory "c:/Apache24/htdocs">
Options Indexes FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
AuthName "mycompany_proxy.loc"
AuthType SSPI
SSPIAuth on
SSPIAuthoritative on
SSPIDomain mycompany_proxy.loc
SSPIOmitDomain on
SSPIOfferBasic on
SSPIBasicPreferred on
SSPIOfferSSPI on
SSPIMSIE3HACK on
require valid-user
</Directory>
此外,我添加了函数apache_request_headers(),其输出在两个服务器上的读数如下:
[Host] => server1
[Connection] => keep-alive
[Cache-Control] => max-age=0
[Authorization] => NTLM TlRMTVN... [long base64 code]
[Accept] => text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
[User-Agent] => Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.81 Safari/537.36
[Accept-Encoding] => gzip, deflate, sdch
[Accept-Language] => de,de-DE;q=0.8,en;q=0.6,en-US;q=0.4
在我看来,某种形式的NTLM身份验证会发生。如果我刷新网站,授权条目就会消失(可能是因为它已经完成)。
Apache服务在有效的域用户下运行(两个服务器上相同)。
我找到了这个thread,但我在旧服务器上没有使用认证脚本,所以我认为我在新服务器上也不需要。
两台服务器和我的本地机器都在我们公司的内部网络中。我需要在哪里定义我们的代理(通常不需要代理来访问本地服务器)或活动目录?
我担心这可能是一个非常特殊的问题,但也许你可以指点我正确的方向,或者知道我还能做什么,以找到HTTP代码401的原因。
任何帮助都将不胜感激。提前致谢!
编辑2015-06-02,上午09:40
我发现this module,但它似乎只适用于Apache 2.4 32位。
编辑于2015年06月02日,上午09:51
当我尝试通过Web浏览器从旧服务器访问新服务器上的test.txt时,系统要求我提供用户名和密码。当我使用Apache服务运行的同一用户登录后,我可以访问该文件。查看access.log,显示如下:
[IP address server1] - - [02/Jun/2015:09:49:23 +0200] "GET /test.txt HTTP/1.1" 401 381
[IP address server1] - apacheuser [02/Jun/2015:09:49:23 +0200] "GET /test.txt HTTP/1.1" 200 -