Impersonation and delegation (with SQL Server) in ASP.NET - asp.net

I've written a simple ASP.NET application that works as a frontend for a simple MSSQL database. The application is accessible over the Internet.
There are two physical servers involved: a WS2008R2 Active Directory domain controller which is also running MSQL Server 2008 R2, and another server, the webserver (WS2008R2/IIS7.5) where my application resides.
The Application Pool for my application "FooPool" has its own AD User identity it runs under "FooUser". FooUser does not have any permission to access the SQL Server database, instead only my own personal user account "MyUser" has that permission.
The idea is that attempts to access this web application first perform Windows Authentication with IIS, my web application then uses Impersonation to access the SQL Server database.
However my application does not work.
I tested the application without it touching SQL Server, just to test impersonation, so I did Response.Write( WindowsIdentity.GetCurrent(false).Name ); which correctly shows the application impersonating MyUser and not acting as FooUser. This works from all modern browsers and across the Internet.
But as soon as it touches MSSQL Server I get the error "Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'." but that should not be happening because no user tokens are for Anonymous Logon.
I've done my homework and read all about Delegation and Impersonation in ASP.NET and I have set up delegation: The FooUser account has a Service Principal Name set-up (I set the SPN to an arbitrary string, is that doing it right?) and is marked for delegation in ADUC.
Finally, my connection string has SSPI enabled, Connection pooling disabled, and the network library set to "dbmssocn".
What else am I forgetting?

Finishing the Configuration for Delegation to Work you must enable constrained delegation:
Open Active Directory Users and Computers
Find the user account that the IIS Web site is using for the web application pool and double-click it
Select the option: Trust this user for delegation to specified
services only.
Make sure that the user is constrained to the
SPN associated with the MSSQLSvc service
Restart IIS
http://blogs.technet.com/b/askds/archive/2008/11/25/fun-with-the-kerberos-delegation-web-site.aspx

Related

Implementing ASP.Net impersonation/delegation to connect to remote SQL Server from ASP.Net server not working

