Mathew Alden
Mathew Alden

Reputation: 1680

NTLM authentication doesn't work for JS files unless Fiddler is running

I am running an ASP.NET 4 app in IIS using NTLM (Windows) Authentication. All other authentication schemes are disabled. I am able to authenticate to the server successfully. However, even after successfully authenticating, the server (under certain circumstances explained below) still returns a 401 Unauthorized error when I request Javascript files. Why am I unauthorized to download JS files?

Granted, I don't completely understand how NTLM works, but I expect something like the following to happen when I request a protected resource:

  1. I make a request to localhost:444 (yes, this is the correct port)
  2. I am not authenticated, so IIS returns a 401 to my web browser.
  3. My web browser understands that it must provide me with a popup in which to enter my username and password. I do so.
  4. The browser and IIS perform the NTLM auth flow. (tbh, I don't know the details of this.) Authentication is successful. The browser understands to re-request my original request from Step 1.
  5. IIS returns index.html.
  6. Index.html references a CSS file and some JS files. The browser requests these files.
  7. IIS returns these files.

This desired functionality is working... usually. When I'm accessing the site from Firefox, or Chrome 78, or Chrome 83, everything works as expected. However, when I access the site using Chrome 70, the following happens instead:

  1. Index.html references a CSS file and some JS files. The browser requests these files.
  2. IIS returns the CSS file, but returns a 401 error for the JS file.

Then however, when I turned on Fiddler (and configured it to decrypt https, because I've been using https) Chrome 70 started behaving correctly, just like Firefox and Chrome 78 and Chrome 83 are. I turned Fiddler off again, and I got the same error (on my JS file) again.

Does anyone have any idea what the issue is?

Thanks!

Upvotes: 0

Views: 499

Answers (1)

Mathew Alden
Mathew Alden

Reputation: 1680

The issue was not with the authentication; the authentication was working correctly.

The issue was with Angular 8/9 and Chome 70. I happened across this post which helped me discover this forum thread which (sortof) explains the issue.

Turns out, Angular 8 changed the way the the index.html formats its script tag. In Angular 8+, the tag makes use of JS modules and such, and includes a fall-back for browsers that don't support JS modules. However, Chrome 70 (and possibly others) seems to support JS modules poorly (I don't understand the exact nuances of what Chrome 70 does and doesn't do). Therefore, instead of using the fall-back for browsers that don't support JS modules, Chrome 70 seems to have made a malformed request for the JS files. Specifically, Chrome 70 requested the JS files, but requested their MIME type to be "text/plain" instead of "text/javascript". When IIS received this (assumedly) malformed request, it returned a 401 error. (I would've thought it would return a 400 error, but whatever.)

I don't know why turning on Fiddler fixed the issue. Maybe Fiddler was somehow changing the (assumedly) malformed headers to be correct again? I don't know.

The solution is easy - in your tsconfig.json file, simply set the target to "es5" instead of "es2015" (or whatever else is the default in the future). Compiling to es5 simply doesn't use the features that confuse Chrome 70.

Upvotes: 1

Related Questions