16

我正在尝试在 Intranet ASP.Net Web 应用程序中使用模拟和委派,以便将经过身份验证的用户凭据传递到 SQL Server。

Web 服务器和 SQL 服务器是两台独立的机器,但在同一个域中,因此需要委托。

我做了以下事情:

  • 设置<authentication mode="Windows"/><identity impersonate="true"/>在我的网络应用程序的 web.config 中。
  • 启用了从 Web 服务器到 Active Directory 中 SQL Server 上的 MSSQLSvc 服务的约束委派。
  • 通过 IIS 在网站中仅启用 Windows 身份验证。

显然这应该都可以工作,但它没有(SQL Server 拒绝访问匿名用户 - “用户'NT AUTHORITY\ANONYMOUS LOGON' 登录失败”)。

在 IIS7 中,应用程序池设置为使用集成管道模式并使用 NetworkService 标识运行。该网站仅启用了 Windows 身份验证,扩展保护已关闭,内核模式身份验证已启用,并且 NTLM 是提供者。

我读过的所有网页似乎都表明我的设置应该可以工作。我错过了什么?

4

2 回答 2

16

我发现了答案:

IIS7 中的 Windows 身份验证提供程序必须设置为Negotiate:Kerberos,而不是 NTLM。这意味着必须禁用内核模式身份验证设置。这似乎很好。我认为在使用自定义身份(即一个特定身份)时需要内核模式身份验证是正确的。委托可以使用任意数量的身份。所以一切都很好。

我也写了一篇关于这个的博客文章,其中更详细一点。

于 2010-01-20T14:13:45.507 回答
-2

不 - 说您需要 Kerberos(一个 SPN)来信任服务器进行委派是不准确的,这是唯一的方法。是的,这是一种方法(您确实需要通过 Kerberos 实现它),但它不是唯一的方法,甚至在技术上也是最安全或最简单的方法。您是否真的需要进行额外的配置并为每个 Web 用户在 SQL 中创建一个登录到您的数据库的登录名?如果其中任何一个帐户遭到入侵怎么办?更多帐户,更多漏洞。

不,而是创建一个域服务帐户,然后让该帐户访问 SQL。如果您的安全人员锁定了某些东西,请授予该用户以下权限:作为服务登录、作为批处理作业登录和允许本地登录。或者,如果这只是为了开发和测试理论,或者您不关心或找不到设置或稍后仍然出现错误,这可能不会得到大量关注,但给它本地管理员(有时你必须做你必须做的事情——一些安全专家将事情锁定得比我想写的更严格——以后总是可以解决安全问题以将其锁定)。然后将该帐户设置为应用程序池上的自定义帐户,并在 SQL 中为该帐户提供登录名。只在那个数据库上给它 dbo。

在 IIS 中的网站上,将身份验证类型设置为 Windows。我在其他博客中看到他们说“基本”,因此 Kerberos 可以工作,但 NTLM 使用 Windows 身份验证。在 IIS 7 中,您可能还希望启用 ASP .NET 模拟。就个人而言,我只在 IIS 6 上尝试过,但原理是一样的。

在 web.config 中,将其添加到下面<configuration>,这是一个“对等体” <system.web>

<connectionStrings>
  <add 
     name="NorthwindConnectionString" 
     connectionString="Data Source=serverName;Initial 
     Catalog=Northwind;Integrated Security=SSPI;User 
     ID=userName;Password=password"
     providerName="System.Data.SqlClient"
  />
</connectionStrings>

并在<system.web>

<authentication mode="Windows"/> 
<identity impersonate="true"
      userName="domain\user" 
      password="password" />

然后像这样将字符串读入您的应用程序:

using System.Configuration;

string connString = String.Empty;
if (ConfigurationManager.ConnectionStrings.ConnectionStrings.Count > 0)
{
    connString = ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString; 
    if (connString != null) // do DB connection stuff here
        Console.WriteLine("Northwind connection string = \"{0}\"",
        connString.ConnectionString);
    else
        Console.WriteLine("No Northwind connection string");
}

请参阅http://msdn.microsoft.com/en-us/library/ms178411.aspx

如果在 web.config 中为 impersonate 标记和 SQL 连接填写该帐户后它不会与服务帐户连接,则可以使用 WindowsImpersonationContext ( http://msdn.microsoft.com/en-us ) 使用模拟方法/library/system.security.principal.windowsimpersonationcontext.aspx)。具体来说,您需要 wic.Impersonate() 和 wic.Undo() 在获得它们的令牌后。您可以从 web.config 中以 AppKeys 的形式读取服务帐户域、名称和密码。

简而言之,有一些方法可以解决这些问题。您甚至可以在 web.config 中加密密码 - 无论是在 ConnectionString 中,如果您想将其存储在 AppKey 中而不是直接在“模拟”标签中,如果您不想在其中使用纯文本密码(其中我建议反对),因此如果您需要使用模拟方法(就像我一样),您可以使用它来创建登录令牌。

于 2013-08-27T04:14:19.623 回答