My web application has 2 types of users: non-authenticated visitors and authenticated customers. I'd like the pages that visitors see to work with InProc session and, as soon as a user moves to the the login page, create a new session that works using SQL server session mode.
Is this possible and if so, how is it implemented?
Thanks for your suggestions.
You can only have one sessionMode per Application (Virtual Directory).
You can make 2 separate applications with single-sign-on , to the user it would look like 1 Application.
That is not 100% the same, authenticated users that visit the public pages would use InProc. Up to you if that matters.
On the other hand, are you sure this is worth the effort at all? You can't use the Session for data in a multi-server + InProc scenario anyway (that may depend on your IP setup). And storing (small amounts of) data in the SqlServer shouldn't be much of a problem.
Related
I wanted to try this code/solution to my ASP.net (VScode 1.69.1) but I am not sure where is the "Global.asax". Anyone know how I can apply the code below to asp.net core?
https://teknohippy.net/2008/08/21/stopping-aspnet-concurrent-logins/
I would not advise you to use that code, it wasn't even good advice back in 2015, but we can explore the concept and it's flaws which might help you come to a better overall solution.
This post will provide some context to the issue: Single Instance Login Implementation but is not a direct duplicate. The original source article does actually go into better detail about the general issues with this approach: http://www.nullskull.com/articles/20030418.asp
Using an In-Memory cache is not a viable option for production as multiple instances of the application would not share the same cache, especially if the application is hosted across multiple servers or serverless infrastructure that is configured to scale out beyond a single instance.
If all you want to do is block new logins, if the user is already logged in, then a server-based or cache concept itself is the right solution, conceptually to enforce a single instance across different browser sessions and across multiple servers will require that there is a server-side cache or store that holds the source of truth for all active connections. This could be in the form of a database or a distributed cache like REDIS.
But this is not a practical model for how users actually use their browsers and devices. Instead of blocking new logins, it is more practical from a user point of view to expire or force close the existing logins. The problem with only blocking new logins is that if the user doesn't have access to the original browser session that holds the login, then there is no way to log out the previous session, you would have to wait for it to timeout. The challenge with being able to expire a login session is that your clients and the server code must be designed to round-trip to the session store to validate the session token. Most default JWT or even cookie implementations do not do this, they will rely on the expiry or validity information in the token itself, and bypass consulting the store.
Instead of the article you have found, please try these resources:
ASP.NET Core security topics
Can I force a logout or expiration of a JWT token?
JSON Web Tokens (JWT) are Dangerous for User Sessions—Here’s a Solution
So I am new to the whole datacache thing. I am building an app for a client who has potential to grow substantially so I am using the datacache instead of Session variables so that I can have multiple servers.
I have been in development mode and this has worked just fine, but it has just been me.
Now we are testing and completely new people on a computer that have never been to the site before are being recognized as another user somehow...
I do use cookies to remember a user, but these guys are coming in for the first time so that can't be it. Never had this problem with Session variables so I must be doing something wrong with the datacache.
Why does the datacache confuse the users? How do I prevent this?
Thanks!
David
cache = server level, session = user level. Your server is saving the cache data and passing it along to the users. If you have intentions of having multiple users connected, and storing separate data for each, sessions is actually the correct way to do it.
As for performance, yes there will be a slight performance hit, but it shouldn't be too drastic unless you've got a massive amount of users hitting the site at one time or you're storing huge amounts of data to the session.
You need to use Session to store a logged in users credentials and other session specific information. Datacache is used to store application wide data that can be quickly accessed, things like xml files used on the website or perhaps a dataset used by anyone on the website. Session is a unique id and "thread" for each user for their specific user name and all other information related to their logged in id.
Maybe I'm missing some fundamentals about this, I just don't get why Form Authentication is not build in top of Session.
I've had some issues with Form Authentication timeout and Session timeout, I understand how to get arround those issues thanks to blog posts like this one.
But why are they separated?
I just don't get why Form Authentication is not build in top of Session.
Forms Authentication uses cookies which are common in all applications. Only the currently authenticated username is stored into the cookie. The session on the other hand could store arbitrarily large values as it is stored on the server. You cannot persist arbitrary large data into cookies. The session state has lots of problems. For example if you are running in a web farm you need to ensure that you are using an out-of-process session persistence instead of the default InProc so that all nodes of your web farm could share the same session data. Personally I never use sessions in my applications. The very first thing I do is to ensure that I disable all session state in my web.config:
<sessionState mode="Off" />
This way I am sure that no developer working on my projects would ever do the mistake of using ASP.NET sessions. They turn web applications which are intended to be stateless into stateful.
With cookies you do not have such problems. You could throw as many nodes you want to your web farm to face increasing user load without ever worrying about any state on the server.
Basic because some may chose to use only one of them, and because they are two different modules - and both gives the interface to make a custom one.
Also one user can have session with out have never been authenticated.
Also some other (like me) can made totally custom session module, but keep the Authentication module.
So this is two different modules and they can not be connected.
I'm re-writing a website from the ground up for azure. Each user has ownership of a number of objects, and has a number of permissions. Together, these determine what they are authorized to do. The question is, how should this information be stored. I want to do the authentication myself, using custom logic.
For performance reasons, I'd like to cache these authorization lists for each user once they're logged in. Can someone give me a sample for how to store & access this session information securely and efficiently.
Edit
I looked into the App Fabric Access Control, but that seemed overkill as I was going to have to create a separate site for authentication, which doesn't seem to make sense. Would the claims based authentication make sense separately though? How would you do that if it does?
Would it make more sense to just keep the username in a cookie in the traditional way and then re-query table storage with each request to get the permissions etc.? How would storing the username work in Azure?
Cost is a big factor here as it's a very small site (by azure standards) but I want high performance for a small number of users.
If you want to run with a reasonable amount of availability you need to run your site with two instances. If you're running with two instances you need to use a session provider that's no the default InProc one. Your choices are:
AppFabric Caching (which you don't want to use because it's too expensive, fair enough)
Azure Storage Session Provider. Don't use this. It's an interesting experiment, but it's only sample code, it's slow and doesn't cope well in production.
SQL Server session provider.
If the permissions for a user weren't going to change while they were logged in, you could just store their permissions in session. This will probably be fast enough. However this information will need to be read from SQL for each request that uses session and it is overhead.
If you wanted to make things faster you could just store the user ID in session and load the permissions into a static dictionary (keyed on user ID) when needed. These items will need to be expired after a certain amount of time or lack of use.
Well, you could use the Azure App Fabric cache to store the session info. ASP.Net can be configured to use it as the backing store for its session state as like a normal custom session state provider.
This article from MSDN shows you how to configure it:
http://msdn.microsoft.com/en-us/library/windowsazure/gg278339.aspx
From your code you just use the normal ASP.Net way to get/set the state.
Be aware though - it could be expensive ($45/month for 128MB of cache).
I have to design a CMS where a set of credentials can only be used once. So if a user has logged in from his computer, no-one can login with his credentials from another location until that user logs out.
Now using the asp.net membership provider out the box, the IsOnline method returns a boolean that reflects the timeout window vs. the last activity date. This is not a viable option for me, because if the user just closes the browser after logging in, IsOnline will still be true. But his session will be destroyed(assuming he's not using Remember Me) so if he tries to log in somewhere else it will say "Sorry you still logged in".
Are there any hard and fast options for doing this..?
I was thinking of forcing the users to be "Remembered" so when he logs in a boolean "IsReallyOnline" will be set to true and vice versa when he logs out.. Although this option has it's limitations, (people turn off cookies, not logging out and closing the browser then sum1 else comes and browser to the site and he's logged in etc....) it seems like the most viable for now?
Any suggestions?
Thanks in advance
You are really asking for something that is outside of the remit of the web. The HTTP protocol is by definition stateless, meaning that at any one time; a server never need know if a client still exists. The newer/older implementations of web server programming languages (e.g. php / asp.net mvc) for the most part shy away from storing any state about connected/active clients.
Some things to ask yourself include:
How long may a user be 'active' on a page without causing a postback? Javascript based pages may allow for a user to interactively be using a page for quite some time before any kind of postback happens.
Will the users be going through a proxy or caching server? Multiple requests from 'different' users may come from the same machine in this case.
Will your application be running on one machine only, or maybe a server farm? You'll need to ensure that load balancing (for example) doesn't punt different users onto different servers allowing multiple logins.
How about a user legitimately using two different browsers on the same machine? Is this to be allowed?
One might suggest your problem here stems from trying to use the wrong technology given your requirements? Maybe writing a client application which uses direct connection to your servers would be more 'secure'? (Yes I understand this is huge hassles but if your one user / one logon requirement is absolute maybe you could explore this avenue?)
Oh alright, a web solution
For a http centric solution you could try a javascript timer making a request to your server every X seconds to indicate that the session is still active. As long as the browser is open and the network connection valid you should be getting these 'pings'. The session is kept open by the cookie passed by the httprequest.
You'll be able to code the 'ping' page to store the user details into either the application object or some membership provider of your choice then interrogate this provider whenever a client attempts to log in.
This will require a relatively short time-out on a session or some other mechanism to ensure that a crashed browser doesn't lock your legitimate user out for too long.
Please note: This will fail horribly if the user doesn't have javascript turned on (Don't assume that they will have!)
Fast Option: Store IsOnline as a session.
Check if session is true, then allow. If not, don't allow.
If user closes browser, he will be logged outas its in a session.