I have a control that i've written that has a javascript component and a web service component. The problem i'm having is that the javascript is set to do:
setInterval(this._checkAlertsHandler, this._messageCheckInterval * 1000);
This calls a function which makes a webservice call like so:
Alert.SiteAlertService.GetAlerts(this._receivedAlertsHandler, this._errorReceivedAlertsHandler);
So this is using the web service javascript proxy methods to access the web service. The issue is that our application has forms authentication and a timeout value, so if the user is idle for too long it will log them out.
My webservice call apparently sends the cookie which includes the session and the forms authentication key to the web service. The asp.net webservice then automatically renews the session AND the forms authentication. Everytime the javascript hits the web service it basically keeps the user alive. I do not want this behavior, this should just circumvent that, so that even though this js is hitting the web service to check for new messages, if the user hasn't done a postback on our application (and is effectively idle) it will still log them out. This isn't happening :(
What i would like to happen is this interval call to the web service does not renew any authentication (the session renewal i can get around by using an application level variable with dictionary key/value for the users session id, so i dont have to use any session level variables).
How do i do this / change my web service / or control to work like the way i want it?
I'm working on different approaches to this as well. One way I'm doing it is by adding this to the Ajax service endpoint:
// Hide the cookie so this call doesn't extend the user's ticket
HttpContext ctx = HttpContext.Current;
ctx.Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
This way you can negate an Auth Ticket renewal, sine the updated cookie will never make it back to the client.
If you have multiple Ajax endpoints that you want to exclude, a module can be implemented to identify those endpoints and include the code to remove the cookie from the response.
@RyanW provided the answer I needed so here's my implementation for MVC using an attribute just to keep things DRY.
using System.Web.Mvc;
using System.Web.Security;
namespace Your.Web.Attributes
{
public class RemoveAuthCookieAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
filterContext.HttpContext.Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
base.OnActionExecuted(filterContext);
}
}
}
Implementation:
[RemoveAuthCookie]
public ActionResult PollMe()
{
return View();
}
You could exclude your webservice from forms authentication:
<location path="yourwebservice.asmx">
<system.web>
<authorization>
<allow users="?"/>
<authorization>
</system.web>
</location>
But you probably need the information about the user, so you could configure the webservice to use forms authentication, but deactivate SlidingExpiration
:
<location path="yourwebservice.asmx">
<system.web>
<authentication mode="Forms">
<forms slidingExpiration="false"></forms>
</authentication>
</system.web>
</location>
Be sure to test what happens if the forms cookie is expired. Maybe you'll have to redefine the loginurl, too.
Could you put your webservice asmx file into its own separate project/solution/application?
That way it should use a different session id to your main application.