"User already logged" HttpContext or Request DB - c#

So, im working in a huge .NET MVC 3 system. As many users could be logged in at same time. I was just writting a way of "hey there's still someone logged with this key" with HttpContext. But, is this the best practice ? is it better to Query DB ?
what i wrote:
MvcApplication.SessionsLock();
if (!force && MvcApplication.Sessions.Values.Any(p => p.ID.Equals(acesso.id_usuario.ToString(CultureInfo.InvariantCulture)) && p.Valid))
throw new BusinessException("There's another user logged with this key. Continue ?");
MvcApplication.SessionsUnlock();
our I can query my DB.. maybe cookies ? any ideas would be appreciated

Storage
The database provides a central, durable location for this information. You might use a custom data structure, or ASP.Net SQL session might meet your requirements (more below on this).
There is not a deterministic way of always knowing exactly when a user's session ended. For example, you can listen to the Session End event, but it will only fire for in-process sessions and is not guaranteed to fire at all (e.g. the OS could crash).
Regardless, if you are building a "huge system" as you state, you shouldn't design against using in-proc session as it won't scale upwards. Start thinking about SQL-based session state which is more scalable (and may give you enough information to determine roughly how many users are active).
Session Pro/Con
I want to know if session is a good practice. That piece of code
works. But i have been reading a lot of articles deprecating usage of
sessions on ASP.NET MVC Application.
As far as Session being a good or bad thing--as always--it depends on how it is used. Properly designed MVC apps can present fairly complex views without needing to preserve state. Part of this is due to strong support for AJAX (no need to reload the page) and elegant model binding (which can take a complex Request.Form and turn it into a complete model).
Conversely, there is nothing inherently wrong with putting small snippets of repeatedly-used information into session state, using it to avoid sending sensitive data to the client, using it to make a smoother user flow, etc.
Do beware of session fixation attacks in high-security scenarios. Session may not be appropriate and/or may need to be manually secured further.
One thing to be aware of is that ASP.Net places a lock on session. This can lead to very real performance issues when multiple requests are made at once. Normally, this isn't an issue, but consider a page with a dozen AJAX widgets which all requested data from a controller or endpoint that used session. These will contend with each other (firsthand experience).
A non-locking in-process ASP.NET session state store
https://stackoverflow.com/a/2327051/453277
MVC provides an easy way to mark a controller as needing only readonly access to Session, which eliminates the issue. However, any read/write activity to Session will still be serialized, so plan accordingly.
Business Considerations
From a business perspective it's not always important to know that the session has expired so much as work has ceased (do you care that they stopped using the site, or that their session timed out?) This can be reliably addressed by checking last modified timestamps on entities and warning the users. Warn, don't lock. In my opinion, you shouldn rarely/never lock records based on login/logout in a web application (too easy to get stuck in a locked status).

Related

Is there a way to access another session via its ID and read it's session variables?

This application is running in a load balanced environment. It uses a SQL database as the session store. The app is simple and does not have it's own database.
I have created an endpoint to be called from another internal server that knows the SessionId. I want this endpoint to be able to grab a session variable by SessionId instead of from the current session.
I know that I could create a new database to do this, but it would be overkill as it would only have 1 table with 2 fields, SessionId and the one value related to it. I could even put this table in the current session database. I am trying to avoid having to add database connection code if at all possible.
Is there a way to access the variables of a different session other than the current session?
I might be wrong and if I am - downvote; the fact that the session state storage is database-based (and not in-memory) does not change the principles of how the IHttpSessionState works. I doubt you will be able to do that and I doubt you actually want to: you simply cannot access an absolutely separate context from a different context. Doing so has a lot of potential issues (thread safety, problems if the session state implementation is changed and so on). Your web application might not be aware of the session state store.
For example, if I simply use session state and have the session state configured directly in IIS, there is no way for the application thread to know it's in the database which immediately presents an issue: what if I decide to run the same application without the DB-backed session state? No changes to application code are required, just IIS reconfiguration. It might introduce unexpected behavior and/or runtime errors.
The suggestion (in the comment) to set the cookie to the known session ID is the only "way out" but from the security perspective it's less than optimal.
However, what you are trying to implement seems like a proper job for a Cache Provider. You can use SqlCacheDependency from System.Web.Caching to use the database for your cache. Then you could use the aforementioned SessionId as one of the cache identifiers.

ASP.NET MVC Session State Timeout

