Is asp.net core session not user specific? - asp.net-core

When i was working with classic ASP.NET or even with old web forms the HttpContext.Current.Session was User specific. So when user makes the request he receives the session cookie and then onward that session belongs to that user only. So two different users can have session key with the same name in their respective session.
I am reading the documenation on session in ASP.NET Core and looks like it has the same concept as old asp.net however certains notes in the documentation is confusing.
here it says
Session storage relies on a cookie-based identifier to access data
related to a given browser session (a series of requests from a
particular browser and machine). You can’t necessarily assume that a
session is restricted to a single user, so be careful what kind of
information you store in Session. It is a good place to store
application state that is specific to a particular session but which
doesn’t need to be persisted permanently
also here it says
Session is non-locking, so if two requests both attempt to modify the
contents of session, the last one will win. Further, Session is
implemented as a coherent session, which means that all of the
contents are stored together. This means that if two requests are
modifying different parts of the session (different keys), they may
still impact each other.
so lets say i have User1 logged in and upon some action i set
`Session.SetInt32("key1", 123)`
now User2 logs in from some other machine and upon some action i set
`Session.SetInt32("key1", 999)`
Question 1
Will this overwrite User1's key?
Also note here says
ASP.NET ships with several implementations of IDistributedCache,
including an in-memory option (to be used during development and
testing only)
Question 2
What are the other implementation of IDistributedCache that i can use in production?

For Question 1.
No, one user modifying a session key will not overwrite a different user's key. The session is unique to each visitor/user because of the .AspNetCore.Session cookie that is created.
All of the Session.Set calls get stored per that unique identifier.

#1
Session isn't tied to a user because session is only identified by it's session key, so if someone gets possession of the session key/cookie, he can access it.
Asp.Net Core Identity has its own cookie (if you are using cookie authentication) and Session middle ware use its own cookie too.
Naturally, you can also use Sessions without a user. Take Google.com for example. When you first visit Google, it shows you policies and set a session cookie. All settings you do (i.e. maturity filter), will be saved in the session which gets accessed each time you perform a search.
This all without being logged in, so there is no user at all.
#2
Open Source is your friend:
https://github.com/aspnet/Caching/tree/dev/src
Redis and SqlServer are the default distributed caches, with InMemory being for development / single-node only. There also may be other third party libraries which add support.

Related

how to restrict multiple login of the user

We want to restrict users to multiple login sessions at a time, there should be a single active login session.
Users should be allowed to be logged in to one application from only one browser at a time. When the user log in the server should check his current active sessions to the same application from other browsers. If there is then log out from everywhere else and keep only the newest session.
ASP.Net Core's default authentication cookie middleware has a handy hook (via the CookieAuthenticationOptions.SessionStore property and ITicketStore interface) to allow you to implement custom backend storage for the cookie payload (claims). The end result is a protected cookie containing just basic AuthenticationProperties values and the session ID as a claim and everything else stored in the DB, keyed off the user ID and session ID etc.
With this in place you can automatically invalidate any existing session for a given user account (the ID of which being an indexed field/property in your backing store) by deleting or otherwise expiring any other sessions.
This also has the advantage of allowing you to invalidate sessions based on other circumstances like a password or other security settings changing.
You could also implement something to trigger back channel logout calls to client applications if you also track which clients they've signed into in the given session in the backing store too.
Note: The SessionStore property is a singleton concurrently accessed instance so ensure your implementation handles database connectivity appropriately if you go this route. Note also that the wireup is best done via an implementation of IPostConfigureOptions<CookieAuthenticationOptions>
Change the security stamp SecurityStamp.AbpUsers when the user logins.
The previous logins becomes invalid.
https://github.com/aspnetboilerplate/aspnetboilerplate/issues/4821#issuecomment-524732321

Does HttpContext.Session in ASP.NET Core share session data between users?

We have an ASP.NET core application which stores objects from a user's session to record values before the information is added to the database.
We have an issue where two different users (on opposites side of the world) are able to influence one another's session and we can't understand why?
For example if User1 has a session variable set, the same value influences User2's session.
I have read previously that AspNetCore.Http.HttpContext.Session is unique per user here however the post is confusing and the answers contradict what Microsoft says.
Should I really be using HttpContext.Session to store data which should be unique at user-level and if not what should I use?

How are logged-in users remembered? (Using Pyramid and in general)

