Apache 2.4上使用mod_authnz_sspi进行NTLM身份验证

3

我遇到了一个问题,无法从一个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 -
1个回答

2

Apache服务器的行为是正确的,函数get_headers()没有发送正确的身份验证信息,因此服务器响应了HTTP代码401。

它在旧服务器上工作的原因可以在httpd.conf中找到。在那里,我为每个子目录定义了SSPI选项,而不是整个htdocs目录。新服务器上所需的文件位于wshelper目录中,因此我在新服务器上将其放入httpd.conf中:

<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>

# List all subdirectories which need to be accessible without authentication
<Directory "c:/Apache24/htdocs/wshelper">
    Satisfy Any
    Allow from all
</Directory>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接