I am trying to set up a Test server to try out asp.net (3.5) web applications before they're moved to Production. I want to mirror the settings in IIS from Production server. On my web app, application pool is set as Classic .NET AppPool with identity NetworkService and Windows Authentication is enabled. When I attempt to access app on Test server I get error "The EXECUTE permission was denied on the object 'GetTable', database 'DatabaseName', schema 'xxx'. I realize I can add the network account to that stored procedures security but I shouldn't have to - it works in production without it.
I am using a restored copy of the production database thus the permissions are identical between the two. I did have to add the querying Test server name (i.e. xxx\Test$) to the database security in SQL server to gain access to the database, but I shouldn't have to add other local network permissions as they are included in the Security Logins of SQL (public).
In Windows Event Log* on Test server this piece of the error detail bothers me because the "Thread account name is NT AUTHORITY\NETWORK SERVICE compared to when a permission error is thrown on production server the Thread account name is the name of the user.
I think I need to get the Test server to recognize the real user. I (obviously) do not understand security to the fullest for web apps yet. Can someone suggest other areas for me to investigate? I did research this but I'm only finding things like how to change the apppool account, or identity, not the piece that troubleshoots permissions between client to web server to database server. BTW the production and test databases are on the same server. The product and test applications are on different servers (both Server 2008/IIS 7).
There is one difference: ASP.NET 1.1 application pool is not installed on IIS on Test server. Could that be the issue?
*Windows Event Log snippet:
Request information:
Request URL: http://server/appname/default.aspx
Request path: /appname/default.aspx
User host address: xx.xxx.xx.xx
User: xxx\username
Is authenticated: True
Authentication Type: Negotiate
**Thread account name: NT AUTHORITY\NETWORK SERVICE**
BTW if I move my test app to production server in a new folder, it works fine. Problem is with the test server configuration.
ANSWER: Set Active Directory for IIS server to say "trust this computer for delegation". I found my answer from a 2007 entry posted by plq in this: Microsoft ASP.NET forum
ANSWER: Set Active Directory for IIS server to say "trust this computer for delegation". I found my answer from a 2007 entry posted by 'plq' in this forum: Microsoft ASP.NET forum
Related
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).
I've inherited a WCF web service that uses impersonation to connect to the database, while trying to get the automated tests running I noticed that any of these hitting the test instance of the service were failing with a 401 response.
Using Fiddler to capture the response I was able to see that it was trying to open the database connection using NT AUTHORITY\ANONYMOUS LOGON.
I eventually got remote debugging setup and break pointed immediately before the connection was opened and I used the immediate window to check the current principal, here are the results:
?System.Security.Principal.WindowsIdentity.GetCurrent().Name
"myDomain\myUser"
This is exactly as I was expecting to see. Following this I checked the content of our connection string and it was:
Data Source=myDbServer;Initial Catalog=devDb;Integrated Security=True;User ID=;Password=;Asynchronous Processing=False;Connect Timeout=300;Application Name=myApp
Which again is what was expected.
My next step was to disable the impersonation and see what user was trying to connect at that point:
?System.Security.Principal.WindowsIdentity.GetCurrent().Name
"NT AUTHORITY\NETWORK SERVICE"
However this time the 401 error reported that the user myDomain\myDevServer did not have permissions.
The service is running under Network Service on IIS 7, and this is as intended. Though I did try having it run under a domain user, but saw the exact same results: SQL attempting login with NT AUTHORITY\ANONYMOUS LOGON
My issue is closely related to the one experienced on this question.
However using the same immediate window technique I verified my impersonation level, which was indeed delegation:
?System.Security.Principal.WindowsIdentity.GetCurrent().ImpersonationLevel
Delegation {4}
So what would cause the trusted sql connection to be getting a completely different user than what is shown in the current principal?
Update:
I have verified the settings on the DC, the machine account is configured for unconstrained delegation, and my user account is not marked sensitive.
I also stepped through this article I did note that under the double hop section he says that the ASP.NET Impersonation authentication provider should be enabled, however doing so causes the server to immediately return a 500, it never makes it into managed code.
Additional information:
The services all have the [OperationBehavior(Impersonation = ImpersonationOption.Allowed)] attribute applied to them and the web.config file has <serviceAuthorization impersonateCallerForAllOperations="true" />
The services have both a webHttpBinding for restful calls and a basicHttpBinding for soap calls, both endpoints experience the same issue.
Attempting to authenticate to a remote resource under an impersonated context requires delegation. Follow the Delegation guidelines from Delegation and Impersonation with WCF (these steps require a domain administrator):
On the domain controller, clear the Account is sensitive and cannot be delegated check box for the account under which the client application is running.
On the domain controller, select the Account is trusted for delegation check box for the account under which the client application is running.
On the domain controller, configure the middle tier computer so that it is trusted for delegation, by clicking the Trust computer for delegation option.
On the domain controller, configure the middle tier computer to use constrained delegation, by clicking the Trust this computer for delegation to specified services only option.
If you're under a Windows Server 2012 environment is somehow easier, see How Windows Server 2012 Eases the Pain of Kerberos Constrained Delegation.
If you want to learn more about this problem, google for "Kerberos double hop" and you'll find a tonne of resources, including many answers here on SO.
The most likely cause is a misconfigured SQL Service Principal Name (SPN). When connecting directly to SQL (eg. from Management Studio) a misconfigured SPN causes a fallback to NTLM (ie. it won't be noticed). But in delegation case fallback is not allowed and this causes authentication to fail, so the authorization is done against the anonymous logon, exactly as seen in the OP. SQL Server Kerberos and SPN Quick Reference is a good resource.
I'm facing a weird problem :
I have a simple WCF service that retrieves some data from the DB. When I host the service on local serviceHost everything works fine, but when I host the same service on local IIS (7.5 - windows 7) I get this exception: The Undelying provider failed on open.
I have some logging services inside the service and I found out that this exception occures
only when the service calls some DB service (not one particular, any DB service). The strange thing is that when the service is not hosted on IIS this same DB call works fine.
Things I've done: enabled ASP.NET impersonation on the IIS server -> didn't help.
Another thing : I'm using sql server 2008 express.
Other ideas ???
What security mechanism are you using? It's likely that you are using some sort of Kerberos/Windows Authentication and IIS is unable to pass those credentials to SQL server. This issue is sometimes referred to as the double hop issue and is typically solved by delegation (not ASP.NET delegation).
Link: Delegation and Impersonation
Assuming you are running the service in .NET 4.0 have a look in IIS and the Application Pool serving the application in question.
If the account running the application pool is ApplicationPoolIdentity look in your database that login "IIS AppPool\DefaultAppPool" has rights to access ayour database.
One of the simplest things to get pointed in the right direction is to check your windows event logs, particularly the security log. It may be telling you what's going on.
Check these on both the IIS machine and the DB machine.
Sounds to me like the most likely cause would be security.
In IIS 7.5 you have various security layers. Each AppPool has it's own security credentials which you might want to check.
Also the IIS Windows Service it self has security credentials. You might want to try setting this to Network Account if it's set to local account.
But the error message you posted is the generic WCF error. I would agree with Jim about looking in the event log for more detail. If you find it post it here.
I have a web application set up on our intranet that uses windows authentication (successfully) that I am trying to link to a database running on a separate server.
The problem that I am having however, is that when I try to use a trusted connection to log in to the sql server, instead of passing the domain/username of the person using the website the application is passing NT AUTHORITY\ANONYMOUS LOGON.
I checked that the authentication was working by having the website display a greeting that does identify my username correctly when I log on to the site, so it isn't an anonymous access issue. I think it is an impersonation issue somehow despite the fact that set in the web.config file for the application.
Curiously, the web application works fine when I run it on either my dev machine or even locally through remote desktop on the production server. I'm not sure what's going on here.
Finally, I'm running iis 7.5, windows server 2008 r2 and sql server 2008
This is called Constrained Delegation. Basically what that means is that an impersonated context by default cannot be delegated to authenticate with a resource on the network. If constrained delegation would not be in place anyone could create a web site in the enterprise and expose some benign application. But underneath, once the user authenticated with the site, it could impersonate that user to do anything, like read his mail, sale stock on his behalf, give raises to site developer, *anything. This is why impersonated contexts are not trusted outside the machine that impersonated the user.
To allow an impersonated context to connect to a remote resource (like a file share, or a database server) the domain administrator has to explicitly set up Constrained Delegation, which allows the impersonated context to authenticate with one specific resource.
There are numerous articles describing the problem and the solution:
How To: Use Protocol Transition and Constrained Delegation in ASP.NET 2.0
Protocol Transition with Constrained Delegation Technical Supplement
How To: Connect to SQL Server Using Windows Authentication in ASP.NET 2.0
Configuring Servers for Delegation (IIS 6.0)
How to: Use Protocol Transition for Impersonating and Delegating the Original Caller in WCF
it is a known behavior called double-hop issue. See http://weblogs.asp.net/owscott/archive/2008/08/22/iis-windows-authentication-and-the-double-hop-issue.aspx
If your web application tries to access your database it does it with the account under which the IIS w3wp.exe process is running (networkservice by default).
If you want to change this, you will need to use impersonation.
This document explains it pretty good.
As the document also explains depending on your application, you might want to use trusted subsystem instead of impersonation.
I am using impersonation is used to access file on UNC share as below.
var ctx = ((WindowsIdentity)HttpContext.Current.User.Identity).Impersonate();
string level = WindowsIdentity.GetCurrent().ImpersonationLevel);
On two Windows 2003 servers using IIS6, I am getting different impersonation levels: Delegation on one server and Impersonation on the other server.
This causes issues where I am unable to access the UNC share on the server with 'Impersonation' level.
What could be causing this difference? I searched through machine.config and IIS settings for the app pool, site and virtual directories - but aren't able to find the cause of this problem.
It sounds like one of the computer is trusted for delegation by your Active Directory, but the other is not. If the app pool identity is Network Service, make sure the Computer Account is marked "Trusted for Delegation" in AD.
You may need to ask your AD admin to force a replication and then log out/in to your workstation to refresh your Kerberos ticket cache.
If your testing with localhost as webserver and its working but when deployed you receive errors you could be running into the double-hop issue....outlined in this blog post
For one of our applications where we did Impersonate() we found that we had to modify the local security policy for the application pool owner and add that account to the following policies/groups:
Act as part of the operating system privilege.
Impersonate a client after authentication.
On the server(s), run Start > All Programs > Administration Tools > Local Security Policy then navigate to Local Security Policies > User Rights Assignment and look for the two policies above.