Options for storing user information while logged in - c#

What are some options in regards to maintaining user data while they are logged into my mvc4 site? I am building off of the Internet Application template and right now I am using User.Identity.Name to get the logged in user's username that they used to login with. I'd like to be able to also store and access several other pieces of information about the user across every page on the site. Can I still use User.Identity somehow and apply other attributes to it? I started building a ProfileModel that I could pass to views, but then I don't believe I would be able to pass other models to those views, not sure.
I'm open to suggestions as far as persistent user data, and thank you for any help.
EDIT 1: When I say persistent, I mean while they are logged in, the data itself is already stored in an external database, so I won't be doing any writing of this information, simply pulling it from the database, then holding onto it for the duration of them being logged in.

You'll want to leverage Session for that. Consider the following code:
Session["Profile"] = profileObj;
or maybe you just want to store a string:
Session["SomeSetting"] = value;
What you need to store in Session is unclear, and effectively irrelevant, you can store anything. You can access the Session from any Controller.
Then later on you can get the value out like this:
var profile = Session["Profile"];
// if the profile variable is null then it doesn't exist in Session yet
In response to #AaronLS, Session lasts the duration of the IIS session that's created when the user first accesses the site. Do keep in mind that these sessions are reset if inactive for a period of time (I believe the default IIS timeout is 20 minutes) so you'd want to leverage the null return value to know that you need to redirect the user to the login page to login again.

Related

How to Logout user from a particular session Identity Server 4, .Net Core?

Using Identity Serve 4 with .Net Core 3.1, razor pages. Also using Cookie Authentication
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
Problem -
In a web application John logged-in 2 times
1st Login on Chrome
2nd Login on edge
So, if John again trying to logged-in on 3rd time on Firefox without logout from previous browsers, then I want to logout John from 1st Login on Chrome forcefully.
I can keep the track of logins in a Session table including Session Id, User Id etc.
But I don’t know how logout user from a particular session using Session Id.
Please help.
Thanks
ASP.NET Core provides an ITicketStore interface which allows you to get control of storing user sessions. Once you provide a class implementing this interface and register it, it will call your class when sessions are being created or verified which you can then store in a database however you like, including attaching arbitrary metadata like browser ID etc.
Now that you have user sessions in your database, you can separately query them and revoke as needed in other logic, including during logins. Since you now provide the session data, simply deleting the record effectively logs the user out from that session. Note that if you use any caching layer to reduce the store requests, you'd need to remove any cached copies as well.
Note that this is separate from IdentityServer and happens with ASP.NET Core itself.
This is a good tutorial that helped me implementing this in my app.
A sample of how it looks to register in Startup, where PersistentTicketStore is my implementation:
// Persistent ticket/cookie store to provide durable user sessions
services.AddSingleton<IUserSessionRepository, UserSessionRepository>();
services.AddSingleton<ITicketStore, PersistentTicketStore>();
services.AddOptions<CookieAuthenticationOptions>(CookieAuthenticationDefaults.AuthenticationScheme)
.Configure<ITicketStore>((options, store) => options.SessionStore = store);
Use the End Session Endpoint
The end session endpoint can be used to end a session and trigger a log out
In the log in process you will need to capture the id_token received from authentication and what user it belongs and store it on some dbo.table. You can use this same table to also keep track if a user has logged in more than once.
To log out a user or end a session you will need to pass the ID you saved as a query string parameter called id_token_hint in a GET call as shown below into:
GET /connect/endsession?id_token_hint={id_token}
For reference see the documentation here https://identityserver4.readthedocs.io/en/latest/endpoints/endsession.html#end-session-endpoint
Since you're saying you can keep track of logins, perhaps you should keep track of each session and assign a number somewhere indicating when it was logged in (1 for Chrome, 2 for edge, 3 for Firefox).
Then each time a request is made, you check in your table what the lowest number is (1,2,3 etc), and if the session matches that number, you sign the user out from that session.
await
HttpContext.SignOutAsync(IdentityServerConstants.DefaultCookieAuthenticationScheme);
Since each browser will have their own cookie, you can use the above method.
After signing someone out, the next login can be assigned 4, and if 2 makes a request you log that client out.....
Also see this: https://github.com/IdentityServer/IdentityServer4/issues/736
I have implemented this.
When a user logs in, the session id (IUserSession.GetSessionIdAsync) is manually stored in our database. The previous value of this database field is used to create a logout_token which I send to my clients. You can have look at IdentityServer4.Infrastructure.BackChannelLogoutClient to figure out how to create the token and post.
All this assumes you have backchannel logout implemented ofcourse.

Can't determine if my asp.net session implementation is correct

I am very confused in my implementation of sessions in asp.net web application. My logic is once user enters user name+password, I validate credentials and then create a new session with some user info[All I am after from this point onward is that this user has access to restricted resources and a user must never be able to access those resources unless he/she is authenticated]. This I validate on each request and the rest. Here is my issue though. I have many places in the website where I have html links, and I read that if I have a link such as
<a href='resource1.aspx'>resource 1</a>
This will generate a new session id, hence in reality invalidating the existing session id, which in my case will be treated as session expired and user is sent to login page. While reading up on this issue I came across an asp.net API method[
Response.ApplyAppPathModifier(url);
] which prepends the session id to each request hence resolving the new session id generation for each link. Though it resolves session breaking issue it does add the session id next to all of the urls and now session id can be seen in the source code( view source for web page). I really don't want to use cookies and want to use session for user sessions...Can some one please help me create a system which will work the way I wish it to ? if I am doing it utterly incorrect, I would really really appreciate a details discussion and if possible some example...Thanks you much in advance..
It looks like you are trying to use cookieless sessions which add a session id to all links in order to be able to track the sessions.
The other (much more common, standard and IMO secure) approach is to use normal sessions, which auto creates a session cookie (when you use the .Session object), and uses that to determin the current session. If you don't want a cookie you'll have to stick with cookieless, and the session id in the url.

