sqlsrv_connect:Windows身份验证


sqlsrv_connect: Windows authentication

我有以下PHP代码在IIS下运行:

$serverName = "someServer'someServer";
$connectionInfo = array( "Database"=>"SOME_DB");
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if( $conn ) {
     echo "Connection established.<br />";
}else{
     echo "Connection could not be established.<br />";
     die( print_r( sqlsrv_errors(), true));
}

当我尝试访问该页面时,我得到错误:

[Microsoft][SQL Server Native Client 10.0][SQL Server]用户"NT AUTHORITY''ANOYMOUS LOGON"登录失败。

这是令人困惑的,因为这里的文档说"将使用Windows身份验证尝试连接"。

这个流程是:

  1. workstation1上使用x Windows帐户的用户访问server1上托管的此网站
  2. server1执行上面的PHP代码,并尝试使用y Windows帐户从server2检索数据(y在IIS设置中的应用程序池->标识下定义)
  3. Windows帐户y有权访问数据库

IIS池在Windows域用户"domainadm"下运行,该用户可以访问SOME_DB数据库及其所在的服务器。

为什么它试图匿名进行身份验证,我如何解决这个问题,使它在IIS池运行的用户下运行?

在php.ini中:

fastcgi.impersonate = 1;

检查IIS中的"身份验证"部分,我只有"匿名身份验证"或"ASP.NET模拟"选项。没有Windows身份验证?

"匿名"当前已启用,这会出现上面的错误。如果我切换到ASP.NET,我在访问页面时会出现以下错误:

500-内部服务器错误。您正在查找的资源出现问题,无法显示。检测到一个ASP.NET设置不适用于集成托管管道模式。

我更新的web.config:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <httpErrors errorMode="Detailed" />
        <validation validateIntegratedModeConfiguration="false"/>
    </system.webServer>
    <system.web>
        <identity impersonate="true" />
        <authentication mode="Windows" />
        <customErrors mode="Off" />
        <compilation debug="true" />
    </system.web>
</configuration>

问题是,尽管您以AppPool标识运行,IIS仍在匿名向SQL发送连接。要解决此问题,您必须启用从web服务器(server1)到SQL服务器(server2)的匿名连接。

在SQL server上,为<YourDomain>'server1$创建登录名,并在用户映射选项卡下为Some_DB分配适当的权限。例如,授予此帐户db_datareaderdb_datawriter权限,您应该能够连接并成功完成CRUD操作。为了进行测试,您可能只想暂时授予此登录db_ownerSome_DB的权限,以确保SQL权限没有问题。

关于PHP fastcgi.impersonate设置,我相信您可以将其设置为0/false,因为在这种情况下这无关紧要。

在IIS中的身份验证部分,启用Windows身份验证和ASP.NET模拟。

这些将是IIS中将启用的唯一身份验证类型。

在web.config文件中,您将需要以下内容(如果Windows没有出现,这应该可以解决问题):

<system.web>
    <identity impersonate="true" />
    <authentication mode="Windows" />

identity.impersonate的原因是您需要它来模拟通过windows登录的用户凭据。

一旦用户通过身份验证,就可以使用匿名身份验证来访问数据库。

例如,为了证明上述方法的有效性,请在数据库中转到Security-Logins on SQL Server并添加登录名。

添加:NT授权''匿名登录

并为其分配dboOwner角色以确保其正常工作。

执行以上操作将证明IIS的设置方式没有其他冲突,例如不正确的web.config条目。

请确保应用程序池在集成模式下运行,并且在数据库连接字符串中具有integrated Security=true。

如果需要,您可以分配一个不同的帐户,例如您的"domainadm"帐户,一个运行应用程序池的服务帐户。但是,如果用户不在同一个域上,可能会出现问题,以及由于服务器/帐户的配置方式而可能出现的其他问题,这些问题可能会导致此操作失败。但是,尝试以上步骤将使其运行,以便在必要时诊断这些问题。

此处关于Windows身份验证或模拟的建议不适用于您的情况。Windows身份验证将使客户端计算机"x"使用前端"server1"进行身份验证,模拟将用于将凭据"x"转发到SQL"server2"。这将要求每个使用该网站的用户都有SQL访问权限。相反,您希望匿名访问您的网站,并让网站管理自己对SQL的访问。

问题摘要:匿名身份验证的默认用户是IUSR,无论您的应用程序池设置如何。当它尝试连接到网络资源时,它会验证为"NT AUTHORITY''Anonymous LOGIN"。显然,当试图锁定访问时,这不是很有用。

你可以在这里看到这一点:http://www.iis.net/learn/get-started/planning-for-security/understanding-built-in-user-and-group-accounts-in-iis

注意:IUSR帐户在网络上匿名操作的方式与LOCALSERVICE类似。NETWORKSERVICE和LOCALSYSTEM帐户可以充当计算机标识,但IUSR帐户不能,因为它需要提升用户权限。如果您需要匿名帐户才能在网络上拥有权限,则必须创建一个新的用户帐户,并手动设置用户名和密码,就像过去进行匿名身份验证一样。

更多信息可在此处找到:http://www.iis.net/learn/get-started/whats-new-in-iis-7/changes-in-security-between-iis-60-and-iis-7-and-above

解决方案:转到"身份验证"部分,选择"匿名身份验证",然后单击"编辑…"。。。,并从"特定用户:IUSR"更改为"应用程序池标识"。这应该会迫使网站使用您为应用程序池设置的帐户。

完成后,如果您使用默认的应用程序池设置"应用程序池标识",您的应用程序将尝试使用SQL作为DOMAIN''MACHINENAME进行身份验证。