使用 mod_authnz_sspi 在 Apache 2.4 上进行 NTLM 身份验证
NTLM authentication on Apache 2.4 with mod_authnz_sspi
我很难从另一台 Web 服务器访问一台 Apache 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
要读取 Windows 远程用户(对于单点登录),我在旧服务器上使用模块 mod_auth_sspi。不幸的是,这个模块在 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
但是none第二个:
[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 access.log 上看了两台服务器。关于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,但我没有在旧服务器上使用身份验证脚本
所以我想我在新服务器上不需要一个。
服务器和我的本地机器都在我们公司int运行等。我是否需要在某处定义我们的代理(通常不需要代理来访问本地服务器)或活动目录?
我担心这可能是一个非常特殊的问题,但也许你可以指出正确的方向或者知道我还能做些什么来找到 HTTP 代码 401 的原因。
感谢任何帮助。提前致谢!
编辑 2015-06-02,09:40上午
我找到了 this module,但它似乎只适用于 Apache 2.4 32 位。
编辑 2015-06-02,09:51上午
当我尝试通过网络浏览器从旧服务器访问新服务器上的 test.txt 时,系统要求我提供用户名和密码。然后,当我输入 Apache 服务 运行s 所在的同一用户时,我可以访问该文件。查看 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 -
Apache 服务器的行为完全正确,函数 get_headers() 没有发送正确的身份验证,因此服务器以 HTTP 代码 401 响应。
它在旧服务器上运行的原因可以在 httpd.conf 中找到。在那里我为每个子目录而不是整个 htdocs 目录定义了 SSPI 选项。新服务器上所需的文件在目录 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>
我很难从另一台 Web 服务器访问一台 Apache 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
要读取 Windows 远程用户(对于单点登录),我在旧服务器上使用模块 mod_auth_sspi。不幸的是,这个模块在 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
但是none第二个:
[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 access.log 上看了两台服务器。关于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,但我没有在旧服务器上使用身份验证脚本 所以我想我在新服务器上不需要一个。
服务器和我的本地机器都在我们公司int运行等。我是否需要在某处定义我们的代理(通常不需要代理来访问本地服务器)或活动目录?
我担心这可能是一个非常特殊的问题,但也许你可以指出正确的方向或者知道我还能做些什么来找到 HTTP 代码 401 的原因。
感谢任何帮助。提前致谢!
编辑 2015-06-02,09:40上午
我找到了 this module,但它似乎只适用于 Apache 2.4 32 位。
编辑 2015-06-02,09:51上午
当我尝试通过网络浏览器从旧服务器访问新服务器上的 test.txt 时,系统要求我提供用户名和密码。然后,当我输入 Apache 服务 运行s 所在的同一用户时,我可以访问该文件。查看 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 -
Apache 服务器的行为完全正确,函数 get_headers() 没有发送正确的身份验证,因此服务器以 HTTP 代码 401 响应。
它在旧服务器上运行的原因可以在 httpd.conf 中找到。在那里我为每个子目录而不是整个 htdocs 目录定义了 SSPI 选项。新服务器上所需的文件在目录 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>