Creating unique sessions per user on Webforms ASP.net

We are currently developing a simple system on ASP.net which are going to be used by users simultaneously. What I want to happen is to get each users' Name (or any other useful info) from a SQL table every time they log in to the system and use this data all throughout (Note: this data should be unique per user).
Now my question is, what is the proper approach on this kind of scenario to give unique variable/session per user? And what if I want to make this variable a global one?
Sample Scenario: A doctor logs in to the system and the code behind gets his name from the table and prompts the data on the homepage - "Welcome Doctor John!" (assuming his name is doctor John. Another user logs in to the system, gets his name and prompts respectively, now the conflict arises if the first user - John, refreshes the page and this is the conflict that I want to avoid.
Any article that I could read on with regards the matter? Any help would be much appreciated.
Disclaimer: I am still a beginner when it comes to ASP.net so my apologies for such simple question.
Session is where you will keep this information. It will be unique for each user. Read more about it at: ASP.NET Session State Overview
Just remember, that Sessions are maintained on Server for each user. They are costly. So if you keep too much data in your session then you may end up claiming more resources on the server.
Consider the following example where you retrieve your UserInfo in an object from Database.
UserInfo userInfo = GetUserInfoFromDB();
To Store information in Session:
//once user is authenticated
//store session
Session["UserInfo"] = userInfo;
To Retrieve information:
UserInfo currentUserInfo = Session["UserInfo"] as UserInfo;
if(currentUserInfo != null)
{
//info found
// assign lable Text currentUserInfo.UserName etc
}
You may see: Exploring Session in ASP.NET - Code Project
Just use the Builtin Session Management. It is unique to the user.
The Session Management stores, by default, a cookie at the users browser
to identifiy them. Only a Session Id is stored at the users browser and the other information, in your case the name, is stored on the server. You can define a Session Database for example if you have multiple webservers and want a single point to store the data.
If you have a single webserver it is very easy to use out of the box.
Set a Session variable.
Session["UserName"] = yourUsernameVariable;
Retrieve a Session variable.
var userName = Session["UserName"];
Here are some tutorials.
A Beginner's Tutorial on ASP.NET State Management
Exploring Session in ASP.NET
ASP.NET Session State Overview

ASP.NET Kill Session By Id

My application has a control of User Permissions, because not all users can access full website. At this moment, all those permissions for an specific user are stored in his session, 'cause It would be a problem for me to search at Database every Post Back.
The problem is that when I remove a permission, user can still access the page, and only when he closes the browser, the update take effect.
Is there a way to Kill an specific Application Session by the ID, forcing user to Log in again?
"Is there a way to Kill an specific Application Session by the ID, forcing user to Log in again?"
No. You can only access the Session object of the user doing the current request (i.e. yourself), not other users Session objects.
So, you need to store the id of the user somewhere else, for example in a static collection. When the user makes the next request you can check if the id is in the collection, and update the permissions or log out the user.
Another alternative would be to keep the permission objects of all currently logged in users in a static collection as well as in their Session variable. That way you would be able to change the permission object without accessing the Session object of that user.
Using static variables in a web application of course comes with the usual precautions. As multiple threads can access it, the access has to be synchonised. Also, as Alexei Levenkov pointed out, if you have multiple servers you have to keep the data synchonised between the servers.
You can write Session.Abandon(); or Session.Clear();
or Session.SessionID[int index];
store the particular user session value in this and then use Session.Abandon(); and Session.Clear();
For killing a particular session try using Session.Remove("key");
To remove a particular piece of Session, then use Session.Remove(), like this:
Session.Remove("YourKey");
Note: This removes the value and the key from Session, while you may see people use Session["YourKey"] = null; that will only remove the value, but leave the key. This may or may not be what you want, but just wanted to point out the distinction.

How to Remain loggin throughout the website

I am facing a very basic problem while building a website ; The website have 10 pages , The problem is that when i login once how can i remain logged in through out the rest of the pages ??
Since this question includes tags for asp.net and sesion variables, I'm not sure what you are missing.
On login form:
if (authentaionSuceeded){
HttpContext.Current.Session["loggedin"]="yes";
}
On all other pages (except for logout)
if (HttpContext.Current.Session["loggedin"]=="yes"){
// whatever you do for logged in users.
}
That's the basic idea. Although I prefer to access the session variable through an extension method/class that provides a type safety and a list of all session variables. The example in that answer is in VB, but you can do the same thing in c#.
There are some possible solutions as below:
Cookies: Store session information in the cookies in the page header
Hidden Form Fields: Maintain the session information in some hidden fields in the page forms
In each option, you need to generate the session key(some encrypted unique key) on the server side and on subsequent request, you should be able to validate that session key. Its better to regenerate a new session key on each request and expire it after certain interval. So for active user, it will keep getting new keys, but inactive user session will simply expire.

Categories