Try our conversational search powered by Generative AI!

ksjoberg
Jul 17, 2014
  8874
(4 votes)

Troubleshooting a problem with POST-requests in an environment with mixed NTLM and Forms authentication

In most Intranet solutions there’s a desire to make the users of the Intranet be able to use the Intranet without logging in. This can be done in many ways, but this blog post takes one particular solution and takes a closer look at it.
The partner had created a special FormsAuthentication module to replace the standard ASP.NET FormsAuthentication module. Using some reflection it piggybacked on the OnEnter and OnLeave private method implementations in that module to copy the normal FormsAuthentication behavior that redirects the user to a login page if the authentication ticket is not among the user’s cookies.

As a part of the setup of this module, two virtual paths had been created whose requests were captured by a special module. One of those paths was reconfigured using a web.config location element to add a authentication element that specified that that path expects the user to authenticate using Windows authentication.

The two paths were /WindowsLogin (configured with Windows authentication) and /Authenticate (configured using Forms authentication).

When the user was decided to be unauthenticated, the normal behavior of the Forms authentication module is to redirect the user to the login page. In this case it was configured to be /WindowsLogin (see loginUrl in the documentation). When that Url was successfully executed, the server side code would issue a forms authentication ticket with the credentials the user (or web browser) supplied. In the Intranet zone, Internet Explorer attempts an NTLM/Negotiate based authentication automatically, so no login is required. On failure, the normal forms authentication screen would present via a redirect to /Authenticate.

The solution mostly worked, but there were some problems in critical areas of the web site. Notably, postback-requests would occasionally render as non-postbacks. This is particularly bad when that postback contain information the user has spent much time creating. Typical case would be the user creating a new page or editing an existing page. After about one minute from the moment the page was downloaded, the save action would simply reload the page.

After some troubleshooting we concluded that the problem occurred because Internet Explorer believed that all pages on the intranet was protected with NTLM/Negotiate. It basically means that at each new connection made, ​​the client is required to authenticate itself. HTTP Keep-alives allows a web browser to establish a single connection and then reuse it until the connection is closed. The idle timeout of keep alives in this environment was one minute.

It is done by a (simplified below) four step process:

  1. The browser sends a request for the protected resource, eg / episerver.
  2. The server responds 401 Unauthorized and provides a "NTLM challenge" to the browser.
  3. The browser computes a response to the server's given challenge and sends the response along with a new request for the protected resource.
  4. The server answers confirms the answer to the authentication and if it went well the server responds with 200 OK and process requests in full.

In step 1, the browser omits to send the POST data (the data entered in form fields on the page), as it is certain that the server will reply "401 Unauthenticated" and ignore the POST data so it would be pointless to send it. In step 3, the browser includes the POST data.

Since the server and the browser has different ideas of ​​what resources are protected with NTLM/Negotiate, this creates a conflict. The browser a expects a 401 response to resources protected by NTLM where the connection is not yet authenticated, but the server satisfies itself with the Forms Authentication ticket in the set of cookies sent by the client. This allows the server to act on a POST request without receiving the POST data (as it is omitted in step 1 of NTLM authentication), and then we will get the effect we saw - the "reloaded page" with emptied of form data.

The solution was to add the NTLM / Negotiate protected resources in a virtual directory, eg /AuthenticationSubSystem/WindowsLogin, so that the browser think it's just the resources in that directory that requires NTLM/Negotiate authentication. The other resources are handled by the browser as usual. Previously the NTLM protected resources resided directly in the root which made the browser assume that other resources under the root and its subdirectories are protected with NTLM.

Jul 17, 2014

Comments

Please login to comment.
Latest blogs
Solving the mystery of high memory usage

Sometimes, my work is easy, the problem could be resolved with one look (when I’m lucky enough to look at where it needs to be looked, just like th...

Quan Mai | Apr 22, 2024 | Syndicated blog

Search & Navigation reporting improvements

From version 16.1.0 there are some updates on the statistics pages: Add pagination to search phrase list Allows choosing a custom date range to get...

Phong | Apr 22, 2024

Optimizely and the never-ending story of the missing globe!

I've worked with Optimizely CMS for 14 years, and there are two things I'm obsessed with: Link validation and the globe that keeps disappearing on...

Tomas Hensrud Gulla | Apr 18, 2024 | Syndicated blog

Visitor Groups Usage Report For Optimizely CMS 12

This add-on offers detailed information on how visitor groups are used and how effective they are within Optimizely CMS. Editors can monitor and...

Adnan Zameer | Apr 18, 2024 | Syndicated blog