Main question:
Take your typical web application with login. Does it use a database to keep track of what users are currently logged in? (As opposed to remembering all users. I'm sure you need a database for that.)
I'm just starting to learn web development, and was wondering about the real-world way to remember users as logged in, as compared to simulated examples as on this Pyramid cookbook page. I could not yet find anything about the Pyramid-way of doing this, not by searching nor in the authentication-specific tutorials. Some tutorial compare the userid against a hard-coded list, others against a not-further-specified database. The question above is my guess after reading this post on correct practices of user authentication:
If you are unfamiliar with session data, here's how it works: A single randomly-generated string is stored in an expiring cookie and used to reference a collection of data - the session data - which is stored on the server. If you are using an MVC framework, this is undoubtedly handled already.
It would be cool if someone could clear this up!
Somewhat related: This question, about the same Pyramid example - it asks how secure the method is, while my question is about understanding the method.
...and was wondering about the real-world way to remember users as
logged in.
It's not the server (or not only the server) who needs to "remember the user as logged in", it's also the client who needs to remember.
Conceptually, it works like this: upon verifying the login credentials the server returns something which the client remembers. The client then needs to send that something with every request to the server. The server, on every request, checks that the provided value is correct, matches a user in the database, etc.
In a web application, the usual mechanism to store and automatically send that "key" to the server is via HTTP Cookies - basically, the server sends a Set-Cookie header and the browser stores the cookie and sends it back in the Cookie header on every request.
Regarding the actual payload of the cookie, there are two common approaches. One option is that upon login the server starts a "session" (which may be a row in some database table). The server then returns the ID of the session, which is a random unguessable string, to the client. To check that the particular session is active the server would need to consult the database on every request.
Another option, commonly used in Pyramid tutorials, is auth_tkt authentication: the server returns a cookie containing the actual user ID, cryptographically signed with a server-side secret. When the client sends the cookie back, the server can verify the signature and be sure the cookie hasn't been tampered with. In this case, there's nothing on the server side to keep track of "all logged in users" and no need to consult the session database.

.Net core 2.1 identity configureapplicationcookie session store vs addsession/usesessions

I am trying to figure out how to use .net core identity authentication with cookies and sessions. I want to be able to view currently logged in users/devices and revoke their sessions if necessary.
When doing services.ConfigureApplicationCookie() there is an option to specify a session store instead of keeping the user's login information/claims in a cookie. Can or should this session store be used for tracking users and logging them out? Or is this just supposed to be used for making the cookie size smaller?
I only need my session for authentication purposes (for a rest web api), I'm not sure if I need to separately use services.AddSession() and manually set session data when logging in and out - it seems the implementations I found for a RedisCacheTicketStore correctly add a cache entry on login and removes it on logout when I call signInManager.PasswordSignInAsync() and signInManager.SignOutAsync().
But I notice in those implementations the entry key is a randomly created GUID (similar to this implementation for a memory cache ticket store) - which means I would need to add something identifiable to the key like the user's ID to make it searchable or store that key again somewhere else?
I don't really want to use JWTs or IdentityServer / OpenID etc. if at all possible.

Implement user login/out without database using Play framework

I am using play framework to develop a web app. Now I need to implement authentication/authorisation without database (really strange requirement). There will only be log in and log out function, no registration. The username/password pair will be authenticated using external service.
Due to limited experience, my current idea is to use token to authenticate and a local file to store username/password.
Is my idea feasible? Is there any recommended libs? If I use token, do I need to pass that token in Http request/response every time and authenticate the token in every controller?
Thanks!
Why store user name and passwords in a local file? I don't see the point and this constitutes a database, which you want to avoid it seems... Deciding to work with local files will be an important limitation if you ever want to deploy more than one server and have some load-balancing done.
Playframework is stateless, meaning that the server doesn't keep session state. To work around that play uses signed session cookies (the browser is storing the session data, and cannot modify it as the session data is signed).
Here's what you can do:
on login: set some data in the session
on each subsequent request, determine the state (logged-in or not) based on the session cookie, see https://www.playframework.com/documentation/2.6.x/ScalaActionsComposition#Authentication
on logout: reset the session cookie
Now this approach has a serious downside, it allows people to replay (reuse) old session cookies to pretend being logged. Another (could be less serious depending on your requirements) is that it is not straightforward to implement session expiration after a certain inactivity.
This is probably enough to answer your question and give you a starting point.