WebApi access to database fails when deployed to IIS - c#

I developing ASP.Net MVC website which uses an ADO.Net Entity Data Model to connect to a MS SQL Server.
To access data it uses WebApis in views called from jquery which use the above datamodel to get data, and it also uses code in the view controller which also uses the same datamodel.
When I run this locally (on the development machine), everything works fine. However, when I deploy it to IIS v10.0 and try to access the website from another machine, it partially works. Calls to the database made using the WebApis fail with a:
HTTP500: SERVER ERROR - The server encountered an unexpected condition that prevented it from fulfilling the request.
Whilst pages that call data access code from the view controller work correctly.
When I look at the error for the WebAPI I see that the following error is produced:
"ExceptionMessage":"Login failed for user 'xxx\yyy-zzz-15$'
I don't know why this login is being used - I would expecting it to be using the 'NT AUTHORITY\IUSR' login, like the data access code from the view controller does.
Any thoughts?

you have two options
in database add that user to NT AUTHORITY\SYSTEM and give it the
permissions to your database.
make new user login in database and give it the
permissions to your database and change the web.config to not be integrated
security and add the user ID and password.

Your problem as it stands is because you are running as a default account - you've then asked that account to access other machines and data. To fix that you need to have it work as an actual account.
To have your webcode run as a user the simplest way is get a functional account from your AD team, and then set the pool for your site to be that AD account, and allow that AD account also the appropriate (eg not sa) to SQL.. As per comment to Mohamed's options above.

Please check the application pool on which your website is running. If the app pool is running on a service account, you need to add same account to your database server and assign proper permissions.

In your connection string, if you don't set the user, it will use the IUSR user.
And the IUSR User will not have enough permission to connect to the database.
I don't recommend to give rights to the IUSR user because this can cause security issues!
Instead, you should define your user id and password in your connection string.
If there is not user that you can use in your server, you can create a new user and give necessary permissions to this user.
here is a simple connection string :
data source=yourServerID;initial catalog=YourDatabaseName;user ID=yourNewUser;password=PasswordOfYourNewUser;
To configure a new user :
https://support.chartio.com/knowledgebase/granting-table-level-permissions-in-sql-server

Related

Entity Framework Core and Windows authentication on IIS Server