I'm trying to set up impersonation/delegation for a web application using ASP.NET 4.5/SQL Server 2016. The goal is to use the Windows authentication on the web application and the SQL Server.
I reproduced on Azure a setup similar to the one which will be used for production, but I can't seem to find what is making the impersonation not working.
Azure VM #1 [machine name: test-iis-server]: Windows Server 2012 running IIS 8.5 and acting as Active Directory Domain Controller
Azure VM #2 [machine name: test-sql-server]: Windows Server 2016 running SQL Server 2016
Azure VM #3 [machine name: test-client]: Windows 10 machine for simulating a user connecting to the website
I created an Active Directory domain named TEST. It is possible to connect to the 3 machines with users created in Active Directory.
IIS Web server configuration:
In the web.config file:
Authentication mode = Windows
Identity impersonate = True
validation validateIntegratedModeConfiguration = False
Integrated security = SSPI
In IIS Manager:
Windows authentication = Enabled (Kernel-mode authentication = Disabled, Providers = Negotiate:Kerberos)
ASP.NET Impersonation = Enabled
Application pool = Integrated Managed Pipeline (Identity = Custom Identity: test\my-svc-account)
In Active Directory Users & Computers
For each computers (web server, sql server and user computer), I went into Properties and checked in the Delegation tab Trust this
computer for delegation to any service (Kerberos only).
SQL Server Configuration
I did not setup anything here. I assumed that ASP.NET will use the credentials of the user logged in the web application to access the
SQL Server database.
Edit: SQL Server service account: test\my-svc-account
Results:
If I don't use impersonation in the web application and use a defined user/pwd login created in SQL Server, my application works normally and I can get the Windows user credential if I want.
Using impersonation, I get a SQL Server connection error when I open the web application page: Login failed for user 'TEST\test-iis-server$'.
Expected behavior:
The web application will log into SQL Server using the credentials used to log into the "test-client" machine.
I've read a lot on how to implement the impersonation/delegation for my solution, but can't seem to find what's wrong. Anyone has any idea where the proble might come from and how I can resolve it?
Edit #1:
From what I've read, it seems like I need to setup SPNs. I'm confused about how to set them up correctly for my double-hop scenario.
I have created a user account in Active Directory to act as a service account. I've set this account to be trusted for delegation.
I use this account as the identity for my application pool in IIS and as the service account of the SQL Server instance.
Yes, you do need to configure SPNs for both the ASP.NET app pool identity, and the SQL Server service account.
It's relatively straightforward, but you need to make sure you get the right values.
In AD Users and Computers find the 'my-svc-account' account and open the properties. Navigate to the attribute editor tab (if you don't see it, enable advanced features through the ADUC 'View' menu). Find the servicePrincipalName attribute and edit it. Add the following:
http/servicename.foo.com
http/servername <== optional
Where service.foo.com matches your DNS name. If this is a CNAME, you need to also include the underlying A record name as well. So if servicename.foo.com maps to whatever.cloudapp.net, you need to add an SPN for whatever.cloudapp.net. This is for IE, because IE is ...dumb... and trying to be smart (it resolves the DNS down to lowest named record and requests an SPN for that).
Then do the same for the SQL Server service account.
MSSQLSvc/sqlserver.foo.com
MSSQLSvc/sqlserver <== optional
This needs to be the FQDN of the SQL Server host.
Lastly, you need to enable Constrained Delegation between the App Pool identity and the SQL Server service account. This is the 3rd radio button in the delegation control. Add the SQL Server SPN as a delegated target.
Restart IIS and SQL. Try browsing to the app. You should now see it connect to SQL as your named user.

Can't get rid off "Login failed for user IIS APPPOOL\NETWORKSERVICE"

I'm trying to access a sql server database from an ASP NET app configured to work with IIS.
I have several questions now,
1) Authentication in IIS: I need to know if my authentication settings for the site are ok:
I tried with Windows Authentication set to Disabled, but the problem continues.
2) Are the settings for the user NT AUTHORITY\Sericio de red well configured? ("Servicio de red" means Network Service)
3) When I added the login for network service, I only found "Servicio de red", I guess it's the equivalent for NetworkService, I'm I right?, My windows 7 ultimate is an spanish version, I just changed the windows interface by using a windows upgrade to make it appear in english. Is there a problem with it?, I guess it's right because the access to the database is being done through the IIS APPPOOL\Servicio de red user.
My DefaultAppPool identity is set to to AppPoolIdentity
If you want to see what I have tried, see this thread.
The whole project, along with a backup of the database I'm using can be found here, called MyServiceSolutionInIIS
What I'm trying is to build a WCF Data Service that offers information that comes from an entity data model generated from a sql server database. This service will be used by a WPF App as a client.
I'd like to avoid creating a user for it, I think it can be done with the App Pool
Okay so the way this works is, whatever application pool your endpoint is running under passes its credentials to the SQL Server. So, you have two options:
Run the default application pool under NetworkService, or;
Use SQL Authentication when connecting with your web service to the SQL Server.
Honestly, the latter is the most common, but in your situation you may be just fine by changing the default application pool to run under NetworkService.
This has nothing to do with the authentication you've chosen (well, mostly nothing.. you can control which credentials anonymous users run under). Every website runs in an app pool, and this app pool has an AppPoolIdentity.
I'm a little confused as to why it would be claiming it's IIS AppPool\NetworkService, since NetworkService should be NT AUTHORITY\NetworkService, or IIS AppPool\MyAspService or IIS AppPool\DefaultAppPool.
There is a lot more information on App Pool Identities here:
http://www.iis.net/learn/manage/configuring-security/application-pool-identities
Note: There is a bug in IIS 7.5 (the version of IIS that comes with Windows 7 and Windows Server 2008 R2) that sometimes causes authentication problems with AppPoolIdentities if the users password changes (say, if you have mandatory password change policies). There is a hotfix here:
http://support.microsoft.com/kb/2545850/en-us
More info here:
IIS application using application pool identity loses primary token?
There so many scenarios in which this issue occurs.
First thing you need to clear if you are using windows authentication and you are not mentioning any username password in your connection string then:
What happens when you run your code through localhost: when you run your wcf test client from localhost, it will be able to communicate to database as local debug mode application is calling database by your account's service. So it has access to database because devenv.exe is running under your user account.
But when you deploy your web service in IIS. Now understand this service runs under IIS not under your account. So you need to assign access rights to IIS service to access the sql server for windows authentication. Here your web service would not be able to communicate to the SQL server because of access rights issue and Login Failed for user_______ (here your user will come)
So if you are using windows authentication to connect your database, you just have to change the IIS Application pool settings. You need to change IIS Application pool's identity to:
local System (for single windows user).
Network Service (for intranet users or domain users)
Below are the Steps for windows authentication WCF:
•Open IIS (windows+R (run) then type inetmgr, then click ok)
•double click your PC name under Connections
•Click Application Pools
•Select your app pool (DefaultAppPool)
•Then under actions on the right click Advanced Settings:
•Go to Process Model section and
•click on Identity.
•Now select LocalSystem (for single windows authentication user).
or select Network Service (for Intranet users)
Now open your sql server management studio: open run-> then type ssms then press ok in ssms, login using your windows authentication account. open security tab expand logins tab then you will be able to view your account.
Now open properties of your account go to userMapping then select the database you want to connect then check the role membership services you want to use for the selected database click ok. (For network services i.e. intranet users you need to configure above settings for NT AUTHORITY\SYSTEM user too)
add Trusted_Connection=True; property in your connection string. Save it & deploy the web service. Restart app pool.
you will be able to connect the database now.

Connect to SQL Server with EF using windows credentials of final user

I have an application developed in ASP.NET MVC using Entity Framework / Sql Server 2008
Actually, connections to the database are made with the "sa" account.
Is it possible to use, instead of "sa" the windows final user credentials ?
This would be helpful to control more efficiently the security limitations of each user.
I use, in my application windows authentication.
Thank's !
It is possible but whole your system must run inside windows domain, users must have domain accounts and your system infrastructure must be enabled for Kerberos delegation (belongs to ServerFault). The reason is that you have two hoops in the system - first user authenticates from his client machine to your web server and then web server delegates user credentials to database server. If client computer, web server and database server are different machine Kerberos delegation must be enabled (if db and web runs on the same server you should be fine without Kerberos). Your web application will have to use impersonation and your connection string will have to use windows integrated security.
Also using end user credentials will reduce performance of your system because EF will have to maintain separate connection pool per user. Administrator of SQL server will have to give access for every single user (or user group) using your application.

