Question about redirecting to a "session expired" page...

J

John Smith

This may sound trivial but I cannot figure out how to do this...
When a logged in user's session expires, I want that user redirected back to
the login page with a label that says "session expired". Sounds easy, eh?

First, am I correct in assuming that a session is totally separate from the
"AuthCookie" that gets set when you use the FormsAuthentication class? They
have nothing to do with each other, right? So, if my IIS application is set
to expire Sessions every 20 minutes, that has no affect on the AuthCookie
that I set to timeout every 18 minutes and vice-versa.

I just started playing around with <authentication> in my web application.
I had simply been using Session variables to track the session of a logged
in user with the following code that I would put at the top of each page. I
had to use try/catch because, if the session had expired, it would throw an
exception while trying to print the name. If the exception occured, that
means the session expired and it would redirect back to the login page. The
login page tests for the "j=session_timedout" in the querystring and will
display "Sorry, your session timed out!". No problem.

try {
lblSessionName.Text = Session["name"].ToString();
}
catch (Exception exp) {
Response.Redirect("login.aspx?j=session_timedout");
}

But I just started REALLY playing around with the built-in authentication
that .net has and I think its much nicer than what I was trying to do. I
have it now using Forms based authentication (web.config):

<authentication mode="Forms">
<forms loginUrl="/login.aspx" name=".FORMSAUTH" path="/"
protection="All" timeout="18" slidingExpiration="true" />
</authentication>

<authorization>
<deny users="?" />
</authorization>

It validates users against Active Directory by trying to pass the username
and password found in the login.aspx form to a DirectoryEntry object. If it
succeeds, it calls:

FormsAuthentication.RedirectFromLoginPage(strUsername,false);

After 18 minutes have passed with no activity, the cookie expires and the
user tries to click on a link, it redirects to the login page. All that
works fine. The problem is I don't know how to test the AuthCookie for
expiration. In the login.aspx page, I need to somehow test to see whether
the user was directed here because of a session timeout (actually the
AuthCookie expired). Previously, I had simply been testing the querystring
for "j=session_timedout". But now I can't do that since the redirection
happens automatically when the AuthCookie expires. I've tried testing the
AuthCookie for expiration with its "Expire" property:

FormsIdentity fiAuthTicket =
(FormsIdentity)HttpContext.Current.User.Identity;
FormsAuthenticationTicket fatAuthTicket = fiAuthTicket.Ticket;

if (fatAuthTicket.Expired) {
lblLoginError.Text = "Your session has timed out. Please log in
again!";
lblLoginError.Visible = true;
}

but the problem there is that, if the AuthCookie has expired, the
User.Identity seems to be set to null because I get an error with:

FormsIdentity fiAuthTicket =
(FormsIdentity)HttpContext.Current.User.Identity;

So that fails and it never prints out "Your session has timed out...".

It shouldn't be that hard to do but I can't figure out how to do it. Any
help is appreciated.
 
J

Joseph E Shook [MVP - ADSI]

You need to get the authticket directly and check it's expired property.

HttpCookie authCookie =
Context.Request.Cookies(FormsAuthentication.FormsCookieName)
FormsAuthenticationTicket authTicket =
FormsAuthentication.Decrypt(authCookie.Value)
if (authTicket.Expired)
{
'do your thing.
}

I think that works... I pulled it from a more complicated piece of code
and didn't test it, but I think you can see that with an expired
authTicket you would not get a non-anonymous User.Identity populated.


John said:
This may sound trivial but I cannot figure out how to do this...
When a logged in user's session expires, I want that user redirected back to
the login page with a label that says "session expired". Sounds easy, eh?

First, am I correct in assuming that a session is totally separate from the
"AuthCookie" that gets set when you use the FormsAuthentication class? They
have nothing to do with each other, right? So, if my IIS application is set
to expire Sessions every 20 minutes, that has no affect on the AuthCookie
that I set to timeout every 18 minutes and vice-versa.

I just started playing around with <authentication> in my web application.
I had simply been using Session variables to track the session of a logged
in user with the following code that I would put at the top of each page. I
had to use try/catch because, if the session had expired, it would throw an
exception while trying to print the name. If the exception occured, that
means the session expired and it would redirect back to the login page. The
login page tests for the "j=session_timedout" in the querystring and will
display "Sorry, your session timed out!". No problem.

try {
lblSessionName.Text = Session["name"].ToString();
}
catch (Exception exp) {
Response.Redirect("login.aspx?j=session_timedout");
}

But I just started REALLY playing around with the built-in authentication
that .net has and I think its much nicer than what I was trying to do. I
have it now using Forms based authentication (web.config):

<authentication mode="Forms">
<forms loginUrl="/login.aspx" name=".FORMSAUTH" path="/"
protection="All" timeout="18" slidingExpiration="true" />
</authentication>

<authorization>
<deny users="?" />
</authorization>

It validates users against Active Directory by trying to pass the username
and password found in the login.aspx form to a DirectoryEntry object. If it
succeeds, it calls:

FormsAuthentication.RedirectFromLoginPage(strUsername,false);

After 18 minutes have passed with no activity, the cookie expires and the
user tries to click on a link, it redirects to the login page. All that
works fine. The problem is I don't know how to test the AuthCookie for
expiration. In the login.aspx page, I need to somehow test to see whether
the user was directed here because of a session timeout (actually the
AuthCookie expired). Previously, I had simply been testing the querystring
for "j=session_timedout". But now I can't do that since the redirection
happens automatically when the AuthCookie expires. I've tried testing the
AuthCookie for expiration with its "Expire" property:

