WCF, IPC Named Pipes, ASP.NET, and <identity impersonate="true" /> - asp.net

We have a .NET 4.0 Windows Service that is hosting an endpoint over a Named Pipe (using IPC). This service is running under the context of User A.
We have an ASP.NET-hosted client that is requesting the operation that is exposed by the aforementioned service. This client runs under the context of User B (via Anonymous Access ,via <identity impersonate="true" />).
The problem:
If we use <identity impersonate="true" /> in our web.config (this cannot be changed), we get "Failed to connect to an IPC Port: Access is denied." exceptions when the client tries to call the hosted operation. If <identity impersonate... /> does not exist (perhaps by virtue of not using ASP.NET, say a client Console Application), we have no issue.
Does anyone out there know how to get this configuration working so we stop receiving Access Denied errors? It has something to do with authentication but we just can't work it out.

Recalling from 70-503: net.pipes only works with Windows security. It's obvious because the whole process (WCF) is on the current (Windows) machine only. ASP.NET runs under the credentials of a dedicated ASP.NET-user by default who's rights are strictly limited. I don't aspect the ASP.NET user having access to the current machine, accessing local files, net.pipes etc. It only has access to the folder your website runs from. So, by impersonating that very user is like ensuring having only the rights to run a website.
What you can do is impersonate to a specific Windows account who has the appropriate rights. This can be done using programmatic impersonation. Or use delegation. Read about it here to use the solution who fits best.

Not possible due to NetWorkService being restricted from seeing or accessing the pipe.
Answer here

Related

How to integrate an ASP.Net intranet with Active Directory?

I'm currently working on an intranet portal for my company, it will remain internal, only users with accounts on our domain will have access to it. At the moment, I use forms authentication method, and authenticate users against the Active Directory domain with System.DirectoryServices. I also interrogate the AD with System.DirectoryServices.AccountManagement to manage access rights depending on the Active Directory groups the user belongs to and I store some data in user sessions and everything works fine.
I've been asked to study whether Single Sign-On could be implemented in our context, all our users work in RDS without exceptions, so they always are in an authenticated session and the higher-ups would prefer not having to sign in at all. As far as rewritting the code to authentify and authorize users as explained here and here
I'm not too concerned.
I tried everything on a blank ASP.Net MVC5 project, to which I added an ADO.Net model with integrated security. My dev SQL Server is hosted on a remote server (not the dev desktop), the same server also hosts the dev IIS server. In production, both services will be on separate servers. This worked fine as long as I was debugging localy on my desktop, but once I published to the IIS server, I hit the first snag and couldn't get out of it.
When I changed settings in the IIS app to disable anonymous and enable windows authentication, IIS automatically changed <authentication mode="Forms" /> to <authentication mode="Windows" /> in the web.config file (as suggested here), but I couldn't make it work with Integrated Security=True or Integrated Security=SSPI, I get an error page saying [SqlException (0x80131904): Login failed for user 'DOMAIN\MACHINE$'.].
The connection string reads like: <add name="ASPNetProjectEntities" connectionString="metadata=res://*/Models.ModelASPNetProject.csdl|res://*/Models.ModelASPNetProject.ssdl|res://*/Models.ModelASPNetProject.msl;provider=System.Data.SqlClient;provider connection string="data source=MACHINE;initial catalog=DATABASE;persist security info=True;Integrated Security=SSPI;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
I tried to add the machine account DOMAIN\MACHINE$ to SQL logins and grant it rights to the database, but no dice. I tried to authorize delegation in the server AD account and activate identity impersonation, but that didn't work either. I can only make it work on the remote IIS server if I put a SQL user/pass in the connection string.
So I'm at loss what could be missing here to make it work with Integrated Security. Or will I have to put SQL credentials in the connection string and encrypt it on IIS?
You're confusing Integrated Security with the authentication mechanism of your website. If you use Integrated Security, the connection used from your web app to SQL Server will use the account that the application pool your web app is running as is using. To use Integrated Security, have a service account created in AD, set your app pool to run as that account, and grant the necessary permissions to that service account in SQL Server.
Note that whether you're using forms auth or integrated security isn't relevant to how the web app connects to SQL Server, unless you're using impersonation, which you should never use.

asp.net Impersonate User for network resource access

