Control a service on a remote server from IIS - asp.net

Please note: In each step I describe below I'm logged in as the same domain user account.
I have a web application that controls a service on a remote machine (via ServiceController). When I connect to the website remotely and attempt to control the service, I get an InvalidOperationException: Access is denied.
I know it CAN work, because when I connect to the website from the web server (remote desktop in, login as my domain user, then open the webpage), it works as expected.
I have configured IIS and ASP.NET to require windows authentication and impersonation. I log the current thread's principal when this fails, and I see that the thread is running under my identity whether I'm connecting remotely or from the server itself.
I have tried forcing IIS to use Kerberos authentication, NTLM authentication and both at the same time; whether my principal reports its AuthenticationType as "Negotiate" or "NTLM" it doesn't matter. None of them work when I connect remotely (from my local machine)
ANOTHER weird thing about this is that if I'm debugging from my local machine/connecting to the remote server, it works every time! But I'm NOT debugging, it fails every time!
What in the heck could be going on here?

Your scenario is delegation and not impersonation. Delegation is hard to achieve and it depends on many thing that are done right.
A place to start would be Kerberos authentication and troubleshooting delegation issues
David Wang blog is a very useful resource on thous issues.

"ANOTHER weird thing about this is that if I'm debugging from my local machine/connecting to the remote server, it works every time! But I'm NOT debugging, it fails every time!"
That's a clear indication that you have permission issues. When you run in the debugger you're running as the logged on user, when you're not debugging it runs as whatever IIS is set to use (NETWORK SERVICE by default). Try setting (temporarily!) the Enable anonymous access using your domain account as the user and see if that works. If it does then it means your IIS is not setup properly to impersonate (and it's probably running as NETWORK SERVICE).
Permissions in IIS can be a bitch to fine tune properly...
Good luck!
P/S: This looks more like a network administration question than a programming one (see https://stackoverflow.com/questions/321618/stackoverflow-is-for-programming-questions-here-are-some-better-forums-for-your#321756)

Related

Asp.net windows authentication against domain - use local (cached) credentials when offline

I have ASP.NET MVC application that uses windows authentication against remote active directory server. The computer where the app runs is connected via VPN to the AD server. The problem is that after user logs into the PC with domain user and logs into the application it needs to run even while offline as well, but it throws this error:
The trust relationship between workstation and domain failed.
From what I understood there is no cookie and the authorization works on per-request basis. Is there any way to authorize the user name/password against the locally cached credentials? The connection often drops and the application needs to keep running.
Also I can't turn on Anonymous Authentication as we want to sign in users without providing credentials.
Any suggestions appreciated.
Thank you
It was due to calling (while off the network)
User.IsInRole(role)
We have custom role management, so removing base.IsInRole on our custom WindowsPrincipal solved this issue.
After doing research I thought that it actually has to be on the network, but to keep using cached credentials you don't have to be, just do not try to fetch any user related information.

delegation of authentication fails when opening web application from another network

I've been developing a web application calling an authenticated web service located on another server through the use of delegation of authentication and Kerberos. Everything is working fine when the user authenticates through a browser/desktop located on the same network as the server (Intranet context). When the desktop is on another network than the servers (ex: from Internet), I get prompted for credentials, which is expected. After that the web services server returns "The remote server returned an error: (401) Unauthorized." message. This happens even if I add my web application to the "intranet" or "trusted site" Security Zone in Internet Options, in Internet Explorer (11). I also tried with Chrome but same result. I don't understand what creates that error. I expected the behaviors to be the same on both networks. Maybe someone has an idea for the cause of that behavior?
Attached is a diagram to help clarify the context.
The reason it cannot work is that the connection falls back to NTLM instead of using Kerberos. Therefore, delegation of authentication is not possible.

How can I fix the Kerberos double-hop issue?

I'm having some trouble calling a web service from within a web application and I was hoping someone here might be able to help. From what I can tell, this seems to have something to do with the Kerberos double-hop issue. However, if it is, I'm not sure what to do to actually fix the problem. To make things harder, I don't have the proper permissions to make changes to Active Directory accounts, so I need to know what to ask for when requesting changes. In my situation, I need to pass the credentials (Integrated Windows Authentication) from a web application onto a backend web service so that the web service runs under the proper user context.
Here's my exact issue:
This works
This doesn't work
The only difference between the working scenario and the non-working scenario is that the working scenario is running the application on localhost (whether a developer's PC or on the server in question) and the non-working example is running on another machine. The code between both scenarios is exactly the same.
What I've tried
Adding an SPN to the domain account that runs the app pool for each server setspn -a http/server1 DOMAIN\account
Different methods of impersonation
Removing the impersonation code using(...) and executing the web service call as the app pool account. This works as expected.
Does anyone have any idea on what I might be able to do in order to fix this problem?
The intermediate server must be trusted for delegation. Otherwise no credential will be delegated and the intermediate server cannot impersonate the original client.
More often than not the reason is that Server 1 does not pass a delegation token to Server 2. So when Server 2 tries to use that authentication ticket to go somewhere else (probably a SQL server) it fails.
You should set the impersonation level for the WCF call
ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Delegation
http://msdn.microsoft.com/en-us/library/system.servicemodel.security.windowsclientcredential.allowedimpersonationlevel.aspx

Classic ASP Impersonation problem on IIS7 Windows 2008 server

I am trying to write to a file on a server (web05) from a classic asp site running on Windows 2008 serer on IIS7 (webadmin). This fails and web05 logs an anonymous logon attempt during the course of the save operation.
Webadmin's site is running on an app pool in classic mode with a domain user as the process account. The process account has rights to "Trust this user for delegation to any service (Kerberos only)". The same applies for the web05 and webadmin servers.
The site is using Windows Authentication and the idea is that when I log on the site with my domain user, the rights of my user should define what I am allowed to do in the context of the IIS site. If I turn on Basic Authentication, everything works fine.
I have also used setspn.exe to add an SPN for the URL. If I type setspn.exe -L webadmin, I get:
HTTP/webadmin.companyname.com
TERMSRV/webadmin
TERMSRV/webadmin.companypub.local
HOST/webadmin
HOST/webadmin.companypub.local
So from what I understand the SPNs are set up correctly.
If I run processmonitor on webadmin while the save operation is executed, it says that the process is indeed impersonating my domain user - but getting "Access denied" (and as I said before, web05 logs an anonymous logon attempt).
Any idea what causes this?
Kind regards,
Simon
It sounds to me like you're a little confused over impersonation. The process isn't impersonating the domain user account its simply running as that user. There is a difference.
When a request arrives into ASP it will then impersonate a user and the thread handling the request will be running under the security token of the impersonated user. Its quite possible to have the same process impersonating multiple different users in multiple threads. In most cases where the anonymous user access is enabled this user is the Guest level IUSR account. Its most likely that its under this user your code is attempting and failing to run.
However if anonymous is turned off for the resource being accessed or the IUSR account does not have access to the resource then the a 401 response is sent back, with some indication of what authentication protocols it will accept. The browser may then attempt to authenticate the connection using either the current users credentials or request some credentials from the user.
You don't specify exactly how you are attempting to save file. Its worth pointing out couple of things though.
ASP code exection which may subsequently result in an access denied will not use the above mechanism to try to resolve the user.
Once a connection is authenticated it often continues to be re-used for subsequent requests (which is counter-intuative to the knowledge the HTTP is a "connection-less" protocol).
I am trying to clean up my previous questions. This answer is not sufficient to answer the question above, but I concluded that it is better to provide some insight than none. If op disagrees, please take necessary action.
This is a way back - but I recall wanting to run kerberos authentication on this app. The problem turned out to be that I tried to do kerberos outside the firewall. The app would work fine within the domain and firewall of the server's home domain but failed whenever requests came from outside.
I did a lot of chatting with an Irish technician in Microsoft, and he taught me a little about the limitations when using Kerberos. The reason I wanted to use Kerberos was that I didn't like the thought of Basic Windows authentication being unencrypted.
Good luck with your Kerberos quest :-)
I ran into this same issue and it turned out to be a simple change to the application pool. If enable 32-bit applications is set to FALSE then I recieved a prompt to login to the machine. Setting this value to true fixed the issue.

How do I tell which account is trying to access an ASP.NET web service?

I'm getting a 401 (access denied) calling a method on an internal web service. I'm calling it from an ASP.NET page on our company intranet. I've checked all the configuration and it should be using integrated security with an account that has access to that service, but I'm trying to figure out how to confirm which account it's connecting under. Unfortunately I can't debug the code on the production network. In our dev environment everything is working fine. I know there has to be a difference in the settings, but I'm at a loss with where to start. Any recommendations?
Have you looked in the IIS logs?
I would also recommend looking in the Security event log on the server for authentication failures. You should find a footprint of the failed authorisation attempt here. Be warned though - it is not unusual to get 10s of security events a second, so ideally you need to be able to access the event log as the requests are failing.
If you do not specify which credentials to use in your ASP.NET page when you instantiate the web service then I believe it defaults to NT_Authority\Anonymous.
If you're using System.Net.CredentialCache then your web service needs to be in a trusted domain, accessed over HTTPS and using either NTLM, Kerberos or Digest Auth otherwise it does not pass the credentials from the cache.
http://msdn.microsoft.com/en-us/library/system.net.credentialcache.defaultcredentials.aspx
http://msdn.microsoft.com/en-us/library/system.net.credentialcache.defaultnetworkcredentials.aspx
http://msdn.microsoft.com/en-us/library/system.net.credentialcache.defaultcredentials.aspx
Perhaps the production server uses a different user for its application pool than your dev environment? I once spent a day figuring that one out. Another option would be the (lack of) impersonation in the web.config

Resources