Given that session state is not reccomended in ASP.NET MVC. I'm trying to understand under what circumstances session is used. I know that using the TempData creates a session but what other circumstances are there and does it matter how I configure the session state timeout for better security?
<sessionState cookieName="s" timeout="20" />
The accepted answer you reference states in part
This tended to lead to an overuse of session, populating "current" variables in session intended to indicate what the current object being interacted with was. This overuse in turn made applications very state-dependent and much harder to determine expected behaviour ("Is this variable populated?" "Do I have the current order ID yet?").
MVC is structured around the idea that your website is a view into a logical model of information. It encourages having stateless operations through the use of simple controllers responding to actions with key information passed as part of the HTTP request
Session is not a bad thing when your website needs to tie certain content to a specific user, whether for security or personalization purposes. It is fine, expected and normal to use a session for that purpose.
What you should avoid doing is stuffing the session with any and all information that you might need anywhere in your web application. Take time to learn and understand the MVC architecture, and favor loading data that you need to render a given page when that page is actually being rendered. Only cache things that are relatively expensive to load, or are needed on many/all pages.
does it matter how I configure the session state timeout for better security?
The primary concern with session timeout periods is a session hijacking attack, which allows a man in the middle to intercept session information and control the session from a different device under control of the hacker. For most applications, I don't see anything wrong with the default session timeout.
The another concern is people that walk away from their device, leaving it unattended. People that do that have much greater security worries than just your website.
as you mentioned, it is true that session is not recommended in mvc . Because, in mvc identity is used to in identity there is no need for session.the data is stored in profile.
Session is used in such a condition when you want to maintain the value for multiple pages or multiple controllers. For ex, after, login you maintain the username and keep it until you remain in the application. While the tempdata is used to save or maintain value for the current action and the value is discarded after the next action
session state has no concern with security so there is no need to change the session time out value for the sake of security.

Blocking editing fields when already opened by another user [duplicate]

I have a SQL Server 2008 database and an asp.net frontend.
I would like to implement a lock when a user is currently editing a record but unsure of which is the best approach.
My idea is to have an isLocked column for the records and it gets set to true when a user pulls that record, meaning all other users have read only access until the first user finishes the editing.
However, what if the session times out and he/she never saves/updates the record, the record will remain with isLocked = true, meaning others cannot edit it, right?
How can I implement some sort of session time out and have isLocked be automatically set to false when the session times out (or after a predefined period)
Should this be implemented on the asp.net side or the SQL side?
Don't do it at all. Use optimistic concurrency instead.
Pessimistic locking is possible, but not from .Net applications. .Net app farms are not technically capable of maintaining a long lived session to keep a lock (obtained via sp_getapplock or, worse, obtained by real data locking) because .Net app farms:
load balance requests across instances
do not keep a request stack between HTTP calls
recycle the app domain
Before you say 'I don't have a farm, is only one IIS server' I will point out that you may only have one IIS server now and if you rely on it you will never be able to scale out, and you still have the problem of app-domain recycle.
Simulating locking via app specific updates (eg. 'is_locked' field) is deeply flawed in real use, for reasons you already started to see, and many more. When push comes to shove this is the only approach that can be made to work, but I never heard of anyone saying 'Gee, I'm really happy we implemented pessimistic locking with data writes!'. Nobody, ever.
App layer locking is also not workable, for exactly the same reasons .Net farms cannot use back-end locking (load-balancing, lack of context between calls, app-domain recycle). Writing a distributed locking app-protocol is just not going to work, that road is paved with bodies.
Just don't do it. Optimistic concurrency is sooooo much better in every regard.

Is there a better solution than using session variables; should session variables really be used in Web Pages, at all?