I'm trying to use, for the first time, Windows authentication on my ASP.NET Core 3.1 MVC site to connect to SQL Server using EF Core.
Locally everything is ok (using IIS Express), but on the server, something goes wrong.
My site has "hi,<myDomain/myAccount>!" on the top right of the page, and it is correct, but when I request a page with database query, I get this error:
SqlException: Login failed for user 'MyDomain\MyServerName$'
Why? How do I configure EF Core connection string?
Update:
I can't use form authentication
I don't have a user list table
I can use impersonation (WinAuth? active dir?)
Every user(more can login to site has the access to the sql database
I can change some IIS Server settings
This is the first time i use the winAuth (auto configured by visual studio create project tool => with windows authentication)
"what kind of user is the app pool running under?" i don't know, the default one i think
This is likely an issue having to do with the credentials running the app pool in IIS, and the access rights those particular credentials have. You say you are NOT using impersonation, in which case the request to SQL Server from your app running on IIS needs to be made using a system account that has proper database access. A system account being a singleton account that only exists to run as the "Application Pool Identity" for the app in IIS.
On IIS on your server, what kind of user is the app pool running under? In most cases with Windows Authentication, you want to use a system account of some kind to run the app pool and then give that system account access to the database. If you don't want to use a system account, you would have to use impersonation, and then use an AD Group to give the impersonated users access to the SQL Server Database.
Since you're saying the request to SQL server is coming across as DOMAIN\SERVERNAME, you likely need to change that setting in IIS to set the request to come from a system account, and then give that system account explicit access to the SQL Server database.
You can change this by adjusting your Advanced Settings in IIS and inputting the information (Username/PW) of the account you want to run the app under or "as" in IIS.
Then, add this same DOMAIN\USERNAME account to the Database as a user who can Read/Write/Delete etc. You could also simply add the DOMAIN\SERVERNAME that is being denied in it's request to the database here, if you don't want to use a custom system account.
As for "How to configure EFCore connection string?", this is usually done in the Startup.cs file. There you can input a connection string from your appsettings.json directly with the .UseSqlServer(connectionstring) method.
You access the connection string using Configuration.GetConnectionString("KEY").
Once configured there, you don't need to configure it again (unless perhaps to change from dev/qa/prod environments).

API Database Connection Issue

I am attempting to create a new web api for my company and am running into an issue with permissions.
First, the api is hosted on one server and it needs to access a database on another server. The app pool is using ApplicationPoolIdentity as it's identity.
When I run the api from Visual Studio, it is able to access the database on the other server. Incidently, I made sure that my login doesn't have access to that server. Instead I am forcing the api to use a connection string from the web.config file that contains a username and password. I am able to pull back information just fine.
When I put the api into IIS on my machine, I get the error 'Login failed for user Domain\username' any time I try to get information to return from the API. Is there any reason that Visual Studio would allow this to work, but IIS keeps trying to login to the database server with my machine account instead of using the connection string in the web.config file? I am trying to figure out how to get around this issue.
I found the issue. It seems that my connection string was being modified in three different places in the program. At one point one of my team members had it coded to pull the machine as the user instead of using my connection string. Once I updated and removed redundant code I was able to make the connection between machines without having to use a domain account.

Send User Identity to SQL for login

We have developed a product which is a web application. While configuring it in IIS, we disable all the authentication modes except Windows authentication (app works on Windows authentication only).
We create a service account and provide admin access to that account on all the servers, and on database servers.
We configure the connection string in web.config with username and password of that service account. Everything was working fine till now.
We received a new requirement which says, no service account will be created and individual users will be granted database access. We have to configure our application in such a way that Windows credentials are used to access the app gets passed to SQL Server. Reason for this change: we can log the user accessing the database.
I set Integrated Security=SSPI in the connection string and tried with different App Pool Identity but to no avail.
We are even ready to change the code if same is required to achieve the functionality.
Can someone please help me what am I missing, or how it can be achieved? Please let me know if more information is required and I will be happy to provide the same.
App server and database server are on the same domain and network but different machines. Users accessing the application will be on the same domain and network. This is a intranet based application.
You need to enable and configure constrained delegation. Follow this document: How to Implement Kerberos Constrained Delegation with SQL Server. Your app pool need to be configured to impersonate, see Using IIS Authentication with ASP.NET Impersonation.
Also this will be a hop scenario so you will have to enable delegation for the IIS server and if you intend to pass user credentials then you need to enable delegation for the user accounts too. You can use the tool delegconfig to troubleshoot this.

Authenticating user trying to access TFS2010 through webform on remote server

I have made a webform that inserts work items to a tfs 2010server. On the tfs server I need to be able to see which user created the work item. If I run the webform code locally on my machine this works, because my machine is logged in to my user on the tfs server. But after deploying the code on a server I get a (401) unauthorized error message if I don't hardcode in my credentials like this
TfsConfigurationServer configurationServer = new TfsConfigurationServer(configurationServerUri, new NetworkCredential(user, pwd, domain));
(Locally the code below works)
TfsConfigurationServer configurationServer = new TfsConfigurationServer(configurationServerUri);
Is it possible to tell the webserver which user is logged into the machine accessing the webform, or is it any way I can prompt the user for username/password when he/she submits the webform?
thx for any help!
There are several things you need to do and approach this issue
First most likely you have anonymous authentication allowed for your website. Meaning users can access your site without any restrictions and wont need to provide any information. Webserver doesn't know who they are. This will need to be disabled as by your question you need their info. You web app will try to connect to tfs under the webservers identity - either the dedicated account running the application pool or computer account.
http://technet.microsoft.com/en-us/library/cc770966(v=ws.10).aspx
The most simplest method is to enable basic authentication for your website, this will request users to provide username and password, downside is this method transmits data in base64 plain text, as such you channel must be secure
http://technet.microsoft.com/en-us/library/cc772009(v=ws.10).aspx
Forms authentication will allow you to use custom form to collect login info from users, and validate it yourself but works much like basic authentication
http://technet.microsoft.com/en-us/library/cc753252(v=ws.10).aspx
If clients are users in your domain and application is used in intranet the best option is to use Windows authentication, it will try to automatically get users identity from domain, and will issue popup if that fails. Depending how your servers are setup getting this to work may be as easy as enabling it (tfs and your app on the same server) or require configuring your domain controllers for kerberous.
http://technet.microsoft.com/en-us/library/cc754628(v=ws.10).aspx
Once users are in have been authenticated you must make the webserver impersonate them when your code calls tfs. Complexity again depends on your setup.
http://technet.microsoft.com/en-us/library/cc730708(v=ws.10).aspx
Alternativly you can use tfs impersonation to get similar result, this can be also used if for example you dont have users in tfs for each user connecting but instead want to impersonate and ClientCompany, Project or Team account
http://blogs.msdn.com/b/paulking/archive/2010/11/04/using-the-new-tfs-2010-impersonation-apis.aspx

Users spoofing domain name

We currently have a winforms app that allows users to log in in order to access the system. The authentication system is a custom made kludge. I'm working on a implementing a change that links users NT username and domainname to their existing custom account so that they don't need to repeatedly log in. I'm using WindowsIdentity.GetCurrent().Name then storing that information in a database table that maps to their old accountid. What I'm wondering is if it would be possible for a user to vpn into the network with a computer name that mirrors the real domain name? This could potentially give a rogue user access to someone elses account. I guess the real question is: is there a way to differentiate between the sql servers domain and a users domain without just doing a string compare on the names.
Yes it would if your app was using SQL Authentication to access the database. If you change the Database connection to use trusted authentication then the SQL Server will authenticate the login against the domain controller. So despite the user having access to the application they wouldn't be able to access the database driving the applicaiton. If you did this you could also move the capturing of the user name to a SQL Server stored procedure which would ensure that the name captured matched that of the Domain rather than the local users.
THE SERVER MUST NOT TRUST THE CLIENT.
If the client can get and use credentials to log in to the database server you're toast.
If your server is only a database server and your application does not use trusted connections and your application does not prompt for db credentials you're toast. (See previous statement.)
I'm lazy. I'll patch WindowsIdentity.GetCurrent().Name to return "Administrator" if I feel like it.

Categories

Resources