代码之家  ›  专栏  ›  技术社区  ›  Graham Clark

尝试使用模拟和委派连接到SQL Server的ASP.NET Web应用程序

  •  15
  • Graham Clark  · 技术社区  · 14 年前

    我试图在内部网ASP.NET Web应用程序中使用模拟和委派,以便将经过身份验证的用户的凭据传递到SQL服务器。

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

    我做了以下工作:

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

    显然,这一切都可以,但事实并非如此(SQL Server拒绝访问匿名用户-“用户'NT AUTHORY\ANYONYONY LOGON'登录失败”)。

    在iis7中,应用程序池被设置为使用集成的pipleline模式,并使用networkservice标识运行。网站仅启用了Windows身份验证,扩展保护已关闭,内核模式身份验证已启用,NTLM是提供程序。

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

    2 回复  |  直到 11 年前
        1
  •  16
  •   Graham Clark    14 年前

    我发现了答案:

    iis7中的Windows身份验证提供程序必须设置为 协商:kerberos ,而不是NTLM。这意味着必须禁用内核模式身份验证设置。这看起来不错。我认为我说的对,在使用自定义标识(即一个特定的标识)时需要内核模式身份验证。委派可以使用任意数量的标识。所以一切都很好。

    我写了一篇 blog post 关于这一点,也会有更多的细节。

        2
  •  -1
  •   vapcguy    11 年前

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

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

    在IIS的网站上,将身份验证类型设置为Windows。我在其他博客中看到他们说“基本”,这样Kerberos就可以工作,但NTLM使用Windows身份验证。在IIS 7中,您可能还需要启用ASP.NET模拟。就我个人而言,我只在IIS6上尝试过这个,但是主体是相同的。

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

    而在 <系统.WEB & GT; :

    <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中为模拟标记和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中而不是直接存储在“impersonate”标记中,如果您不希望在其中使用纯文本密码(我建议不要这样做),那么您可以在需要使用impersonation方法时将其用于创建登录令牌。ODS(像我一样)。