FormsIdentity fiAuthTicket =
(FormsIdentity)HttpContext.Current.User.Identity;
FormsAuthenticationTicket fatAuthTicket = fiAuthTicket.Ticket;

if (fatAuthTicket.Expired) {
lblLoginError.Text = "Your session has timed out. Please log in
again!";
lblLoginError.Visible = true;
}

but the problem there is that, if the AuthCookie has expired, the
User.Identity seems to be set to null because I get an error with:

FormsIdentity fiAuthTicket =
(FormsIdentity)HttpContext.Current.User.Identity;

So that fails and it never prints out "Your session has timed out...".

It shouldn't be that hard to do but I can't figure out how to do it. Any
help is appreciated.
 
J

John Smith

I think that did the trick! You rock dude! :) Thanks.

Final code:
// why are we here? session timeout? user clicked logout? or new
session?

// if auth expiration (ie session timeout)...
// get auth ticket info if it exists

try {
HttpCookie authCookie =
Request.Cookies[FormsAuthentication.FormsCookieName];
FormsAuthenticationTicket authTicket =
FormsAuthentication.Decrypt(authCookie.Value);

if (authTicket.Expired) {
Response.Write("Session Timedout");
lblLoginError.Text = "Your session has timed out. Please log in again!";
lblLoginError.Visible = true;
}
}
catch (Exception exp) {
// auth ticket probably didn't exist which means this is NOT a session
timeout..ignore
}

// did user click logout?

if (Request.QueryString.ToString().IndexOf("logout") >= 0) {

// remove all session items and the auth ticket
Session.RemoveAll();
FormsAuthentication.SignOut();

lblLoginError.Text = "You have been logged out at your request!";
lblLoginError.Visible = true;
}


Joseph E Shook said:
You need to get the authticket directly and check it's expired property.

HttpCookie authCookie =
Context.Request.Cookies(FormsAuthentication.FormsCookieName)
FormsAuthenticationTicket authTicket =
FormsAuthentication.Decrypt(authCookie.Value)
if (authTicket.Expired)
{
'do your thing.
}

I think that works... I pulled it from a more complicated piece of code
and didn't test it, but I think you can see that with an expired
authTicket you would not get a non-anonymous User.Identity populated.


John said:
This may sound trivial but I cannot figure out how to do this...
When a logged in user's session expires, I want that user redirected back to
the login page with a label that says "session expired". Sounds easy, eh?

First, am I correct in assuming that a session is totally separate from the
"AuthCookie" that gets set when you use the FormsAuthentication class? They
have nothing to do with each other, right? So, if my IIS application is set
to expire Sessions every 20 minutes, that has no affect on the AuthCookie
that I set to timeout every 18 minutes and vice-versa.

I just started playing around with <authentication> in my web application.
I had simply been using Session variables to track the session of a logged
in user with the following code that I would put at the top of each page. I
had to use try/catch because, if the session had expired, it would throw an
exception while trying to print the name. If the exception occured, that
means the session expired and it would redirect back to the login page. The
login page tests for the "j=session_timedout" in the querystring and will
display "Sorry, your session timed out!". No problem.

try {
lblSessionName.Text = Session["name"].ToString();
}
catch (Exception exp) {
Response.Redirect("login.aspx?j=session_timedout");
}

But I just started REALLY playing around with the built-in authentication
that .net has and I think its much nicer than what I was trying to do. I
have it now using Forms based authentication (web.config):

<authentication mode="Forms">
<forms loginUrl="/login.aspx" name=".FORMSAUTH" path="/"
protection="All" timeout="18" slidingExpiration="true" />
</authentication>

<authorization>
<deny users="?" />
</authorization>

It validates users against Active Directory by trying to pass the username
and password found in the login.aspx form to a DirectoryEntry object. If it
succeeds, it calls:

FormsAuthentication.RedirectFromLoginPage(strUsername,false);

After 18 minutes have passed with no activity, the cookie expires and the
user tries to click on a link, it redirects to the login page. All that
works fine. The problem is I don't know how to test the AuthCookie for
expiration. In the login.aspx page, I need to somehow test to see whether
the user was directed here because of a session timeout (actually the
AuthCookie expired). Previously, I had simply been testing the querystring
for "j=session_timedout". But now I can't do that since the redirection
happens automatically when the AuthCookie expires. I've tried testing the
AuthCookie for expiration with its "Expire" property:

FormsIdentity fiAuthTicket =
(FormsIdentity)HttpContext.Current.User.Identity;
FormsAuthenticationTicket fatAuthTicket = fiAuthTicket.Ticket;

if (fatAuthTicket.Expired) {
lblLoginError.Text = "Your session has timed out. Please log in
again!";
lblLoginError.Visible = true;
}

but the problem there is that, if the AuthCookie has expired, the
User.Identity seems to be set to null because I get an error with:

FormsIdentity fiAuthTicket =
(FormsIdentity)HttpContext.Current.User.Identity;

So that fails and it never prints out "Your session has timed out...".

It shouldn't be that hard to do but I can't figure out how to do it. Any
help is appreciated.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top