Being an ASP.NET enthusiast, I've soon came across this issue and had to deal with it. This happened very shortly after the release of the .NET Framework and, at the time, seemed like a major headache for developers. Well, actually it still does seem like a major headache but I've came to accept it as a "normal" thing :P.
Because I regularly post in ASP.NET newsgroups, I realized that every so often someone sends in an email stating that they lose the user credentials connecting to a SQL Server or accessing a file in a network share from within their ASP.NET application. And this is called the "double hop" issue.
The typical scenario follows: you're building an intranet application and using Integrated Security. You're also setting "
Let's look at it step-by-step:
Integrated Security - What this means is that IIS doesn't explicitly ask the users for credentials. Instead the credentials used to log on to their workstation are used to authenticate against IIS. And here is the first hop: the user's credentials are passed from the workstation to the web server in a secure way.
Impersonate - This is a very cool feature. You can access resources in the context of the user currently using your application. This simplifies resource access control but it's only suited for resources hosted on the web server itself.
Double hop - For security reasons, NTLM credentials cannot hop between servers at will. So, accessing a SQL Server instance running on another machine other than the web server will result in a logon failure error. It would be the second hop: the web server would have to pass the user's credentials to the SQL Server machine. For security reasons this is not allowed. Imagine that you access a site through your browser, the site collects your credentials without your knowledge (Integrated security) and then starts doing whatever the developer desires with your identification. Clearly, this is not a good scenario.
Ok, and now that we identified the problem, how do we workaround it?
There are a lot of possible ways to workaround this issue, but I actually couldn't find one that completely satisfies me. Oh well, security is a process and one that should be between our major concerns when writing an application. Here you'll find possible solutions to this problem. Note that you should carefully analyze each of these options and choose whichever fits your security and design requirements.
Basic Authentication (consider HTTPS in this case)
Kerberos and Trust computer for delegation privilege in AD
Specify explicit credentials
1. When using basic authentication, users are asked to insert their credentials when accessing the site. In this case, they are authenticating against the web server and the machine can now use the credentials provided to access SQL Server. You can think of this as the user giving permission to the machine to use his/her identification. This doesn't change anything in your code, it's only an IIS setting. Careful though, because the credentials are sent in clear text between the client machine and the web browser, so you should think of getting a SSL certificate and using https to secure communications.
2. It's a lot more complex to handle authentication this way but Kerberos would allow you to hop the user's identification between servers. You'll also have to give the web server the "Trust machine for delegation" privilege in AD. You'll need to ask a domain admin to do this and normally they don't really like to accept this type of request. It's not a question of bad attitude but concerns for security. If your domain admin refuses your request feel happy that he knows what he's doing ;) Take a look here:
3. This is the solution more commonly used. Basically, you do not connect to SQL Server using a trusted connection, you specify a username and a password in the connection string or you specify this values in the impersonation settings and still use a trusted connection. The connection is still secure, and the only problem you have is where to store the these values so that it'll be safe. Of course, you could hard-code it, but that would leave you with no easy way to change it afterwards. One way is to store it in web.config and that would give you an easy way to change the parameters in runtime. Although the web.config file is not served by IIS (meaning that a client cannot view it in the browser) it's not the safest way to store this valuable piece of information. The recommendation is storing this values in the registry. This article although not specifically written for this issue, does show a way to accomplish this:
That's about it. This is not meant to be a complete article on ASP.NET security. It justs aims to give a few pointers on working around this common problem.
Hope it helps.