I have a handler, like this, using IRequiresSessionState:
public class MyHandler : IHttpHandler, IRequiresSessionState
{
// code
}
In the code, I am able to read and set Session values. I also check ensure that the caller is logged in. That all works fine.
The web site uses forms authentication, so in the web.config, I have this:
<authentication mode="Forms">
<forms loginUrl="Login.aspx" timeout="10" slidingExpiration="true"></forms>
</authentication>
The problem is that AJAX calls from the client to the server code MyHandler do not extend the life of the session!
So even if the user is busy sending and receiving data from the server, they time out 10 minutes after their last full page load.
In the handler, I've tried specifically changing a value is the session on each call, but not even that extends the time out.
Any suggestions?
Finally got a solution to this... sort of.
I abandoned trying to get the handler to do the job, and instead called a normal ASPX page. In that page, I removed the HTML code, and used Response.Write(...) to send back some JSON that I wanted. However, even with that, my session was not being extended!
I finally realized that in the PreRender event, I used Response.ClearHeaders(). That was the problem. It turns out that the Forms authentication system was updating the session ticket cookie when needed, but was adding it to the Headers before my code was running. So when I cleared the headers, I was erasing the new cookie before it was sent to the browser.
So, if you are having problems with sessions not being extended, check to make sure that your code is not using ClearHeaders()!
Related
I am developing ASP.Net MVC application.
We have used sessionState mode SQLServer and i have set timeout to 20 minutes.
<sessionState mode="SQLServer"
sqlConnectionString="data source=127.0.0.1;user id=sa;password=sa"
cookieless="false"
timeout="2" />
Code is something like this in web config.
I have also set login page.
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
Now when session expires i want to navigate user to login page.
I checked many things but i was unable to understand how it exactly works? and how can i navigate user login page on session expire?
It is working in InProc mode. I used it in same way and user is redirected to login on session expire.
But i am unable to accomplish same thing in SQLServer Mode.
I am unable to understand what i am missing?
I checked Session State and also found that Session timeout handled in SQLServer Mode
Edit :-
I want to redirect user to login page whenever another http request is executed for that session.
Ordinarily the browser has no idea what is going on on the server. Unless an HTTP round trip occurs, it will remember the state of the session from when the page was rendered.
In addition, you session cookie is probably HttpOnly, so there is no way for the page to check for the presence of a session cookie.
One way to accomplish what you want is:
Add a hidden iFrame to your page. Set the SRC of the iFrame to a handler in your web site
The handler doesn't have to do much except return a 200 OK, plus a refresh header set to a few seconds, so that the handler gets continually polled.
context.Response.AddHeader("REFRESH", "2");
Add framebreaker code to your login page
if (top.location != location) {
top.location.href = document.location.href ;
}
When a request for the handler occurs with an expired session, it'll get redirected to the login page via forms authentication; when the login page is returned, it'll break your iFrame and redirect the full window to the login page.
Or, you can do what everyone else does, which is wait for the user to request another page.
For me, changing the timeout value in the web.config file to anything didn't take place, and the reason was there were somehow some leftover old records in the ASPStateTempSessions table in ASPState database. I had to empty the table and only then my web.config changes took place. I wasted an hour trying to search for the cause so hope this helps someone.
So, run this:
delete from ASPStateTempSessions
Difference between InProc and SQLServer mode is that SQLServer relies on MSSQL job to remove the session. It actively doesn't prevent you from login again.
See Session State Providers
SqlSessionStateStore doesn't actively monitor the Expires field. Instead, it relies on an external agent to scavenge the database and delete expired sessions—sessions whose Expires field holds a date and time less than the current date and time. The ASPState database includes a SQL Server Agent job that periodically (by default, every 60 seconds) calls the stored procedure DeleteExpiredSessions to remove expired sessions.
In my web application, i often can see, that when i am not doing anything for a few minutes, and then i come back, and refresh the page - i am still being logged in, but my session data is all gone!
On the login() action i am setting up few Session[] objects that are necessary for a page to work correctly. I have no idea why is it doing so, but i need it to log user out whenever it clears his session data.
I have read about setting <sessionState mode="InProc" timeout="20"/> but will this timeout refresh everytime i refresh the page? Or will it run out after 20 minutes from the time i logged in? What if i make this timer bigger than i have on keeping the user online?
Posting back to the server will keep the session alive for longer. It's a sliding expiration. There are two ways to handle from the client, which the client is not aware of this 20 minute timeout:
Create a timer using client javascript that redirects to the logout page when 20 minutes is hit
Whenever a postback happens, check if the session expired (which can be done in a variety of ways, such as checking Session.IsNewSession, see if your objects are lost, etc.) and then redirect to the logout handler before processing the request.
I assume you are using Forms Authentication. Is that correct? If so, you need to have your Forms Authentication ticket's timeout match the Session timeout.
The user stays logged in through a process that is more complicated than it first seems. A cookie is stored in the user's browser that is called the Forms Authentication Ticket. If the user stays idle past the session timeout limit, the server will discard the session. But on the next request, the Forms Authentication Ticket is passed back to the web server. The server validates the ticket, and if it is still valid, the user is logged back in.
As you can see, the user's session is not restored. If you want that behavior, you would have to detect that condition and restore the session yourself.
The solution is to set the Forms Authentication Ticket's timeout to be the same as the Session timeout. You accomplish that in your Web.config file, as explained here:
<system.web>
<authentication mode="Forms">
<forms timeout="20"/>
</authentication>
</system.web>
The timeout value is in minutes. Once the Forms Authentication Ticket's timeout is hit, the user will be logged out. This operates independent from the session's timeout, but if they are the same, they will expire at roughly the same time. If you want to be completely safe, set the Forms Authentication Ticket timeout to be a little shorter than the session timeout. The user will be logged out before their session times out. When they log in again, they will get a new session. The old session will eventually time out on its own.
Try checking this:
Q: In Proc mode, why do I lose all my session occasionally?
A: Please see the "Robustness" section in the "Understanding session
state modes" section of of this article.
Robustness
InProc - Session state will be lost if the worker process
(aspnet_wp.exe) recycles, or if the appdomain restarts. It's because
session state is stored in the memory space of an appdomain. The
restart can be caused by the modification of certain config files such
as web.config and machine.config, or any change in the \bin directory
(such as new DLL after you've recompiled the application using VS) For
details, see KB324772. In v1, there is also a bug that will cause
worker process to restart. It's fixed in SP2 and in v1.1. See
KB321792.
Source - http://forums.asp.net/t/7504.aspx/1
Can I write my code in the Session_End method when my session is timeout and I redirect users to the Login Page?
I am using Form Authentication method.
Currently I have create a "CheckSession()" method and calling on each page...
please suggest...
I've always placed the session check code in a master page for webform projects or, more recently, creating a base controller that has this method. Either way the goal is not to duplicate that code everywhere for obvious maintenance reasons.
I think you can manage this through settings in your web.config file without having to use code at all. Just ensure that the duration of your forms authentication cookie and your session are the same length. If your authentication session times out ASP.NET will automatically redirect a user to the login page.
Try:
<forms ... timeout="20" slidingExpiration="true" />
(slidingExpiration is true by default but I've specified it here because it must be true to replicate the timeout behaviour of sessions in ASP.NET)
and:
<sessionState ... timeout="20" />
1.-I'm using reporting services and sometimes I get this error ASP.NET session has expired or could not be found when I try to load a report.
2.-I realized that I get this error when the Session.SessionID property changes even though the user is the same. If it does not change, the report is loaded. I mean, if I refresh the report a number of times, whenever the Session.SessionID is the same than the last one, the report is loaded.
3.-Microsoft Documentation says:
When using cookie-based session state, ASP.NET does not allocate
storage for session data until the Session object is used. As a
result, a new session ID is generated for each page request until the
session object is accessed. If your application requires a static
session ID for the entire session, you can either implement the
Session_Start method in the application's Global.asax file and store
data in the Session object to fix the session ID, or you can use code
in another part of your application to explicitly store data in the
Session object.
If your application uses cookieless session state, the
session ID is generated on the first page view and is maintained for
the entire session.
The point is that I can not use a cookieless session state because I need cookies.
What could I do to avoid this error? Or What could I do to avoid the Session.SessionID to change on every request?
You are probably storing your session InProcess. Try changing it to session state server. You can find more details here.
I'm using report viewer 11.0.0; in your web config on system.web section, put the next configuration:
<sessionState timeout ="120" mode="InProc" cookieless="false" />
When you are generating the report (C# code bellow) in the reportviewer object change the KeepSessionAlive property to false and the AsynkRendering property to false, and that's all
this.rvReporte.KeepSessionAlive = false;
this.rvReporte.AsyncRendering = false;
(rvReporte) is a ReportViewer control located on my asp.net Form
This solution work for me, i hope that work for other people.
Regards
<httpCookies httpOnlyCookies="false" requireSSL="false"/>
Solved the problem.
Thanks to :
http://www.c-sharpcorner.com/Blogs/8786/reportviewer-Asp-Net-session-has-expired.aspx
I had the same issue on report viewer page when the web site was accessed from outside intranet. hardvin's suggestion saved the day for me which is to set
this.rvReporte.KeepSessionAlive = false;
this.rvReporte.AsyncRendering = false;
I changed the property on the control itself. I am using report viewer on a user control which raises a custom event for supplying parameters programmatically at the host page instead of prompting the users.
I solved this issue by setting AsyncRendering to false on reportviewer server control
Having the reportviewer being displayed in iframe was giving us this error. If displayed outside of iframe it works nice.
The reportviewer object has this configuration, AsyncRendering = false and KeepSessionAlive = true.
The webapp that has the reportviewer and set the session cookie in the browser was compiled with .net framework 4.6.1. We upgrade to 4.8 and put this in web.config
<sessionState cookieSameSite="None" />
<httpCookies requireSSL="true"/>
SĂł the solution is from https://learn.microsoft.com/en-us/aspnet/samesite/system-web-samesite#:~:text=The%20updated%20standard%20is%20not%20backward%20compatible%20with,SameSite%3DStrict.%20See%20Supporting%20older%20browsers%20in%20this%20document.
The answer given by Alexsandar is just one of the solution to this problem.
This link clearly explains what is the root cause for this problem and possible solutions:
http://blogs.msdn.com/b/brianhartman/archive/2009/02/15/did-your-session-really-expire.aspx
In case of Brian, the way he has descrived the problem, if he had just a single IIS server, using a session object in his code would have solved the problem because in that case, the SessionID which is passed in the request from browser to the server will get mapped to a corresponding sessionID on the server and hence the session expiry message will not come.
Setting the mode may only work in case of a server cluster where Brian had multiple IIS servers handling the same request. In that case an out of process mode will help to retrieve the session object from the Session Store irrespective of the server hit.
So based on this observation, I would conclude that Brian's problem was not related to cookies but to a server cluster. The information provided by Brian in his question and the subsequent solution misled me and hence this clarification. Hope it helps anyone looking for a similar problem.
Thanks,
Vipul
I have added the below-mentioned line on the web config file and it is working fine for me.
<sessionState mode="InProc" cookieless="true" timeout="3000" />
<pages enableSessionState="false" />
<customErrors mode="Off" />
Try removing SessionState="somevalue" tag from the top of your calling ASPX page. I'm using a custom SessionState and refuse to use InProc since I have multiple instances on Azure. You can even use AsyncRendering=True if you desire. Let me know if this did the trick for you.
For me, it turned out to be having more than one worker process for the app pool.
For me Azure hosted web app turning ON - ARR Affinity fixed the issue.
ARR Affinity ON
Please help me I'm getting desperate here trying to find the problem, and I don't know where to start looking for it.
Here are the symptoms:
I've noticed, that when a user logs on in the morning, he is then immediately logged off, then when he logs on again, everything is fine and he can work on the site.
Every once in a while, when the user clicks a link, the page takes a lot of time to load, but it never actually loads, and the user is thrown to the login page.
Also, after an Exception has occurred in the website, the user is then thrown to the login page. It's as if the exception clears somehow the session.
Do any of you know of a situation where this might happen ?
The code I use in every page in my application is as follows :
If (Not User.Identity.IsAuthenticated) Then
Response.Redirect("../login2.aspx")
End If
' If session timeout then return to login screen '
If ((Session("LocationId") Is DBNull.Value) Or (Session("LocationId") Is Nothing))
Then
Response.Redirect("../login2.aspx")
End If
The code in the web.config:
<sessionState cookieless="false" timeout="600" />
<authentication mode="Forms">
<forms timeout="600" />
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
Why are you using that code in every page?
.NET authorization and authentication normally takes care of all those things if you have it set up correctly.
Related to this scenario *`
".... after an Exception has occurred
in the website, the user is then
thrown to the login page. It's as if
the exception clears somehow the
session
I know of one possible situation where it may occur.
It is far fetched especially in a production scenaio for multiple reasons but i have seen it happen :-)
If the session is In Memory and logging is done by writing to a log file that is in the Bin directory of the application, then this may occur as modifying the bin folder of the web application results in the application restarting i.e the in memory session getting lost.
Just one possible scenario. If your session is not in Memory OR your logging mechanism isnt like this, then this doesnt apply to you.
I am turning to all the dot net experts out there because I am really desperate,
let me give another symptom of the problem because it still persists,
the server is a very strong server - intel xeon with a 3 gb ram, so it is probably not a problem of resources.
When the user uses the system continuously there is no problem and she can work freely, the problem arises when the user leaves the computer (or the application for that matter) for as long as 5 minutes, then when she wants to continue working and clicks a link in the application she is thrown to the login page. when she tries to login again, she succeeds, but after she clicks another link, she is thrown out again, then when she logins she can work freely and everything is fine.
Somehow the session is being cleared when the site is idle. let me emphasize that this doesn't happen when I run the app in visual studio, only in iis.
The app was converted from asp.net 2.0 to 3.5,
that's it, thanks
First of all, you need to deny access for non-authenticated (anonymous) users:
<authorization>
<deny users="?" />
</authorization>
Have you configured default and login pages?
<authentication mode="Forms">
<forms name=".ASPXFORMSAUTH" loginUrl="Login.aspx" defaultUrl="Default.aspx" slidingExpiration="true" timeout="30" />
</authentication>
name sets the name of a cookie, useful if you will use .NET 2.0 built-in security infrastructure (roles, membership, etc)
slidingExpiration enabled normal timeout behavior - any user action resets timeout
If you are just using the normal session functionality in asp.net I believe that the session times out after 15-30 minutes of inactivity (I typically don't use session so I remember it is somewhere in this range). Every postback to the server resets this timer so if a user is active doing things then they won't hit this time out.
For the page taking a long time to load it is most likely due to the worker process recycling and that user is the first user to access the site after a recycle which triggers IIS to do all of it's compilation stuff and then serve the page which causes the delay. This only happens for the first visitor after a worker process recycle. You can change this behavior in IIS to happen on a schedule rather than after a certain amount of time has passed without activity. This will cause your worker process to take up more memory though so depending on your environment this might not be a good change to make.
EDIT: I should add that the code you posted explains exactly why the user is kicked back to the login page. It is checking to make sure that there is something in the session and if there isn't anything there it kicks the user back to the login page. So if they are inactive for too long your session times out, so it is cleared, and the user is kicked back to the login page by your code. Also you should use FormsAuthentication.RedirectToLoginPage(); for your redirect instead of Response.Redirect. This way after logging in they go back to the page they requested originally.