IIS fails to pass windows credentials through to SQL Server for ASP.NET Core app - asp.net

I work for a large company with an intranet and Windows AD logins for everyone. We have a number of internal SQL Server databases which allow us to log in using Windows authentication, one of which I'm trying to connect to through an ASP.NET Core application. I can connect to this database through SQL Server Management Studio and query the tables fine.
I've followed the tutorial for an ASP.NET Core app using an existing database as closely as I possibly could, and created a single model class to test with to see if I could read data from the database. When debugging with IIS Express in Visual Studio, I can read data from the database when accessing the auto-generated controller and views.
Everything seems fine when debugging, but when publishing to IIS, I receive the following error:
SqlException: Login failed for user '<DOMAIN>\<COMPUTERNAME>$'.
Where domain is my domain and computername is my computer's name. This is expected, since my computer itself doesn't have access to the database. But it shouldn't be trying to connect using that system account (with the dollar sign), it should be trying to connect with my windows account: <DOMAIN>\<USERNAME>.
What's weirder, the app does seem to recognize my Windows credentials in some capacity - when I access the home page, I get the familiar "Hello, <DOMAIN>\<USERNAME>!" message in the nav bar. So the Windows credentials are definitely getting passed through to the app, but for some reason not getting passed through when trying to connect to the database through DbContext.
Am I missing something obvious here?
My Code
I started with Visual Studio's ASP.NET Core Web Application template.
In launchSettings.json, I have:
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": false,
"iisExpress": {
"applicationUrl": "http://localhost:60686",
"sslPort": 44336
}
},
In appsettings.json, I have:
"ConnectionStrings": {
"MyDB": "Server=<servername>;Database=<dbname>;Trusted_Connection=True;"
},
In Startup.cs, I have the following line in ConfigureServices
services.AddDbContext<MyContext>(options => {
options.UseSqlServer(Configuration.GetConnectionString("MyDB"));
});
And from there, I have scaffolded an MVC controller with views using Entity Framework.
IIS has Windows authentication set to Yes and anonymous authentication set to No. My application pool is set to No Managed Code with ApplicationPoolIdentity.
Edit: The problem
To state the actual problem I'm trying to solve, I have a SQL Server database on a remote intranet server which allows access to a subset of the whole company via Windows authentication. If I want to create an ASP.NET application to provide an API to that database, hosted by IIS, what's the best way to do this? Assuming:
I don't want to have to manage permissions myself or have to duplicate them in some way
The people who have access to the database directly should have access to the API, the people who don't should not.
If they're accessing it from within the intranet while logged in to Windows, they shouldn't have to log in again.
I assumed I could just pass their windows credentials from IIS through the app to SQL server but I'm starting to wonder if that's actually the case.

After learning more about .NET and what Windows auth actually does on IIS, I'm going to say that what I was trying to do is not recommended. There is a difference between passing windows credentials to a .NET app in order to read from them, vs. actually executing a secondary process as that user. The latter case is what I was trying to do, but instead should set up my app pool in IIS with a user who can log in to the database, and use the windows credentials to verify against the list of users who have access.

You are using Entity-Framework for SqlServer and EF is using ADO.NET SqlClient. Therefore Trusted_Connection=yes; does not work.
Add Integrated Security=true; instead and it should be fixed.
Here some resources to read about it
https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/connection-string-syntax

Not to dig up an old thread, but this is a function that should work as long as Identity Impersonate = True is set. Here's some stuff being worked on.
GitHub Doc

