Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forms Authentication - loginUrl page executed for each request (Chrome only)

I think I've pared this down as far as I can. It happens only when using Forms Authentication and only seems to work in IE. So far, I've found that both Chrome and Firefox cause the issue. I have a very simple ASP page that increments a counter (stored in a session variable) on each page load. The page is named test.asp and appears in my web root. Here are the contents:

<%
    ' Write the last value (obviously blank the first time)...
    Response.Write "Last Num: " & Session("Num") &  "<br>"

    ' Increment the counter...
    Session("Num") = Session("Num") + 1

    ' Show the number we just saved...
    Response.Write "This Num: " & Session("Num") & "<br>"

    ' Throw the session ID out there, too, to make sure it's consistent...
    Response.Write "Session ID: " & Session.SessionID
%>

<form method="post" action="test.asp">
    <input type="submit" value="Submit">
</form>

And I've stripped down my web.config as much as possible while still reproducing the issue. Here are its contents:

<configuration>
    <system.webServer>  
        <modules runAllManagedModulesForAllRequests="true" />
    </system.webServer>
    <system.web>
        <authorization>         
            <deny users="?" />          
            <allow users="*" />         
        </authorization>
        <authentication mode="Forms">
            <forms loginUrl="test.asp" />
        </authentication>
    </system.web>
</configuration>

Pretty basic stuff here. I've set test.asp as the "login" page and enabled runAllManagedModulesForAllRequests. Things work as expected. All requests are redirected to test.asp, as you'd expect. And test.asp loads fine, except it for what happens next...

Here's how the page appears in IE (v11), Chrome (v44), and Firefox (v39) when loading initially and after submitting:

Internet Explorer 11:

enter image description here enter image description here

Google Chrome 44:

enter image description here enter image description here

Mozilla Firefox 39:

enter image description here enter image description here

When I click [Submit], I'm obviously expecting the Last Num value to be equal to the previous This Num. But that only happens in IE. In Chrome, it seems to be doing an extra increment. And in Firefox, it seems to be doing two! To make things more confusing, after that initial submission, Firefox properly increments by 1 each time. Chrome, however, continues to double-increment with each submission.

These are default browser installations. No added extensions or special configurations. Cookies are enabled in all three browsers (the default). I can see the ASPSESSIONID cookie using the developer tools of each browser. And, as you can see in the screenshots, the Session ID is created on page load and stays consistent throughout the session.

If I continue submitting, the results are the same. IE continues to work properly. The other browsers continue to double or triple increment.

Anyone seen this issue before? Or see where I may have gone wrong here? I've tried specifying cookieless="UseCookies" in the <forms> section of the web.config as well.

Edit 1 - Testing Elsewhere:

All of my testing to this point has been on my local PC: Windows 7 64-bit with IIS 7.5. Today, I connected to my eventual test server -- a Windows Server 2008 R2 box, also with IIS 7.5 -- and I get the same results there with my test page.

Edit 2 - loginUrl-related?

Using a new page, test2.asp, with the same content (and given explicit anon access via a <location> element in my web.config) works fine. So it seems to be loginUrl related? Maybe with every page request, it's calling the loginUrl page behind the scenes? But again, with some connection to Chrome/Firefox...

Edit 3 - More Proof:

I decided to log the value of This Num each time the page is executed. Here's what I'm seeing:

Internet Explorer:

8/4/2015 11:52:07 AM, Num=[1]    Initial page load. One execution.
-----------------------------
8/4/2015 11:52:11 AM, Num=[2]    All future submissions run once.
8/4/2015 11:52:16 AM, Num=[3]
8/4/2015 11:52:20 AM, Num=[4]

Chrome:

8/4/2015 11:34:58 AM, Num=[1]    I get 2 executions on initial page load.     
8/4/2015 11:35:00 AM, Num=[2]    First execution (Num=1) appears in browser.
-----------------------------
8/4/2015 11:35:29 AM, Num=[3]    Every submit causes page to run twice.
8/4/2015 11:35:29 AM, Num=[4]
-----------------------------
8/4/2015 11:35:49 AM, Num=[5]
8/4/2015 11:35:49 AM, Num=[6]

Firefox:

8/4/2015 11:36:25 AM, Num=[1]    I get 3 executions on initial page load.
8/4/2015 11:36:25 AM, Num=[2]    The first execution (Num=1) is the page
8/4/2015 11:36:25 AM, Num=[3]    I see in the browser.
-----------------------------
8/4/2015 11:36:34 AM, Num=[4]    All future submissions run once.
8/4/2015 11:36:43 AM, Num=[5]
8/4/2015 11:36:48 AM, Num=[6]
8/4/2015 11:36:53 AM, Num=[7]

Edit 4 - loginUrl Page Called on Every Request:

It seems any type of page request is causing test.asp to execute behind the scenes, which increments the session variable. And that must be because it's the page identified by loginUrl for Forms Auth. Combining the tests I did under edits 2 and 3, I granted anon access to a new test page (test2.asp) that doesn't do anything special -- just loads a static page. Here it is:

<html><body>I'm test2.asp</body></html>

And then I monitored the log file that test.asp appends to when it runs. Every time I requested test2, I would get a new entry in the log. So every time I made a page request, test.asp runs in the background (and increments the session variable). Here's how the log looked after three requests to my test2 page:

8/4/2015 12:20:57 PM, Num=[3]
8/4/2015 12:21:07 PM, Num=[4]
8/4/2015 12:21:14 PM, Num=[5]

test2.asp doesn't do anything with the session variable (nor logging) but there's the proof. So, for some reason, on Chrome, it runs the loginUrl page with each request. I think I can consider that to be proven. Now I just need a solution!

like image 690
Bond Avatar asked Aug 03 '15 20:08

Bond


1 Answers

With the help of Fiddler, I was able to figure this out.

It seems both Chrome and Firefox make an additional request for your favicon.ico, whether or not you've specified that you're using one in your HTLM page. Internet Explorer, on the other hand, doesn't bother.

This was a problem for me for a few reasons:

  1. I didn't have one. I'd only just started my site and creating a favicon.ico was step 274.
  2. I'm using runAllManagedModulesForAllRequests, so requests for icons, like all content, runs through Forms Authentication.
  3. If you don't <link> to one and specify its location, Chrome and Firefox try to grab one from your web root. Forms Authentication (and my web.config) have my root locked down. The only file being served from my root is my loginUrl page.

Each time a request for favicon.ico was being made, Forms Authentication was disallowing it and redirecting the request to my loginUrl page, consequently causing my loginUrl page to be executed twice and screwing up my session values. The following Fiddler screenshots show the proof.

Chrome seems to request the icon on every page request: enter image description here

Whereas Firefox seems to request it twice initially, for some reason, but then gives up for subsequent requests:

enter image description here

So, the solution:

  1. Create a favicon.ico file and place it in your web root.
  2. Allow anonymous access to it via a <location> element in your root web.config.

    <location path="favicon.ico">
        <system.web>
            <authorization>
                <allow users="?" />
            </authorization> 
        </system.web>
    </location>
    

Alternatively (probably the preferred method, since you can designate the name and location):

  1. Create a favicon.ico file and place it in a public subfolder, like /img.
  2. <link> to it properly within your loginUrl page.

    <link rel="icon" href="/img/favicon.ico">
    
like image 51
Bond Avatar answered Oct 14 '22 04:10

Bond