CARVIEW |
April 13, 2005
ASP.NET NTLM Authentication - is it worth it?
At work, we have the luxury of assuming that everyone's on an intranet. So when it comes to identity management on our ASP.NET websites, NTLM authentication is the go-to solution. Why trouble the user with Yet Another Login Dialog when you can leverage the built in NTLM functionality of IIS and Internet Explorer? Just reach in and grab one of these Request.ServerVariables
passed in through the HTTP headers:
LOGON_USER = HOMESERVERJeff AUTH_USER = HOMESERVERJeff REMOTE_USER = HOMESERVERJeff
I don't pretend to understand the subtle difference between these three fields; this CodeProject article has some hints. At any rate, at least one of them will contain the domainusername of the user accessing our web page. And it's free-- as long as you define "free" as three browser round trips:
GET /WebApplication1/WebForm2.aspx HTTP/1.1 User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322) Host: homeserver Connection: Keep-Alive HTTP/1.1 401 Unauthorized Content-Length: 1656 Content-Type: text/html Server: Microsoft-IIS/6.0 WWW-Authenticate: NTLM WWW-Authenticate: Basic realm="homeserver" Date: Thu, 14 Apr 2005 02:59:26 GMT GET /WebApplication1/WebForm2.aspx HTTP/1.1 User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322) Host: homeserver Connection: Keep-Alive Authorization: NTLM TlRMTVNTUAABAAAAB7IIogQABAAwAAAACAAIACgAAAAFASgKAAAAD1dVTVBVUzY0SE9NRQ= = HTTP/1.1 401 Unauthorized Content-Length: 1539 Content-Type: text/html Server: Microsoft-IIS/6.0 WWW-Authenticate: NTLM TlRMTVNTUAACAAAAFAAUADgAAAAFgoqiMixeuxRDQq8AAAAAAAAAAKgAqABMAAAABQLO DgAAAA9IAE8ATQBFAFMARQBSAFYARQBSAAIAFABIAE8ATQBFAFMARQBSAFYARQBSAAEAFABIAE8ATQBFAFMARQBSAFY ARQBSAAQANgBoAG8AbQBlAHMAZQByAHYAZQByAC4AYwBvAGQAaQBuAGcAaABvAHIAcgBvAHIALgBjAG8AbQADADYAaA BvAG0AZQBzAGUAcgB2AGUAcgAuAGMAbwBkAGkAbgBnAGgAbwByAHIAbwByAC4AYwBvAG0AAAAAAA== Date: Thu, 14 Apr 2005 02:59:26 GMT GET /WebApplication1/WebForm2.aspx HTTP/1.1 User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322) Host: homeserver Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGwAAAAYABgAhAAAAAwADABIAAAACAAIAFQAAAAQABAAXAAAAAA AAACcAAAABYKIogUBKAoAAAAPVwBVAE0AUABVAFMASgBlAGYAZgBXAFUATQBQAFUAUwA2ADQAhUEDudJHhNcAAAAAAA AAAAAAAAAAAAAA74hHe6W7Di69Hgo553hEc7OZLaIizpzh HTTP/1.1 200 OK Cache-Control: private Date: Thu, 14 Apr 2005 02:59:26 GMT Content-Type: text/html; charset=utf-8 Server: Microsoft-IIS/6.0 Set-Cookie: ASP.NET_SessionId=0nispyqogdrmpjyxnzxe2b55; path=/ Content-Encoding: gzip Vary: Accept-Encoding Transfer-Encoding: chunked
This is the classic challenge-response handshaking sequence that Eric Lippert described in his recent entry You Want Salt With That? Part Four: Challenge-Response. And it really does work; no passwords are ever transmitted, and yet we know exactly who the user is.
Although it is delightfully easy to implement, NTLM authentication carries a hefty performance cost. How hefty? The last time I benchmarked it, almost 1000ms per request, compared to under 20ms for anonymous requests. And there are a lot of other caveats, too:
- IE will only send NTLM credentials automatically to sites it deems in the "Intranet Zone". Websites in any other security zone will pop up a login prompt.
- NTLM credentials typically don't make it through a proxy, so you must enable Basic authentication in addition to NTLM, otherwise you risk permanently blocking a chunk of your userbase from your application. And Basic authentication is, uh, unsecure. Like "barely better than plain text" unsecure.
- If you have users coming in from multiple domains, you must set authentication to use "all domains" via the backslash trick. This leads to another problem: if users have accounts with the same name in other domains, those accounts will take priority.
- All new folders in IIS default to Integrated and Anonymous authentication. This seems contradictory; will NTLM be used, or will everyone map to the anonymous account? The Windows Server 2003 Directory Security dialog clarifies this at long last: anonymous will be used unless NTFS access control lists are specified on that folder. And how do we know that, exactly?
- It's also possible to control authentication via ASP.NET's <authorization> Web.config section. But this only works if the IIS Directory Security settings are left at their default of Integrated and Anonymous. IIS settings will overrule whatever you specify in Web.config.
- Integrated authentication checks the user's Windows account at the time they access your website. If there is any problem with a given user's Windows account, they won't be able to access your website. Is that user temporarily locked out? Password expired? Must change password at next logon? Are there network problems preventing your webserver from communicating with other domains? This inevitably results in a lot of user complaints that "I can't get to your intranet site, but all the others work-- what's wrong with your site?" Those other sites don't use NTLM. And I am put in the uncomfortable position of troubleshooting people's Windows accounts so they can get to our website.
I used to be a big believer in NTLM authentication in ASP.NET. However, after living with it for the last two years, I'm starting to wonder if we wouldn't all be better off with Yet Another Login Dialog.
I'm in the process of moving new part of our intranet site from apache/php to asp.net, but one of the requirement is to authenticate users in LDAP. But the real challenge is that IIS doesn't support LDAP and there is no free/working ISAPI extension for this. Of course I can write HttpModule but this requires to disable all IIS authentication methods, and this disables debugging in Visual Studio.
How can I convince other developers to move to this platform wihout debugging. That was one of advantages I use to force the change in our team.
Im starting to hate IIS authentication support.
seer on April 14, 2005 01:46 AMI wasn't aware of the NTLM authentication performance impact but one possibility would be to use Kerberos Authentication as opposed to NTLM. Generally speaking kerberos authentication is faster and "may" provide some cross platform authentication, although I can't personally speak to how compatible kerberos domain tickets generated from w2k3 AD are with *nix implementations but it might be a possibliity. Another advantage is that it supports authentication delegation which is very usefull for end-end validation in multi-tiered applications(if thats a requirement on your application). I'd be curious on people's experience with kerberos as I don't see it very often.
Josh C on April 14, 2005 08:48 AM> Of course I can write HttpModule but this requires to disable all IIS authentication methods, and this disables debugging in Visual Studio.
Ah, right-- because Integrated is required for debugging. That's a tough one.. I'd be interested to hear what you actually end up doing.
> one possibility would be to use Kerberos Authentication as opposed to NTLM
Has anyone done this? I need to research that solution.
Jeff Atwood on April 14, 2005 10:34 AMWhy not compromise? Do the traditional login checks as if you were writing the logic yourself, and just cheat on the login page:
On every page, check for a specific cookie and if it does not exist (or has expired or is otherwise bad), redirect the browser to /ntlmLogin/[originalUrlHere], or save it in the session, whatever.
Pretend that the login page is the traditional sort - it would ask for a username/password/whatever, and if the user is authenticated it would send over the magic cookie and forward the user back to the original page.
So... why can't that login page (and only that login page) support NTLM authentication? Better yet, have a fallback so that if there's an authentication failure it just goes to a traditional username/password page rather than an "access denied" page (or not - your site, your requirements, but this would open up access possibilities for more obscure clients (or faux-clients)).
That way you have the massive NTLM overhead at most once, everything stays at least as secure as it would be in a traditionally secured site, and you've still achieved single-sign-on.
Or am I missing something?
Richard on April 14, 2005 12:27 PMRichard, you're right, that works. Actually, we've got that implemented in my current project, using the Application_AuthenticateRequest handler in Global.asax. Using Global.asax obviates the need for an HttpModule as "seer" suggested above.
One difference between what Richard suggested and what we have is that there is no login page -- the first request to any page in the app will force NTLM authentication. But then the response to that first request will set a FormsAuthentication cookie, which is used for all future requests. Works great in practice, and it's not too hard to code up.
One gotcha with this-- in IIS manager you have to make sure to enable both Windows Integrated Authentication and Anonymous Access (names from my imperfect memory...)
Brian Reischl on April 15, 2005 12:18 PMBrian, that's a great tip. We are using a variant of this technique -- eg, do the expensive auth once, and in doing so generate a ticket valid for the duration of the user's website visit.
Jeff Atwood on April 15, 2005 12:52 PMYou could use www.KeepAliveForever.com to keep your site alive. It is a free resource that seems to work really well.
John Hampton on March 13, 2006 02:12 AMI'll have to check out whether this solution can work for me as i seem to be having a similar problem. Thanks for the info!
Tom Tom on July 10, 2007 05:33 AMGood article; for the sake of completeness, here's a Technical Artical of an implementation (with an installer that will install to the running website on IIS) that has a fallback mechanism where you can use a secondary authentication mechanism (Forms authentication) if NTLM is not available from the UA (because of firewalls, no domain account)
Mixing Forms and Windows Security in ASP.NET
https://msdn2.microsoft.com/en-us/library/ms972958.aspx
Hello!
I have a related issue you huys may know have to resolve.
There's a website using NTLM auth that we are trying to login to.
On a standard internet connection this is no problem. We put in the prompted for the username and password, we put them in and they are accepted.
If we try and do the same in the office, our windows/NTLM domain, it sometimes gives us access but most of the time tells us that access is denied!
I believe that this is due to the external webserver thinking that we are authenticating as mydomain\username instead of extwebsite\username.
Any thoughts whether this is correct?
Is there any work around for this?
At the moment we're using a proxy server but there has to be someway for the external webserver to just see us as authenticating as website\username. This is what it must be doing when at home on the internet(?).
Any advice would be very much appreciated!
Thanks!
Asher.
Asher on January 31, 2008 05:37 AMAsher:
Your issue is with IE security zones; the site is being detected as in the intranet zone, and so it automatically sends your current credentials (and thus, no prompt is shown).
You can fix that by adding the server to your Internet zone, or turning off the security setting for automatically sending credentials to intranet servers.
Kit Grose on February 15, 2009 10:49 PMContent (c) 2009 Jeff Atwood. Logo image used with permission of the author. (c) 1993 Steven C. McConnell. All Rights Reserved. |