Forms authentication and session expiration

R

Rippo

Hi

I am using role base forms authentication in asp.net and have come
across a problem that I would like advice on.

On a successful login a session variable is set to identify a user.
This is all good as this session variable is used to retrieve data for
that user etc. However if I restart the webserver then the users
session is lost but the ticket is still active. Therefore the user is
not redirected back to the login page.

My question is what is the best approach to see if the user session is
still active and sign out the user from forms authentication.

I do not really want to perform a check on every member page. Nor can I
perform a check in global.aspx as there are some non mmbers pages that
can be viewed. I also do not wish to rebuild the session if the users
session has expired.

I am sure that there is an easy answer however I can not come up with
the best approach.

Can any one help?
 
T

tom.pesterDeLeTeTHISSS

My first though is to make the ticket timout sooner than the session.

You can set the ticket timout in the web.config :

<authentication mode="Forms">
<forms timeout="" />
</authentication>

I think the following blog post is also relevant :

http://weblogs.asp.net/rajbk/archive/2004/10/11/241080.aspx

Let me know if you have any more questions..

Cheers,
Tom Pester

PS
You can also store the session in a database so that it will survive for
as long as you want (AFAIK).
 
R

Rippo

OK.I understand this and thanks for the url.

Setting the ticket timeout to expire sooner than the session will not
work if IIS is reset or if I place a new build on to the server.

Is resetting the sesion or storing it in the DB the only way forward
for me?

Thanks for any help
Rippo
 
T

tom.pesterDeLeTeTHISSS

My first thought doesnt work at second thought and isn't an answer to your
question.

if session("X") = "" then FormsAuthentication.SignOut()

Is this what you want?

Let me know if you have any more questions..

Cheers,
Tom Pester
 
R

Rippo

This is correct if i want to place this on every page that need to
check for the exisitence of a session variable, unfortunetely this
forces me to remember to do this on every page and every new page I
create.

I was hoping for a more elegant solution

Thanks
Rippo
 
T

tom.pesterDeLeTeTHISSS

And that code should go inot the beginrequest event of global.asax of course.

Mustn't press the send button so fast :)

Cheers,
Tom Pester
 
R

Rippo

I have tried this and found that it does not work.

Thanks for your help but please can you test your assumptions before
posting them here. I do thank you however for your help
Rippo
 
T

tom.pesterDeLeTeTHISSS

Will do... Im trying to put you on the right track but ill write some code k?

Cheers,
Tom Pester
 
T

tom.pesterDeLeTeTHISSS

Hi Rippo,

The beginrequest event doesnt have access to the session object yet (its
too early in the page lifecycle)... so we look for an event that does. AcquireRequestState
is our guy :

Protected Sub Application_AcquireRequestState(ByVal sender As Object,
ByVal e As System.EventArgs)

If Session("test") = "" Then
If User.Identity.IsAuthenticated Then
FormsAuthentication.SignOut()
End If
End If

End Sub

If you put that code in your global.asax it should work.

"If User.Identity.IsAuthenticated Then" is necessary otherwise we end up
in an ifinate loop.

Let me know if this works for you.

Cheers,
Tom Pester

PS The build in web server of VWD beta 2 wants to handle images and other
things as well and this leads to some strange behaviour.
If you see this its not because of a bug in our code. Under IIS it should
work fine.
 
R

Rippo

Tom

Thanks for sticking with this.

It almost works. However do the following and you will see a problem

1. login and make sure your sesssion variable is set and your ticket is
created
2. goto cmd prompt and type iisreset -restart
3. navigate to a page that outputs the session variable. You will see
that the result is blank
4. now refresh and you should go back to your login

This is because we are signing out but not redirecting to the login
page. Normally you would think to put response.redirect("login.aspx")
after the signout code. however if you do this then you will never be
able to go to a page an aspx that does not need roles authentication
(e.g. a contact us page).

Can you think how one would solve this

Thanks again
Rippo
 
T

tom.pesterDeLeTeTHISSS

however if you do this then you will never be
able to go to a page an aspx that does not need roles authentication
(e.g. a contact us page).

If you were on the contact page when the server was reset and do a refresh
you will be redirect to the login page.
(At least thats what happens on my asp.ent v2 beta2 machine. See the web.config
snippet below)

But since you can view the contact page just fine anonymously this is not
necessary and actualy a nuissance.

Is this the problem you have now? You state that you can _never_ see the
contact page if you are not logged in. I dont agree with that.

Once we agree on the problem lets find a solution.

Cheers,
Tom Pester

web.config snippet
<authentication mode="Forms">
<forms defaultUrl="~/Aanbieden/Menu.aspx" loginUrl="~/Aanbieden/Default.aspx"/>
</authentication>
 
R

Rippo

Sorry tom

I did not explain myself very well. I will try again!

If a member logs in and the server is then reset or the session is lost
then we both agree that we need to sign out the user imediately from
formsAuthetication and imediately redirect the user back to the login
page. This needs to happen when the user tries to go to the next page
after the session is lost that requires authentication.

You solution does not quite achieve this as this is the chain of events
(try it and see):-