I'll add my answer because this is how I fixed this issue.
The reason a "$"-sign is added to the login name/user must have something to do with the IIS that the application is being hosted on.
I'm not an expert on any of this, so I can't really go in-depth, but I've added the IIS user to the Logins and then it works.
USE [master]
GO
CREATE LOGIN [IIS APPPOOL\'name'] FROM WINDOWS WITH DEFAULT_DATABASE=[master], DEFAULT_LANGUAGE=[us_english]
GO
ALTER SERVER ROLE [sysadmin] ADD MEMBER [IIS APPPOOL\'name']
GO
ALTER SERVER ROLE [securityadmin] ADD MEMBER [IIS APPPOOL\'name']
GO
ALTER SERVER ROLE [serveradmin] ADD MEMBER [IIS APPPOOL\'name']
GO
ALTER SERVER ROLE [setupadmin] ADD MEMBER [IIS APPPOOL\'name']
GO
ALTER SERVER ROLE [processadmin] ADD MEMBER [IIS APPPOOL\'name']
GO
ALTER SERVER ROLE [diskadmin] ADD MEMBER [IIS APPPOOL\'name']
GO
ALTER SERVER ROLE [dbcreator] ADD MEMBER [IIS APPPOOL\'name']
GO
ALTER SERVER ROLE [bulkadmin] ADD MEMBER [IIS APPPOOL\'name']
GO
You have to change 'name' to your IIS hosted application name. So for example if you app/site's name in ISS is "My-Backend-App" you should do:
CREATE LOGIN [IIS APPPOOL\My-Backend-App] FROM WINDOWS ...
So all the names should be "My-Backend-App".
When adding this user to the logins, my backend application could access & create the DB, create tables, access data etc...
SIDENOTE: I've used the Windows Event logger to find out this was my issue. My application just crashed, said a "500.30" error but no real information given.
You can access the "Event Viewer" application from Windows Search. Then you can go to "Applications" and there are all application errors/crashes that occured on your machine, and in this case also the reason why. It said it couldn't find user "myUser$" while trying to login to SQL, but the Windows Authentication user was "myUser". So for some reason it added a "$"-sign and couldn't log in. My fix above fixes this issue and you can login etc.

Related

Granting sql server database access to IIS APPPOOL\DefaultAppPool

I have an ASP NET APP that's trying to access a sql server database, when I run it, I get an error saying
"Login Failed for user IIS APPPOOL\DefaultAppPool"
Searching the web I found that I should grant access to this user, so I executed the following script:
grant execute on schema :: dbo to [IIS APPPOOL\DefaultAppPool]
It executed succesfully as a script for my database, but I still get the "Login Failed" error.
What's missing?
Check the user your DefaultAppPool is using to connect.
On your IIS manager check DefaultAppPool advanced properties and look for Identity. You need to give it a user with enough privileges, depending on what your site is going to do.
I usually create different AppPools for different sites depending on what they will do, for example, if your app will write documents to a folder on your server, the user of the AppPool will need writing access to that folder.
Also is not a good idea to use an administrator user, as it could lead to potential security breaches. However it could be a good way to check if your problem comes from there.
I think I already know what it is. When I upgraded SQL Server Express, it installed a new server .\SQLEXPRESS (because I used "new sql instance"), remote connections where configured in this server and not LocalDB, my database was still in LocalDB. But now I get other error, maybe related to WCF Data Services...

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.

Login failed for user 'IIS APPPOOL\myAppPool

I having the following error message:
Cannot open database "SmallBakery" requested by the login. The login failed. Login failed for user 'IIS APPPOOL\MyAppPool'
How can correct this? I am using windows 7 Enterprise Edition and Sql server 2012.
If you don't change, each app pool has it's own identity. In your case, just add a new user to your database SmallBakery with the name IIS APPPOOL\MyAppPool using SQL Management Studio. You find the users list in the "Security/Users" subnode of your database. This should look something like that:
For testing, let the user be member of the db_owner role. If that works, remove this role and just let it be member of db_datareader and db_datawriter.
This way, each app pool (perhaps each website, if they all use their own app pool) only has access to the corresponding database.
It depends on how you want to authenticate in your app. Are you trying to use impersonation in your app?
What's happening right now is the identity of your app pool in IIS is getting passed when trying to access the database. You can change the identity of your app pool to be something that has access to the database or you could change your connection string to use a specific login instead of integrated security.
Check this post out. Your problem sounds similar to one I was running into, with the same exact error message.
http://blogs.msdn.com/b/sqlexpress/archive/2011/12/09/using-localdb-with-full-iis-part-2-instance-ownership.aspx
Like others said so far you need to take your app pool system user (IIS AppPool\myapppool) and add it as database user for that database with appropriate permissions.
Note that this will work just find on your IIS/Server but if you plan on migrating application to a different IIS/Sql server it will require changes in both SQL Server and IIS. I’d suggest you also consider sql server authentication – it may be more convenient for your specific case.
In my case these steps lead me to successfully handle this error.Hope it will help you also

