title: ASP.NET 3.5 MVC1 - Users randomly unauthenticated/required to log back in
body: <p>We employ Out-of-Process SQL Session State, ASP.NET 3.5 MVC 1.0 and Forms Authentication using IIS 7.</p>
  
  <p>A user's session is correctly set on logon and will time out as expected, redirecting them to a special "Time out" login page.  The problem is that some (not all) users log in and are (from what I can tell) immediately unauthenticated and are required to log back in (i.e. redirected to the original "Login" page).</p>
  
  <p>Might anyone have an idea why our users are intermittently being kicked out?</p>
  
  <p>EDIT: I've since added logging on every Application_AuthenticateRequest event, I can tell you that before the user is booted out both the Auth ticket is authenticated, persistent and expires two days later and the request is also authenticated.  Upon arriving at the logon page the user is no longer authenticated.</p>
  
  <p>EDIT #2:  We've made some progress, it would appear as though users may be unauthenticated because this web app is looking for scripts and other content in the parent app for which users are not authenticated.  The original format for inclusion of these scripts is as follows:</p>
  
  <pre><code>&lt;script src="../../Scripts/MicrosoftAjax.js" type="text/javascript"&gt;&lt;/script&gt;
  </code></pre>
  
  <p>I have corrected it to:</p>
  
  <pre><code>&lt;script src="&lt;%= Url.Content("~/Scripts/MicrosoftAjax.js") %&gt;" type="text/javascript"&gt;&lt;/script&gt;
  </code></pre>
  
  <p><strong>ANSWER</strong>  The above changes to our script references in our .master pages resolved the issue.  It explicitly tells the app to look in the root folder of the current app.  Thank you to all who helped.  I wish I could have marked more than one as the answer!</p>
  
  <p>Below is our login Action:</p>
  
  <pre><code>    [AcceptVerbs(HttpVerbs.Post)]
      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings",
          Justification = "Needs to take same parameter type as Controller.Redirect()")]
      public virtual ActionResult LogOn(string userName, string password, string returnUrl)
      {
          if ((HttpContext.Current.User == null) || (!HttpContext.User.Identity.IsAuthenticated))
          {
            if (!ValidateLogOn(userName, password))
            {
                try
                {
                  return View();
                }
                catch (Exception ex)
                {
                  throw new Exception(string.Format("User validation failed at LogOn: {0}", ex.ToString()));
                }
            }
          }
  
          bool rememberMe = true;
  
          FormsAuth.SignIn(userName, rememberMe);
  
          Session["userName"] = userName;
  
          if (!String.IsNullOrEmpty(returnUrl))
          {
              try
              {
                  return Redirect(returnUrl);
              }
              catch (Exception ex)
              {
                  throw new Exception(string.Format("User redirect to returnUrl ({0}) failed: {1}", returnUrl, ex.ToString()));
              }
          }
          else
          {
              try
              {
                  return RedirectToAction("Index", "RodWebUI");
              }
              catch (Exception ex)
              {
                  throw new Exception(string.Format("User redirect to action: Index, controller: RodWebUi failed: {0}", ex.ToString()));
              }
          }
      }
  </code></pre>
  
  <p>Below is our timeoutlogon action:</p>
  
  <pre><code>    public virtual ActionResult TimeOutLogon()
      {
          try
          {
              FormsAuth.SignOut();
  
              ViewData["TimeoutMsg"] = "Session timed out. Please log back in.";
  
              return View();
          }
          catch (Exception ex)
          {
              throw new Exception(string.Format("Error with redirecting to TimeOutLogon: {0}", ex.ToString()));
          }
      }  
  </code></pre>
  
  <p>I've since added the following check to our global.asax to log the current status of the request and auth ticket.  Everything is authenticated and OK prior to being kicked back to LogOn.</p>
  
  <pre><code>    protected void Application_AuthenticateRequest(object sender, EventArgs e)
      {
          if (HttpContext.Current.User != null)
          {
              if (HttpContext.Current.User.Identity.IsAuthenticated)
              {
                  if (HttpContext.Current.User.Identity is FormsIdentity)
                  {
                      FormsIdentity identity = (FormsIdentity)HttpContext.Current.User.Identity;
  
                      FormsAuthenticationTicket ticket = identity.Ticket;
  
                      LogFunctionCall(HttpContext.Current.User.Identity.Name, "", "User Authentication Check", "", 
                                          string.Format("Auth ticket is expired: {0}, expiration date: {1}, is persistent: {2}, issued: {3}", 
                                          ticket.Expired, ticket.Expiration, ticket.IsPersistent, ticket.IssueDate), "", 0);
  
                      LogFunctionCall(HttpContext.Current.User.Identity.Name, "", "User Authentication Check Line #2", "", 
                                          string.Format("Raw URL: {0}, Request is authenticated: {1}", HttpContext.Current.Request.RawUrl, HttpContext.Current.Request.IsAuthenticated), "", 0);
                  }
              }
          }
      }
  </code></pre>