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...
Related
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.
I've gone too long just telling myself, well this just works so I'll treat it as a black box.
I can enable anonymous, forms, windows security, etc... But if I enable multiple of them on the same path/app, what does that mean? Do they all run? Does the most secure take the role of verification?
Is there a point to enabling anonymous and windows authentication?
Is there a way to step through the authentication process?
This article is for older versions for Windows Server, but the logic is the same
http://support.microsoft.com/kb/264921
When the browser makes a request, it always considers the first request to be Anonymous. Therefore, it does not send any credentials. If the server does not accept Anonymous or if the Anonymous user account set on the server does not have permissions to the file being requested, the IIS server responds with an "Access Denied" error message and sends a list of the authentication types that are supported by using one of the following scenarios:
If Windows Integrated is the only supported method (or if Anonymous fails), then the browser must support this method to communicate with the server. If this fails, the server does not try any of the other methods.
If Basic is the only supported method (or if Anonymous fails), then a dialog box appears in the to get the credentials, and then passes these to the server. It attempts to send the credentials up to three times. If these all fail, the browser does not connect to the server.
If both Basic and Windows Integrated are supported, the browser determines which method is used. If the browser supports Kerberos or Windows NT Challenge/Response, it uses this method. It does not fall back to Basic. If Windows NT Challenge/Response and Kerberos are not supported, the browser uses Basic, Digest. The order of precedence here is Basic, Digest.
Is there a way top specify the authentication timeout for an Asp.Net application using windows authentication?
In my scenario the user logged into Windows does not have permission to the web application so the browser prompts them for a different set of Active Directory credentials. Assuming they don't tick the "Remember my credentials" check box I'd like to be able to set how long the user will stay authenticated for.
This will not be possible from ASP.NET configuration.
As such, windows authentication may use Kerberos or NTLM. AFAIK, NTLM is connection based and connection life-time decides authentication scope. For kerberos, a time-bound token is issued. The token time-out is generally small (say few minutes) and is dependent upon the setup.
Perhaps you should explain the the specific need to set the windows authentication time-out (because typically, time-outs are designed to avoid replay attacks and underlying windows authentication as such take care of them so there is hardly any need to do something at application level).
I need to get the Windows domain name from Internet Explorer using classic asp (I could try it in another way if with classic asp it's not possible).
I need to do this in order to insert the domain name into a database row.
So again, in summary, I need to retrieve the Windows computer domain name from the Internet Explorer that is accessing to a particular webpage.
Any idea where I could find and example in order to do that?, is it possible?
Web browsers by default use the web protocols (think Http, Html, Ssl, etc.). By your username I know that you are familiar with the RFCs that define these protocols.
Windows networks use a different protocols. The Domain is a logical security boundary in Windows networks. Yes, in modern versions of Windows Domain security uses standard protocols like Kerberos.
The problem you'll have is that a web browser doesn't normally send extra information to a web server about the client. That would be a huge security problem. So, by default a web browser (even IE) would not volunteer any network security information in an Http request.
When your web server requires client authentication, the web browser then must provide more security information to the server. Depending on the type of authentication your web server requires, your browser will send different information. For instance, in Http Basic authentication, the browser will send a username and password.
To my knowledge, the best way to get Windows Network Domain information from a web browser is to force the browser to authenticate using Windows Authentication. This is a special authentication mode that Microsoft built that pushes Microsoft network security information over the standard Http protocol. However, in order for this to work:
Users must be running IE on Windows
Web server must be IIS on Windows
The client and server must have a Windows security relationship
IIS must be enabled for Windows Auth
There are many restrictions about the network path between the client and the server. Proxies and firewalls will typically prevent the IE Client from using windows authentication with IIS.
If you can live with this checklist, I think you will find the domain info in the one of the http headers. You may have to parse it out of the username which will be domain\user. But I'm sorry I don't remember the specifics. This should work even in classic ASP. More info on Windows Authentication is available at http://www.iis.net/ConfigReference/system.webServer/security/authentication/windowsAuthentication
http://msdn.microsoft.com/en-us/magazine/cc301387.aspx is about ASP.NET, but it says:
For a user authenticated using Windows
authentication, the name is of the
form domainname\username, where
domainname is the name of the domain
in which the user is registered (or
machine name if it's a local account
instead of a domain account), and
username is the user's name.
In Classic ASP, try Request.ServerVariables ("AUTH_USER") or Request.ServerVariables ("LOGON_USER")
One alternative to Windows Authentication is to use Basic Auth and force the user to login with their windows credentials as domain\user. This however presents other security issues and you should do this only over SSL. However, this technique will work over the Internet and doesn't require a security relationship between the client PC and the server. This would also work for non-IE browsers.
In case anyone happens to get the same problem, here is the solution I've implemented (pretty much what Michael Levy said).
You have to activate Integrated Windows Authentication in IIS: http://en.wikipedia.org/wiki/Integrated_Windows_Authentication.
You can read here how to do it: http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/5f8fe119-4095-4094-bba5-7dec361c7afe.mspx?mfr=true
After that you can use:
In Classic ASP Request.ServerVariables
("AUTH_USER") or
Request.ServerVariables ("LOGON_USER")
It seems to work also with other browsers, not only with IE.
Thanks again to Michael Levy to point me in the right direction.
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.