Attaching mdf file into sql server

Earlier mdf file was in app_Data folder, and application was working fine.
When I attached mdf file into sql server. I can execute queries. But when I try to use it from asp.net application it give following exception.
Cannot open user default database. Login failed.
Login failed for user 'domain\username'
So if I understand correctly you no longer specify the AttachDBFilename but instead you have attached the database 'for real' to an existing SQL Server instance.
since you are no longer conencting to your own personal RANU instance, your application must have proper credentials to connect to the SQL Server instance where you attached the database. The correct solution depends on a number of factors, but possible answers are:
create a SQL Server login for the ASP app pool identity and grant this loggin proper access to the required database. Use CREATE LOGIN [domain\user] FROM WINDOWS and CREATE USER [domain\user]. Better still, for extra credit, add the app pool identity to a security group and grant this security group the needed permission.
change the app pool identity to an indetity that has the proper permissions already granted
if the ASP application uses impersonation and the SQL Server instance is on a different machine from the ASP application, make sure your ASP app pool is allowed to do constrained delegation.
That error indicates that you are trying to use Intergrated Security. Depending on your version of IIS and your configuration, you are probably trying to connect to the database with the IUSR or NETWORK SERVICE accounts.
The simplest fix is to use SQL Authentication. Include a SQL account username/password in your connection string.

ASP.Net application cannot Login to SQL Server Database when deployed to Web Server

I am having a problem with deploying a ASP.NET V2 web application to our deployment environment and am having trouble with the sql server setup .
When I run the website I get a Login failed for user 'MOETP\MOERSVPWLG$'. error when it tries to connect to the database.
This seems to be the network service user which is the behaviour I want from the application but I don't seem to be able to allow the network service user to access the database.
Some details about the setup. IIS 6 and SQL Server 2005 are both setup on the same server in the deployment environment. The only change from the test setup I made is to point the database connection string to the new live database and of course copy everything over.
My assumption at this point is that there is something that needs to be done to the SQL server setup to allow connections from asp.net. But I can't see what it could be.
Any Ideas?
It sounds like you're able to connect to the database alright and you're using integrated windows authentication.
With integrated windows authentication your connection to your database is going to use whatever your application pool user identity is using. You have to make sure that the user identity that asp.net is using is on the database server.
If it is a fresh install not everything may be setup. Check SQL Server Configuration Manager, http://msdn.microsoft.com/en-us/library/ms174212.aspx. Step by step instructions http://download.pro.parallels.com/10.3.1/docs/windows/Guides/pcpw_upgrade_guide/7351.htm.
The user name you've indicated in your post is what the Network Service account on one machine looks like to other machines, ie "DOMAIN\MACHINENAME$".
If you are connecting from IIS6 on one machine to SQL Server on another machine and you are using Network Service for the application pool's process identity then you need to explicitly add 'MOETP\MOERSVPWLG$' as a login to the SQL Server, and map it to an appropriate database user and role. Type that name in exactly as the login name (minus quotes, of course).
Make sure there is a login created for the user you are trying to log in as on the sql server.
There's a few different things it could be.
Are you using integrated windows authentication? If so, you need to make sure the user ASP.net is running as can talk to the database (or impersonate one that can).
Does the web server have permission to talk to the database? Sometimes a web server is deployed in a DMZ.
If you are using a SQL Server login, does that same login exist on the production server with the same permissions?

Resources