delegation of authentication fails when opening web application from another network - asp.net

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.

Related

Web services and Access Denied

I recently created a web service which all worked fine until I moved it from my local PC to our development server. I now get a HTTP status 401: Access Denied message when I try to connect from a small test website. I googled around and found the following code:
SoiisdevJobService.JobsService jService = new SoiisdevJobService.JobsService();
jService.Credentials = System.Net.CredentialCache.DefaultCredentials;
And it now works, but I'm not sure what this code actually does. Can someone explain it to me? I'm using IIS 6, Windows auth, and in my config I've set the auth mode to Windows and to deny non-authed users. In my small test app I've set the same in my config.
Why do I need to provide the code above? I expected this to just work.
It is because you have turned off access for non-authenticated users. See the quote below from the Microsoft website (http://support.microsoft.com/kb/811318/EN-US):
When Anonymous access authentication is turned off for the Web service
application, all the caller applications must provide the credentials
before making any request. By default, the Web service client proxy
does not inherit the credentials of the security context where the Web
service client application is running.

Cannot authorize with different server name

I have a web service running in IIS 6.0 on Windows 2003. It's authentication mode is Integrated Windows security (anonymous disabled), and authorization is done with Authorization Manager and an XML authorization store. My test user is a domain user (admin, actually) with membership in an authorized role.
I am testing this (for now) on the web server (localhost), and using (for now) Internet Explorer to access the web service (.asmx).
I can successfully open the web service (wsdl) page through localhost, like this:
http://localhost:8080/MyService/MyService.asmx
Using this url, integrated windows authentication succeeds (silently), and I am sucessfully authorized by AzMan to access the service. The same goes for the server name:
http://myserver:8080/MyService/MyService.asmx
Now I need to use the external host name (www.mysite.no) to access the service (this in order to get ssl to work with a certificate issued to that sitename). To do this, I add the host name to my HOSTS file, like this:
127.0.0.1 www.mysite.no
...then type this into IE:
http://www.mysite.no:8080/MyService/MyService.asmx
What happens then is that authorization fails. I get the IE/Windows login box and enter my correct credentials three times. Then I get a 401.1:
HTTP Error 401.1 - Unauthorized: Access is denied due to invalid credentials.
Internet Information Services (IIS)
How is authorization through AzMan influenced by the host name?
Edit: I have reason to believe AzMan has nothing to do with it - it seems to be the authentication that fails.
I have reproduced the problem on another server. The essence seems to be that accessing localhost via an entry in the local host file somehow messes up the integrated windows authentication between the browser and IIS.
I have worked around the problem, now my curiosity is all that's left...
Enable audit login failure auditing & check the security event log on the host.
1) On the webserver, go to Control Panel, Administrative Tools, Local Security Policy.
2) Go to local policies, audit policy. Add failure for 'audit logon events'.
3) Close the MMC. Open a command prompt and type gpupdate.
4) browse to http://www.mysite.no. You will get the error again.
5) Launch event viewer (control panel, admin tools, event viewer). Navigate to the security event log and look for the login failure(s).They shoudl tell you something descriptive, like 'the user has not been granted the specified logon type'. Unfortunately the login type itself is not descriptive; logon type 2 is interactive (locally), 3 is 'access this computer over the network', 5 is 'logon as a service' (NT service, not WCF service). The rights required can be granted in the local security policy.
Also, check to see if you have a proxy enabled in IE. If your traffic is being routed to the proxy, it is possible that the proxy does not support NTLM. Add the host as a proxy exception while you test using IE.
My first guess is that it's not the host name.
The first thing to do is narrow down the problem as there are a couple things that could be going wrong.
First set the IIS site to anonymous access, and make sure you can pull up the web service. That will verify that you're accessing the right IIS web site and it's truly narrowed down to an authorization problem.
Also, check the Application Pool credentials, and the security settings on the file folder containing the web service as these could be contributors.

ASP.net kerberos dropping down to NTLM sporadically

Background (just the relevant pieces):
We have a large intranet asp.net 2.0/3.5 app.
Web servers are Windows Server 2003 on an AD domain.
Clients are on Windows, IE 6-8.
Windows Authentication, with a custom principal created from the Windows Identity.
Web servers sit behind an F5 NLB which forwards the user to a specific web server. (The reason for this is a limitation w/ our company's F5 dealing w/ kerberos).
There are no system wide problems like dropping sessions, or timeouts, or overloaded servers, everything's running fine in general.
One piece of functionality requires delegation - we are connecting to a network file share as the authenticated user, using the Kerberos token given to us by the domain/web server.
SPNs, ACLs, etc, seem to be set up properly.
99.x percent of the time, it all works. The problem we're seeing is every now and again, on a refresh, the token drops from kerberos down to ntlm. I can see the login on the web server's event log showing one call getting this:
Logon Process: Kerberos
Authentication Package: Kerberos
And a subsequent call (usually after 10 or 20 page loads) getting this:
Logon Process: NtLmSsp
Authentication Package: NTLM
Anyone have any insight as to what might be making a subsequent postback sometimes go NTLM?
Thanks!
All the tools and techniques you need to identify the issue are in Troubleshooting Kerberos Errors. That document never failed me.
NTLM Fallback
You might find that the
security log recorded an event in
which logon occurred using NTLM when
it should have occurred using Kerberos
authentication.
Problem
There are two
situations in which this might happen:
- The first situation is where the
system attempts authentication using
the Kerberos protocol but it fails. As
a result, the system attempts to
authenticate using NTLM. Windows
Server 2003, Windows XP, and Windows
2000 use an algorithm called Negotiate
(SPNEGO) to negotiate which
authentication protocol is used.
Although the Kerberos protocol is the
default, if the default fails,
Negotiate will try NTLM.
- The second
situation is one in which a call to
Negotiate returns NTLM as the only
protocol available.
Confirmation
The
first situation will result in a
failed Kerberos authentication that
you can investigate by examining
errors in the event log or data
packets captured by Network Monitor.
Both investigation methods are
discussed later in this document...

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

Control a service on a remote server from IIS

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)

Resources