How do I allow anonymous access to my IIS site, but use Windows Authentication to connect to SQL Server?

What I want to do is:
Allow anonymous users to access my ASP .NET site.
Use Windows Authentication for the site to access Sql Server. It will log in to Sql Server with a domain account set aside especially for the site (and preferably do everything under the same account).
Every article on the Web tells you to do this:
<authentication mode="Windows"/>
<identity impersonate="true"/>
in Web.config. However, I gather that this is only if you want users to log in with Windows Authentication. It has nothing to do with the server logging in to SQL Server (except that the combination of the above 2 implies that users' authentication will also be used to connect to the database). Is this correct? Given that my Windows account has access to files on the server and the database which the site is connecting to, this seems hard to test....
It seems that if I:
set the App Pool Identity to the domain account
enable Anonymous Access on the site using the domain account
use a connect string with Windows Authentication
then the site will connect to SQL Server via Windows Authentication. Also, it will use the domain account as long as impersonation is off. Is this correct?
in Web.config. However, I gather that
this is only if you want users to log
in with Windows Authentication. It has
nothing to do with the server logging
in to SQL Server
This is partially true. The impersonated account will be used to logon SQL server if delegation is setup properly. You didn't see this because in most of the environment, delegation needs to be explicitly setup. Delegation is a more powerful form of impersonation and makes it possible for the server process (in your case, IIS process) to access remote resources (in your case, SQL server) while acting as the client. For more information, you can google ASP.NET Delegation. I said it's partially true because in some simple environment, you don't even need any special configuration. The delegation is just working. For example, if you have SQL server running on the same machine as the IIS server. Another case is that you have your IIS server running on an Active Directory domain controller (very rare). In these two cases or on a machine with delegation configured properly, your above statements will be wrong.
It seems that if I:
set the App Pool Identity to the
domain account
enable Anonymous
Access on the site using the domain
account
use a connect string with
Windows Authentication
then the site
will connect to SQL Server via Windows
Authentication. Also, it will use the
domain account as long as
impersonation is off. Is this correct?
Yes, this is correct.
Given that my Windows account has
access to files on the server and the
database which the site is connecting
to, this seems hard to test....
It's easy to test if you have two domain accounts (or one domain account and one local account). Set the App Pool identity to use your DomainAccount1. Grant only DomainAccount1 to have permission to access your database. Access your web app on another machine using another accound (either domain account or local account). Test if the web app can properly access your database.
If I'm following you correctly, you are right; You do not want to use impersonation/authentication to do what you want to do. Set the App Pool identity appropriately, and assure that user account has appropriate access to SQL Server.
Instead of using a Windows Account you can create a separate Sql Login i.e. a username/pwd and use that in the connection string instead.

SQL Server and windows authentication in IIS7

I'm trying to get an ASP.NET website running on Vista (IIS7), using SQL Server and Windows Authentication. No matter what I do, when I connect to the database, I get the exception:
SqlException was unhandled
Login failed for user 'MyDomain\MachineName$'.
It doesn't seem to matter what settings I apply, I cannot get IIS7 to pass through my Windows login credentials.
Extra details:
Both the SQL Server and my local machine are on ActiveDirectory
Vista Enterprise, IIS7
SQL Server 2005
Anonymous Authentication disabled, Windows Authentication enabled
Impersonation on/off makes no difference
All Identities (NetworkService, LocalSystem, etc) give the same result
Classic and integrated pipelines give the same result
Help!
Impersonation on/off makes all the difference, when properly configured. What you want is caled 'constrained delegation' and you need to configure IIS and ASP for it:
How To: Use Protocol Transition and Constrained Delegation in ASP.NET 2.0
Configure ASP.NET Impersonation Authentication (IIS 7)
Configuring Servers for Delegation
By default, the IIS server is not allowed to impersonate you towards the SQL Server. There's an MSDN article on how to configure it. The configuration process is complex and error prone.
If your production ISS and SQL Server run on different servers, you'll need a domain admin to configure impersonation trust between the two servers. This is typically a no-go in a big organization.
In addition to not being deployed by normal admins, impersonation also prevents users from sharing their connections in the SQL connection pool. This results in a very noticeable performance penalty for even small (5+ users) websites.
Did you try to create a new user account for your application, grant it the appropriate rights on the Sql Server, and then set the application pool to run under this new account?
This is what I usually do, and it works. I'm not running my application under NetworkService, LocalSystem or other builtin accounts.
Does your connection string contain Integrated Security=SSPI?
Have you switched the asp.net context to be a domain user as well?
Here is an MSDN article on this topic
http://msdn.microsoft.com/en-us/library/2xzyzb0f.aspx

Resources