10

I'm developing a C# MVC application and I can't seem to get the Authentication and Session timeouts to synchronize. I have a basic Forms Authentication setup and some limited session values. I set the Authentication timeout less than the session (28 minutes vs 30) but running against the development web server, the session will be wiped on a restart of the server but the authentication sticks around. I'm assuming that the authentication is being stored in a cookie that obviously survives the server restart.

<authentication mode="Forms" >
  <forms loginUrl="~/Account/Login" timeout="28" />
</authentication>
<sessionState timeout="30" />

I think I want to force the the authentication to timeout if Session is null, to then force a login.

Is that what I actually want to do? If so how and where do I do this?

If not, what is the proper way to handle this?

EDIT

For more of a perspective I also posted this question for this same project: Login as... best practices?

Community
  • 1
  • 1
Josh Russo
  • 3,080
  • 2
  • 41
  • 62

2 Answers2

14

I found my answer. Override the Authorize attribute. This seems like the most elegant approach:

public class AuthorizeWithSessionAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (httpContext.Session == null || httpContext.Session["CurrentUser"] == null)
            return false;

        return base.AuthorizeCore(httpContext);
    }

}
Josh Russo
  • 3,080
  • 2
  • 41
  • 62
6

You could handle this in global.asax with PreRequestHandlerExecute event handler

protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
    {
        //Check if user is authenticated
        HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
        if (authCookie != null)
        {
            FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
            if (!authTicket.Expired)
            {
                if (Session["XYZ"] == null)
                {
                    //Session is null, redirect to login page
                    FormsAuthentication.SignOut();
                    Response.Redirect(FormsAuthentication.LoginUrl, true);
                    return;
                }
            }
        }
    }

Or, you could write a Httpmodule and implement context_AuthenticateRequest to check if session exists and handle the request accordingly.

Hope that helps.

Edit by Valamas

See answer https://stackoverflow.com/a/1446575/511438 for help with the session error.

Community
  • 1
  • 1
vindh123
  • 144
  • 1
  • 1
  • 11
  • I think this is what I was looking for. Thanks! I will let you know if it actually solves my problem. – Josh Russo Sep 05 '12 at 14:38
  • Nope, no dice. "Session state is not available in this context." – Josh Russo Sep 05 '12 at 14:42
  • I will try a Httpmodule later and let you know – Josh Russo Sep 05 '12 at 16:28
  • Session is not always loaded for content pages such as image files, CSS, js etc. You probably want to implement IRequiresSessionState in HTTPModule. http://stackoverflow.com/questions/1375627/irequiressessionstate-how-do-i-use-it – vindh123 Sep 05 '12 at 20:37