1. user logins in
2. iis is reset
3. user clicks a link which takes him to another logged in page that
depends on a session
4. the code in Application_AcquireRequestStat­e is fired and the user
is marked as being signed out
5. a page is shown to the user but the user session is lost
6. the user clicks refresh
7. the user is directed to the login page because the user is no longer
signed into forms authentication

I am trying to now stop points 5 and 6 from happening!

So what I was trying to say was after we perform
FormsAuthentication.SignOut() in the global.asa we must also redirect
back to the login page otherwise the requested page is shown to the
user. However if I do this then other pages like contact could never be
shown to a non logged in member.

This happens on vs2003 .net 1.1

I really appreciate your help so far! I am sure we can achieve what I
am trying to do as this must affect all sites that use sessions and
forms authentication!!!

Many thanks
Rippo
 
T

tom.pesterDeLeTeTHISSS

4. the code in Application AcquireRequestStat­e is fired and the user
is marked as being signed out
5. a page is shown to the user but the user session is lost
6. the user clicks refresh
7. the user is directed to the login page because the user is no

Step 5 doesnt happend with me. My web app goes directly to step 7.

If I refresh the a page (be it a page thats only accessible to logged in
users or to an anonymouse user), the session has expired and asp.net V2 beta2
decides immidialty to redirect to the login page.
http://localhost:3239/ImmoTom/Aanbieden/Default.aspx?ReturnUrl=/ImmoTom/Aanbieden/Ingave.aspx
(ImmoTom/Aanbieden/Default.aspx is my login page. ReturnUrl was the page
I requested)

The requested page only does a redirect (302). Nothing more

We are not focused on a specific problem now but on the dynamics of a whole
site and that means we maybe have different configuration settings (web.config,global.asax)
that explains you see something different and its a fact we have different
asp.net versions. Mabye this is causing the difference. Its high time to
switch to ASP.NET V2 :)

I can also switch to ASP.NET V1 if you don't find the solution but Id rather
not :) If you get desperate you can send me a working site of a page or 2
that shows the problem and Ill run and tweak it.
So what I was trying to say was after we perform FormsAuthentication.SignOut()
in the global.asa we must also redirect back to the login page otherwise
the requested page is shown to the user. However if I do >this then other
pages like contact could never be shown to a non logged in member.

If you only do the ridirect when
1) the user had a cookie ticket (was logged in) and
2) the user's session has expired

Then it think 1) is sufficent to say that a non logged in member will never
see a redirect and can surf hapily.
 
R

Rippo

So the signout code in asp.net 2 must behave differently and redirects
back to the login page whereas in v1 it just signs out.

Just looked at msdn and msdn (for 2005) help and found this:-

FOR 2003 signout
This removes either durable or session cookies.

FOR 2005 signout
The following code example clears the forms authentication cookie using
the System.Web.Security.FormsAuthentication.SignOut method and
redirects the user to the login page using the
System.Web.Security.FormsAuthentication.RedirectToLoginPage method.

GRRR! Thats why we were on different wave lengths, the signout method
in 2005 also redirects! We will not move to 2005 until it is fully
released (company policy). As soon as it ships we will go that way.

Is there a way I can override the signout and perform the redirect
manually?

Thanks
Rippo
 
R

Rippo

and of course 2005 has this method

FormsAuthentication.RedirectToLoginPage

but 2003 has not
 
R

Rippo

OK

I have taken aboard what you have explained and have the following code
in Global_AcquireRequestState

If Session.IsNewSession Then
If User.Identity.IsAuthenticated Then
FormsAuthentication.SignOut()
Response.Redirect(webtools.basePath & "/Index.aspx")
End If
End If

This works fine apart from if a)you are logged in and b) you browsing
say the contact page. At the point of iis restart you are automatically
redirected to the login page (even though you dont need to be logged in
to view the contact page) .

However I believe that I can live with this and this should not impact
too much on the users, its not like the web server restarts too much

Thanks for your help
 
T

tom.pesterDeLeTeTHISSS

I think we can solve that little nuisace too. This code works for me in asp.net
v2

Protected Sub Application_AcquireRequestState(ByVal sender As Object,
ByVal e As System.EventArgs)

If Session("test") = "" Then
If User.Identity.IsAuthenticated Then
FormsAuthentication.SignOut()
Response.Redirect(Request.RawUrl) ' new code
End If
End If

End Sub


After the user has been signout we try to access the same page (Request.RawUrl)
and if thats ok, ie the page is also ment for anonymous access, that page
is displayed and not the login page.
If that page requires authorization the user will be presented the login
page because the user is now anonymous.

I think if you replace
Response.Redirect(webtools.basePath & "/Index.aspx")
with
Response.Redirect(Request.RawUrl) ' new code

There is a good chance it will work.


Let me know if you have any more questions..

Cheers,
Tom Pester
 
R

Rippo

Perfect. Works like a charm!

just a quick point. i would replace if session("test") = "" with If
Session.IsNewSession as MSDN tells us

"Gets a value indicating whether the session was created with the
current request."

This is just to make the code slightly more reusable.

Anyway, Tom thanks for perservering with this! You have really helped
me out.
Rippo
 
T

tom.pesterDeLeTeTHISSS

It makes it more reusable indeed. Glad I could help you.

Cheers,
Tom Pester
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top