I am using WebMatrix (C#) to design Intranet web applications for the organization I work for.
I have made one database driven site, and am currently working on another, and for some time, I have been having some trouble with the Session variables randomly becoming null and throwing errors. So much so, that one simple Session variable was switched with the use of the server cache memory instead (which I originally thought would be more volatile, but that remains to be seen, so far...)
One question is: Is there any practical use of the Session variable, at all? If it truly is as volatile as it has seemed to be, they appear to be good for just about nothing.\
I know they are technically cookies, so I know that their data shouldn't be relied upon, but therein lies the problem. I need to send data to other pages that I "can" rely upon. This leaves out both Session variables and cookies.
I generally stay away from query strings or url data, for their blatant "plain-text" display of any sensitive information (like Social Security Numbers), with which, even SSL won't help.
The server cache memory is also volatile and is not to be relied upon.
AppState variables aren't user specific.
That leaves hidden input fields... The problem here is that, sometimes after "Post" I do Response.Redirect, and such, so C# doesn't always render a page after post (it seems).
Maybe this is just a lack of knowledge on my part, but I kind of seem cornered no matter which way I go.
Do I really have to save all page information into a separate database with every page and retrieve it with a sql query on the other page just to get reliable and not "blatantly" displayed information from one page to another with Web Pages? Still even this method would be a problem using several different users, no?
ASP.NET has different Session State modes:
InProc, this is in-memory. Session State lives as long as the IIS Application Pool isn't recycled or the entire IIS is restarted.
SqlServer. This is Session State is stored in a SQL Server storage. This is great because sessions survives after an IIS Application Pool or entire IIS restart, but it's a bottleneck as it means that every access to the session requires a deserialization and/or serialization of the Session State objects and, after all, database connections and so on.
StateServer. Similar to SqlServer, but using a Session State Server provided by Microsoft. This mode isn't used at all, but it's an option... (I've no experience with it).
Custom. You can implement some interfaces/abstract classes and define your own Session State storage.
In the other hand, Session State is server-side, it has nothing to do with cookies. It's a way of simulating state in a stateless world ruled by HTTP. Since ASP.NET writes an HTTP cookie in the browser, it can link a browser session with an unique server session too.
About if Session State is useful or not.... In my case, I've decided to avoid "states" at all. I prefer to stay stateless as much as possible. I write down some HTTP cookies in the browser to identity settings, preferences or users, and I do things per-request.
I prefer that because a good caching mechanism can insanely optimize the requests' performance as in most of the cases you wouldn't be accessing data directly in the store but in some cache, which means a lot of speed!
By the way, Session State shouldn't be used to store large object but basic values. Session State isn't a cache. For example, Session State could be a good place to store something like current logged-in user or his/her role. Or their profile identifier. Who knows.
Any other data should be queried in a per-request basis.
And again: cache should be your friend in terms of optimizing your environment and don't accessing the database or whatever in each request, compromising the system performance.

Some questions coming from application programming (C#/Visual C++) to ASP.NET (C#)

At the new place I am working, I've been tasking with developing a web-application framework. I am new (6 months ish) to the ASP.NET framework and things seem pretty straight forward, but I have a few questions that I'd like to ask you ASP professionals. I'll note that I am no stranger to C#.
Long life objects/Caching
What is the preferred method to deal with objects that you don't want to re-initialize every time a page is it? I noticed that there was a cache manager that can be used, but are there any caveats to using this? For example, I might want to cache various things and I was thinking about writing a wrapper around the cache that prefixed cache names so that I could implement different caches using the same underlying .NET cache manager.
1) Are there any design considerations I need to think about the objects that I am want to cache?
2) If I want to implement a manager of some time that is around during the lifetime of the web application (thread-safe, obviously), is it enough to initialize it during app_start and kill it in app_end? Or is this practiced frowned upon and any managers are created uniquely in the constructor/init method of the page being served.
3) If I have a long-term object initialized at app start, is this likely to get affected when the app pool is recycled? If it is destroy at app end is it a case of it simply getting destroyed and then recreated again? I am fine with this restriction, I just want to get a little clearer :)
Long Life Threads
I've done a bit of research on this and this question is probably redundant. It seems it is not safe to start a worker thread in the ASP.NET environment and instead, use a windows service to do long-running tasks. The latter isn't exactly a problem, the target environments will have the facility to install services, but I just wanted to double check that this was absolutely necessary. I understand threads can throw exceptions and die, but I do not understand the reasoning behind prohibiting them. If .NET provided a a thread framework that encompassed System.Thread, but also provided notifications for when the Application Server was going to recycle the App-Pool, we could actually do something about it rather than just keel over and die at the point we were stopped.
Are there any solutions to threading in ASP.NET or is it basically "service"?
I am sure I'll have more queries, but this is it for now.
EDIT: Thankyou for all the responses!
So here's the main thing that you're going to want to keep in mind. The IIS may get reset or may reset itself (based on criteria) while you're working. You can never know when that will happen unless it stops rendering your page while you're waiting on the response (in which case you'll get a browser notice that the page stopped responding, eventually.
Threads
This is why you shouldn't use threads in ASP.NET apps. However, that's not to say you can't. Once again, you'll need to configure the IIS engine properly (I've had it hang when spawning a lot of threads, but that may have been machine dependent). If you can trust that nobody will cause ASP.NET to recompile your code/restart your application (by saving the web.config, for instance) then you will have less issues than you might otherwise.
Instead of running a Windows service, you could use an ASMX or WCF service which also run on IIS/.NET. That's up to you. But with multiple service pools it allows you to keep everything "in the same environment" as far as installations and builds are concerned. They obviously don't share the same processpool/memoryspace.
"You're Wrong!"
I'm sure someone will read this far and go "but you can't thread in ASP.NET!!!" so here's the link that shows you how to do it from that venerable MSDN http://msdn.microsoft.com/en-us/magazine/cc164128.aspx
Now onto Long life objects/Caching
Caching
So it depends on what you mean by caching. Is this per user, per system, per application, per database, or per page? Each is possible, but takes some contrivance and complexity, depending on needs.
The simplest way to do it per page is with static variables. This is also highly dangerous if you're using it for user-code-stuff because there's no indication to the end user that the variable is going to change, if more than one users uses the page. Instead, if you need something to live with the user while they work with the page in particular, you could either stuff it into session (serverside caching, stays with the user, they can use it across multiple pages) or you could stick it into ViewState.
The cachemanager you reference above would be good for application style caching, where everyone using the webapp can use the same datastore. That might be good for intensive queries where you want to get the values back as quickly as possible so long as they're not stale. That's up to you to decide. Also, things like application settings could be stored there, if you use a database layer for storage.
Long term cache objects
You could initialize it in the app_start with no problem, and the same goes for destroying it at the end if you felt the need, but yes, you do need to watch out for what I described at first about the system throwing all your code out and restarting.
Keel over and die
But you don't get notified when you're (the app pool here) going to be restarted (as far as I know) so you can pretty much keel over and die on anything. Always assume the app is going to go down on you before your request, and that every request is the first one.
Really tho, that just leads back into web-design in the first place. You don't know that this is the first visitor or the fifty millionth (unless you're storing that information in memory of course) so just like the app is stateless, you also need to plan your architecture to be stateless as much as possible. That's where web-apps are great.
If you need state on a regular basis, consider sticking with desktop apps. If you can live with stateless-ness, welcome to ASP.NET and web development.
1) The main thing about caching is understanding the lifetime of the cache, and the effects of caching (particularly large) objects in cache. Consider caching a 1MB object in memory that is generated each time your default.aspx page is hit; and after a year of production you're getting 10,000 hits an hour, and object lifetime is 2 hours. You can easily chew up TONS of memory, which can affect performance, and also may cause things to be prematurely expired from the cache, which in turn can cause other issues. As long as you understand the effects of all of this, you're fine.
2) Starting it up in Application_Start and shutting it down in Application_End is fine. You can also implement a custom HttpApplication with an http module.
3) Yes, when your app pool is recycled it calls Application_End and everything is shutdown and destroyed.
4) (Threads) The issue with threads comes up in relation to scaling. If you hit that default.aspx page, and it fires up a thread, and that page gets hit 10,000 in 2 minutes, you could potentially have a ton of threads running in your application pool. Again, as long as you understand the ramifications of firing up a thread, you can do it. ThreadPool is another story, the asp.net runtime uses the ThreadPool to process requests, so if you tie up all the threadpool threads, your application can potentially hang because there isn't a thread available to process the request.
1) Are there any design considerations I need to think about the objects that I am want to cache?
2) If I want to implement a manager of some time that is around during the lifetime of the web application (thread-safe, obviously), is it enough to initialize it during app_start and kill it in app_end? Or is this practiced frowned upon and any managers are created uniquely in the constructor/init method of the page being served.
There's a difference between data caching and output caching. I think you're looking for data caching which means caching some object for use in the application. This can be done via HttpContext.Current.Cache. You can also cache page output and differentiate that on conditions so the page logic doesn't have to run at all. This functionality is also built into ASP.NET. Something to keep in mind when doing data caching is that you need to be careful about the scope of the things you cache. For example, when using Entity Framework, you might be tempted to cache some object that's been retrieved from the DB. However, if your DB Context is scoped per request (a new one for every user visiting your site, probably the correct way) then your cached object will rely on this DB Context for lazy loading but the DB Context will be disposed of after the first request ends.
3) If I have a long-term object initialized at app start, is this likely to get affected when the app pool is recycled? If it is destroy at app end is it a case of it simply getting destroyed and then recreated again? I am fine with this restriction, I just want to get a little clearer :)
Perhaps the biggest issue with threading in ASP.NET is that it runs in the same process as all your requests. Even if this weren't an issue in and of itself, IIS can be configured (and if you don't own the servers almost certainly will be configured) to shut down the app if it's inactive (which you mentioned) which can cause issues for these threads. I have seen solutions to that including making sure IIS never recycles the app pool to spawning a thread that hits the site to keep it alive even on hosted servers

Categories