We use Out-of-Process SQL Session State, ASP.NET 3.5 MVC 1.0, and Form Authentication using IIS 7.
The user session is correctly configured when logging in and there will be a timeout, as expected, redirecting them to a special login page "Timeout". The problem is that some (not all) users are logged in and (from where I can tell) are not authenticated immediately, and you need to return to the system (that is, redirect to the original "Login" page).
Does anyone have an idea why our users periodically fail?
EDIT: since I added an entry to each Application_AuthenticateRequest event, I can tell you that before the user is loaded, both Auth tickets are authenticated, saved and expire after two days, and the request is also authenticated. Upon arrival to the login page, the user is no longer authenticated.
EDIT No. 2: We have made some progress, it seems that users may not be authenticated because this web application is looking for scripts and other content in the parent application for which users are not authenticated. The source format for including these scripts is as follows:
<script src="../../Scripts/MicrosoftAjax.js" type="text/javascript"></script>
I fixed it so that:
<script src="<%= Url.Content("~/Scripts/MicrosoftAjax.js") %>" type="text/javascript"></script>
ANSWER script .master . . , . , !
:
[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()));
}
}
}
timeoutlogon:
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()));
}
}
global.asax . , LogOn.
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);
}
}
}
}