I'm trying to use Impersonation and Delegation in an intranet ASP.Net web-app in order to pass authenticated users' credentials onto a SQL Server.
我试图在内部网ASP中使用模拟和委托。Net web应用程序,以便将经过身份验证的用户的凭据传递到SQL服务器上。
The web server and SQL server are two separate machines, but in the same domain, so Delegation is required.
web服务器和SQL服务器是两个独立的机器,但是在同一个域中,因此需要委托。
I've done the following:
我做了以下几点:
- set
<authentication mode="Windows"/>
and<identity impersonate="true"/>
in my web-app's web.config. -
在我的web应用的web.config中设置
, 。 - enabled Constrained Delegation from the web server to the MSSQLSvc service on the SQL Server, in Active Directory.
- 在活动目录中,使受约束的从web服务器委托到SQL服务器上的MSSQLSvc服务。
- enabled only Windows Authentication in the website, through IIS.
- 仅通过IIS在网站中启用Windows身份验证。
Apparently this should all work, but it doesn't (the SQL Server is denying access to the anonymous user - "Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'").
显然,这一切都应该工作,但它没有(SQL Server拒绝访问匿名用户——“登录失败,用户的NT权限\匿名登录”)。
In IIS7, the Application Pool is set to use Integrated Pipleline Mode and is running with the NetworkService Identity. The website only has Windows Authentication enabled, Extended Protection is Off, Kernel-mode authentication is enabled, and NTLM is the provider.
在IIS7中,应用程序池设置为使用集成的Pipleline模式,并使用NetworkService标识运行。该网站只启用Windows身份验证,关闭扩展保护,启用内核模式身份验证,NTLM是提供者。
All the web pages I've read seem to indicate that my setup should work. What am I missing?
我读过的所有网页似乎都表明我的设置应该有效。我缺少什么?
2 个解决方案
#1
16
I've discovered the answer:
我发现答案是:
The Windows Authentication provider in IIS7 must be set to Negotiate:Kerberos, not NTLM. This means that the Kernel-mode authentication setting must be disabled. This seems to be fine. I think I'm right in saying that Kernel-mode authentication is required when using a custom identity, i.e. one specific identity. Delegation can use an arbitrary number of identities. So all is well.
IIS7中的Windows身份验证提供者必须设置为:Kerberos,而不是NTLM。这意味着必须禁用内核模式的身份验证设置。这似乎没问题。我认为我说得对,使用自定义标识(即一个特定标识)时需要使用内核模式身份验证。委托可以使用任意数量的标识。所以一切都好。
I've written a blog post about this too, which goes into a bit more detail.
我也写了一篇关于这方面的博客文章,其中有更多的细节。
#2
-1
No - it is not accurate to say you need Kerberos, an SPN, to trust the server for delegation, and that this is the ONLY way to do it. Yes, this is one way to do it (and you do need all of it to make it happen via Kerberos), but it is not the ONLY way, or even technically the most secure way or easiest way. Do you really want to have to do extra configurations and create a login for every web user to your DB in SQL? What if any one of those accounts is compromised? More accounts, more vulnerabilities.
不——说您需要Kerberos(一个SPN)来信任服务器以进行授权是不准确的,而这是惟一的方法。是的,这是一种方法(您确实需要所有这些方法才能通过Kerberos实现),但这不是唯一的方法,甚至从技术上讲,也不是最安全或最简单的方法。您真的想要做额外的配置并为每个web用户创建一个SQL中的数据库登录吗?如果其中任何一个账户被泄露了怎么办?账户,更多的漏洞。
No, create a Domain service account, instead, and let that access SQL. If your security guys lock down things, give that user these rights: Logon as a service, Logon as a batch job, and Allow logon locally. Or, if this is just to develop and test the theory or you don't care or can't find the settings or are still getting errors later on, and this might not get a large following, but give it local Admin (sometimes you gotta do what you gotta do - some security pros lock down things tighter than I would care to write about - can always troubleshoot security later to lock it back down). Then set that account as the custom account on the app pool and give that account a login in SQL. Give it dbo on just THAT ONE database.
不,创建一个域服务帐户,让它访问SQL。如果你的安全人员锁定了一些东西,给用户这些权利:作为服务登录,作为批处理作业登录,并允许本地登录。或者,如果这仅仅是开发和测试的理论或者你不在乎或找不到设置仍得到错误以后,这之后可能不会获得很大,但给当地管理(有时你必须做你必须做的事——安全优点锁定一些比我更会写关心——总是可以解决安全后锁定下来)。然后将该帐户设置为应用程序池中的自定义帐户,并使用SQL登录该帐户。给它一个数据库上的dbo。
On the website in IIS, set the authentication type as Windows. I've seen them say "Basic" in other blogs so Kerberos will work, but NTLM uses Windows authentication. In IIS 7, you may also want to enable ASP .NET impersonation. Personally, I've only tried this on IIS 6, but the principal is the same.
在IIS的网站上,将身份验证类型设置为Windows。我看到他们在其他博客中说“基本的”,所以Kerberos可以工作,但是NTLM使用Windows身份验证。在IIS 7中,您可能还希望启用asp.net模拟。就我个人而言,我只在iis6上尝试过,但是原理是一样的。
In the web.config, add this under <configuration>
, which is a "peer" to <system.web>
:
在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>
And in <system.web>
:
在 <包含> :
<authentication mode="Windows"/>
<identity impersonate="true"
userName="domain\user"
password="password" />
Then read the string into your app like this:
然后像这样将字符串读入应用程序:
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");
}
See http://msdn.microsoft.com/en-us/library/ms178411.aspx.
见http://msdn.microsoft.com/en-us/library/ms178411.aspx。
If it will not connect with the service account after filling in that account in the web.config for the impersonate tag and the SQL connection, you can then use impersonation methods using WindowsImpersonationContext (http://msdn.microsoft.com/en-us/library/system.security.principal.windowsimpersonationcontext.aspx). Specifically, you want wic.Impersonate() and wic.Undo() after getting their token. You can read in the service account domain, name, and password from the web.config, in the form of AppKeys.
如果在web中填写该帐户后,它将不连接到服务帐户。配置模拟标记和SQL连接,然后可以使用WindowsImpersonationContext (http://msdn.microsoft.com/en-us/library/system.security.principal.windowsimpersonationcontext.aspx)使用模拟方法。具体地说,您需要在获取它们的令牌之后使用wic. ate()和wic.Undo()。您可以在web上读取服务帐户域、名称和密码。配置,以AppKeys的形式。
In short, there are ways around the issues. You can even encrypt the password in the web.config - both in the ConnectionString, and if you want to store it in an AppKey instead of directly in the "impersonate" tag, if you don't want plain text passwords in there (which I'd recommend against), and so you can have it for the creation of a Logon token, if you need to use the Impersonation methods (as I did).
简而言之,有解决问题的方法。你甚至可以在网上加密密码。配置——无论是ConnectionString,如果你想将它存储在一个AppKey而不是直接在“模仿”标签,如果你不想纯文本密码(我不推荐),所以你可以创建一个登录令牌的,如果您需要使用模拟方法(像我一样)。
#1
16
I've discovered the answer:
我发现答案是:
The Windows Authentication provider in IIS7 must be set to Negotiate:Kerberos, not NTLM. This means that the Kernel-mode authentication setting must be disabled. This seems to be fine. I think I'm right in saying that Kernel-mode authentication is required when using a custom identity, i.e. one specific identity. Delegation can use an arbitrary number of identities. So all is well.
IIS7中的Windows身份验证提供者必须设置为:Kerberos,而不是NTLM。这意味着必须禁用内核模式的身份验证设置。这似乎没问题。我认为我说得对,使用自定义标识(即一个特定标识)时需要使用内核模式身份验证。委托可以使用任意数量的标识。所以一切都好。
I've written a blog post about this too, which goes into a bit more detail.
我也写了一篇关于这方面的博客文章,其中有更多的细节。
#2
-1
No - it is not accurate to say you need Kerberos, an SPN, to trust the server for delegation, and that this is the ONLY way to do it. Yes, this is one way to do it (and you do need all of it to make it happen via Kerberos), but it is not the ONLY way, or even technically the most secure way or easiest way. Do you really want to have to do extra configurations and create a login for every web user to your DB in SQL? What if any one of those accounts is compromised? More accounts, more vulnerabilities.
不——说您需要Kerberos(一个SPN)来信任服务器以进行授权是不准确的,而这是惟一的方法。是的,这是一种方法(您确实需要所有这些方法才能通过Kerberos实现),但这不是唯一的方法,甚至从技术上讲,也不是最安全或最简单的方法。您真的想要做额外的配置并为每个web用户创建一个SQL中的数据库登录吗?如果其中任何一个账户被泄露了怎么办?账户,更多的漏洞。
No, create a Domain service account, instead, and let that access SQL. If your security guys lock down things, give that user these rights: Logon as a service, Logon as a batch job, and Allow logon locally. Or, if this is just to develop and test the theory or you don't care or can't find the settings or are still getting errors later on, and this might not get a large following, but give it local Admin (sometimes you gotta do what you gotta do - some security pros lock down things tighter than I would care to write about - can always troubleshoot security later to lock it back down). Then set that account as the custom account on the app pool and give that account a login in SQL. Give it dbo on just THAT ONE database.
不,创建一个域服务帐户,让它访问SQL。如果你的安全人员锁定了一些东西,给用户这些权利:作为服务登录,作为批处理作业登录,并允许本地登录。或者,如果这仅仅是开发和测试的理论或者你不在乎或找不到设置仍得到错误以后,这之后可能不会获得很大,但给当地管理(有时你必须做你必须做的事——安全优点锁定一些比我更会写关心——总是可以解决安全后锁定下来)。然后将该帐户设置为应用程序池中的自定义帐户,并使用SQL登录该帐户。给它一个数据库上的dbo。
On the website in IIS, set the authentication type as Windows. I've seen them say "Basic" in other blogs so Kerberos will work, but NTLM uses Windows authentication. In IIS 7, you may also want to enable ASP .NET impersonation. Personally, I've only tried this on IIS 6, but the principal is the same.
在IIS的网站上,将身份验证类型设置为Windows。我看到他们在其他博客中说“基本的”,所以Kerberos可以工作,但是NTLM使用Windows身份验证。在IIS 7中,您可能还希望启用asp.net模拟。就我个人而言,我只在iis6上尝试过,但是原理是一样的。
In the web.config, add this under <configuration>
, which is a "peer" to <system.web>
:
在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>
And in <system.web>
:
在 <包含> :
<authentication mode="Windows"/>
<identity impersonate="true"
userName="domain\user"
password="password" />
Then read the string into your app like this:
然后像这样将字符串读入应用程序:
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");
}
See http://msdn.microsoft.com/en-us/library/ms178411.aspx.
见http://msdn.microsoft.com/en-us/library/ms178411.aspx。
If it will not connect with the service account after filling in that account in the web.config for the impersonate tag and the SQL connection, you can then use impersonation methods using WindowsImpersonationContext (http://msdn.microsoft.com/en-us/library/system.security.principal.windowsimpersonationcontext.aspx). Specifically, you want wic.Impersonate() and wic.Undo() after getting their token. You can read in the service account domain, name, and password from the web.config, in the form of AppKeys.
如果在web中填写该帐户后,它将不连接到服务帐户。配置模拟标记和SQL连接,然后可以使用WindowsImpersonationContext (http://msdn.microsoft.com/en-us/library/system.security.principal.windowsimpersonationcontext.aspx)使用模拟方法。具体地说,您需要在获取它们的令牌之后使用wic. ate()和wic.Undo()。您可以在web上读取服务帐户域、名称和密码。配置,以AppKeys的形式。
In short, there are ways around the issues. You can even encrypt the password in the web.config - both in the ConnectionString, and if you want to store it in an AppKey instead of directly in the "impersonate" tag, if you don't want plain text passwords in there (which I'd recommend against), and so you can have it for the creation of a Logon token, if you need to use the Impersonation methods (as I did).
简而言之,有解决问题的方法。你甚至可以在网上加密密码。配置——无论是ConnectionString,如果你想将它存储在一个AppKey而不是直接在“模仿”标签,如果你不想纯文本密码(我不推荐),所以你可以创建一个登录令牌的,如果您需要使用模拟方法(像我一样)。