code:
System.Security.Principal.WindowsImpersonationContext impersonationContext;
impersonationContext =
((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();
//access network resources.
impersonationContext.Undo();
web.config:
<authentication mode="Windows">
</authentication>
<identity impersonate="true"
userName="user"
password="password"></identity>
As clear from web.config file, the app runs in an impersonated mode. I need to impersonate temporarily on top of that to access a network resource. I do that as shown above.
This works fine on server if I browse to the website on the local IE installed on the server but when I access the app from my PC or any other PC, I get a access denied.
Btw, this is all within an enterprise domain environment. so IE in both cases is passing a valid authenticated token.
Any ideas what is going on. thanks.
You need to make sure the server will delegate the impersonated security contexts in your application to another server (the network resource you mentioned).
I'm pretty sure it works while you're logged onto your server because it is using the security context of you being logged in directly, and not the impersonated context that exists in the application.
I can't remember specifics on configuration but I do know it is referred to as delegation or "Kerberos Double Hop". "Constrained Delegation" is when you configure such that only one type of delegation is allowed. IE, your app is only allowed to delegate security contexts when talking to Active Directory (port xyz) on this other specific server - otherwise not.
See Understanding Kerberos Double Hop
See DelegConfig - it is helpful in configuring delegation.
Also see: TechNet Article
And: this other article

ASP.NET > SqlServer; trust and delegation

we have a system where they client wants integrated Windows authentication.
This is an ASP.NET 3.5 application, connecting to Sql Server 2005.
The web server is Server 2003 R2 SP2.
The db server is Server 2003 SP2 (not R2).
In the db server, I ran the following script
exec sp_grantlogin 'myDomain\myUserGroup'
USE myDbName
exec sp_grantdbaccess 'myDomain\myUserGroup'
I have 3 users in the Windows user group 'myDomain\myUserGroup' right now. All three users' accounts are marked as trusted for delegation. The web server account in ADs is marked trusted for delegation.
The web application is marked as using Windows authentication (all others turned off).
The web.config has the following lines:
<authentication mode="Windows" ></authentication>
<identity impersonate="true" />
<authorization>
<deny users="?"/>
</authorization>
Yet when i try to connect to the web application with a user which is in the user group, i get the error:
System.Data.SqlClient.SqlException:
Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'.
My connection string is being built from a Sql ConnectionStringBuilder constructed as such:
ConnectionStringBuilder.DataSource = "MYDBSERVER"
ConnectionStringBuilder.InitialCatalog = "MYDBCATALOG"
ConnectionStringBuilder.IntegratedSecurity = True
If i HARD CODE one of the allowed accounts to impersonate on the web.config <identity /> line it works. But if i take off the hard coded account and try to pass the identity from the client's machine. I get the error.
So it seems that i don't have something configured correctly for the multi-hop integrated login scenario, but i can't figure out what.
Thanks in advance!
The ASP machine has authenticated the user connecting to IIS via NTLM/Kerberos. The authentication is guaranteed by the domain controller that has asked the original user process (IE) to present a secret that guarantees his identity: his password he typed when he logged into the box. The authentication is actually not done by the processes involved, but by the Local Security Authority (LSA, aka. lsass.exe) on each machine involved. Because the LSA on the ASP machine knows that the authentication is OK, it will allow an impersonation of the remote user to access anything it has the rights to access under the control of the said LSA (in other words, everything on the local ASP machine).
As soon as the ASP process that impersonates the user makes another hop to a new machine, it has left the realm controlled by the LSA on the ASP machine. The LSA on the SQL machine has no reason to trust the LSA on the ASP machine. So it ask it to present a proof that it is who it claims it is (the impersonated user). The ASP machine unfortunately cannot present such a proof, since it does not has the user secret (its password).
The work around is something called 'constrained delegation'. Through constrained delegation the domain controller intervenes in the negotiation between the SQL's machine LSA and the ASP machine LSA and says 'the ASP machine is OK, I vouch for him'. So the SQL's machine LSA trust the authentication and authenticate the original, impersonated user.
The technical details how to set up constrained delegation are described in How To: Use Protocol Transition and Constrained Delegation in ASP.NET 2.0
Note that this is true anytime a 'double hop' and impersonation is involved, no matter the type of resources involved (can be a SQL server, can be a file share, can be a new back end ASP service).
If you're using Windows authentication then Impersonation doesn't flow past the ASP.NET process itself. You have two options here - swap to Basic Authentication, where Identity flows or, if you're running on Win2003 or later, you can use Kerberos and some hackery to impersonate when you connect

The error "Login failed for user 'NT AUTHORITY\IUSR'" in ASP.NET and SQL Server 2008

My ASP.NET v3.5 web application is throwing the following exception when it attempts to open a connection to a SQL Server 2008 database:
System.Data.SqlClient.SqlException:
Cannot open database "MyDbName"
requested by the login. The login
failed. Login failed for user 'NT
AUTHORITY\IUSR'.
The thing is, I've added NT AUTHORITY\IUSR to the server's list of logins, and to the database's list of users. For the server, I've granted the user the Public role, and for the database I've granted db_datareader permissions.
I've also granted the same for NT AUTHORITY\NETWORK SERVICE, which is the identity that the application pool is running under.
The web application is hosted by IIS7, if that makes a difference. The problem repros when the DB and IIS are on the same physical machine as well.
The trick here is that NT AUTHORITY\NETWORK SERVICE actually appears to the database as DOMAINNAME\MACHINENAME$ (note the $ sign!). That is, when you cross the machine boundary from your web server to the SQL Server, SQL Server sees the machine account if you use the NETWORK SERVICE or LOCAL SYSTEM accounts. If you use any other non-domain account, SQL Server will not receive your credentials.
I'm a bit puzzled by your error message. Truth be told, I don't think that when the DB is on another box, you'll see anything other than Login Failed for NT AUTHORITY\ANONYMOUS LOGON.
IUSR is used for anonymous websites, and can't pass over the wire to SQL Server. You may find a way for it to work if you're doing everything on the same machine, but I'd never know because I'd never do it that way... ;-)
In case it helps someone, in web.config I added <identity impersonate="false" /> for this error to go away (under <system.web>)
It's important to note that you'll get this error, as I just did, if you don't have IIS configured to allow impersonation, but you do have your web.config attempting to do impersonation.
I just came across this exact error, and all of the following steps are required:
Ensure ASP.NET impersonation is enabled on your IIS web server:
Combine that with configuring your site to use impersonation (web.config):
<system.web>
<identity impersonate="true" userName="your_service_acct" password="***" />
</system.web>
The above steps presume that you have a SQL Login setup on your MSSQL for 'your_service_acct' with permissions
When running on localhost, against a localdb, or even a remote db that you personally have permissions on, the development IIS runs as if it were YOU - and everything just magically works. So, in debug mode, you don't need to create a special web.config..
As soon as you deploy your site onto some kind of server (in my case, our TEST environment) you'll likely need to have done the above steps I just detailed, because IIS will try to connect as the application pool user, which is not usually what you want administratively speaking. So, that's when you want to start using web.config transformations, so Visual Studio will insert the appropriate identity impersonate="true" during your 'Publish...' deployment step.
I would suggest to create a separate (preferably domain) account and specify it in the connection string (usually in web.config)
Then you can limit permissions on the web server what this account can and cannot do.
Then you can grant this account required permissions in SQL server.
I had had the same problem and solved this by changing application pool.
Instead of using Integrated Security=True; in connection string, just use username and password authentication user=sa; pwd=mypassword;
The simple solution is to check your web.config file and make sure one of these is part of the db connection string:
Trusted Connection=false
OR
Integrated Security=True
This problem is shown when you restore a new database on your last database.
To resolve this you must go to sqlserver, then security and then set your apppool again.
this worked for me:
Open the IIS Manager (inetmgr)
In the "Connections" panel, drill down to your site's node and select it
In the right-hand panel, under the "IIS" group, double click the "Authentication" icon.
Right-click on "Anonymous Authentication" and choose "Edit..." from the context menu.
In the popup dialog, select the "Application pool identity" radio button.
Click OK.

ASP.NET web app can't use multiple impersonation for authenication

I have a asp.net app (uses windows authentication for access) which (stipulated by the security team) needs to connect to a remote SQL Server 2005 using integrated security.Because of the fact that it is remote SQL server I needed to impersonate a custom account (impersonating the original caller would not work) via :
<identity impersonate = "true" userName="domainname\user" password="password" />
This workes fine. The rub is my app also connects to an SSRS server for reporting needs using the ReportViewer control. The report server is on a separate server and the security team mandates that all calls to this server must be using the original window's account for auditing purposes. It seems my only option was to to try and separate my app into folders and use a "location" tag in my web.config and use separate identity tags. Such as:
<location path="Reporting">
<system.web>
<identity impersonate = "true"/>
</system.web>
</location>
Note: no username and password specified which means it should impersonate the original caller.
However to make matters even more complicated my app is a Masterpage/content page app. The master page makes calls to SQL to populate menus and such. Bottom line is the dual impersonation track is not working. I am ready to throw my hands up and declare that that this can not be done. If there was a way where I could have the app impersonate the original caller which would satisfy my SSRS auditing needs yet make connections to SQL server as the custom domain account. I cannot use SQL authentication: not allowed although that would solve this issue.
Have you tried the following setup:
Set impersonation to true. This is necessary for authentication into the application and for access to the SSRS to use current user logged in.
Use one connection string to SSRS that has Integrated Security set to true, so that the impersonated user passes straight through.
Use a second connection string, with the custom user name and password hard coded into the connection string. You can encrypt the connection string section of the web.config so that it isn't visible to human eyes, but the framework will automatically decrypt this on the fly when creating a connection.
I have a similar situation (need a specific account to retrieve specific data, but the general impersonation for the rest of the service functionality) and this setup is working.
EDIT: The general syntax for encrypting your web.config from the command prompt is:
aspnet_regiis -pef "connectionStrings" [PhysicalPathToApplication] -prov "DataProtectionConfigurationProvider"
Encryption is done on a machine per machine basis, so the encryption will have to be done on the specific server. You can pull up more documentation on this if needed.
You should be able to switch the impersonation on and off, so you can go back to using the default account running the site. I will have to check, it's been a while since I have done it.
This looks like a start as to how to do it:
System.Security.Principal.WindowsImpersonationContext impersonationContext;
impersonationContext =
((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();
//Insert your code that runs under the security context of the authenticating user here.
impersonationContext.Undo();
Essentially you just impersonate the appropriate user for the calls you need, and then "undo" the context and turn it off. It goes back to the default user after that.
Here is a link to the windows identity class:
http://msdn.microsoft.com/en-us/library/system.security.principal.windowsidentity.aspx

Resources