I need all active users logged on my website. I know I can take my logged-in user:
var currentUser = manager.FindById(User.Identity.GetUserId());
but how can I take all?
ASP.NET membership has a feature that works for FormsAuthentication. Otherwise you need to write to a persistent store somewhere the most recent activity date & then query that table for all users active within a certain window. A web app is stateless, so "actively logged" in is a fictional abstraction we imagine over a stateless protocol. After a request is over the server has forgotten about you. Another hack might be to count how many sessions are still alive if you are using sql session store.
Create a field in user table named "IsLogin".
Set IsLogin = 0 when user Signup.
Update the field whenever user logged in to the system i.e. IsLogin = 1
Now in order to get all logged-in users :
Check all records in a user table whose have IsLogin = 1
Your choice save the result in user object or just store ids or names of those users who are logged-in
Hence you store the result in array or any collection (i.e List)
Now you can easily enumerate list from start till end to get all logged-in users.
I used this method, It is the most recommended way.
Related
In an MVC application, for a given action that all users are authorized to perform, I would like to filter results based on the user's group membership. For instance ...
Users in GroupA should only see records pertaining to BuildingX.
Users in GroupB should only see records pertaining to BuildingY.
Users in GroupC should see all records.
I have no problem using authorization filters to restrict access to Actions, but I'm having a much harder time finding how to restrict access to data short of explicitly modifying statements every place where data is fetched.
Assuming your records are in a database, the roles membership model doesn't extend to the database out of the box. You can build a roles-based access control for your database, but you will likely save time using a simpler approach. For example, using code like this in your controller:
if (Roles.IsUserInRole("GroupA")) {
// Get data for GroupA.
}
// Display data...
A year later, working on a different but related issue, I found the EntityFramework.DynamicFilters package which does exactly what I need!
Scenario:
(with an ASP.NET web app - Core or MVC)
I have a database with Users and Items for each user.
That means the UserId is a foreign key in the Items table.
From the browser I login as a User. I get my Items as a list of ItemViewModels, which are mapped (AutoMapper) to ItemViewModels via a simple api GET request.
I want to update one of the items (which should belong to me - the logged in user) via a simple API call. So I send the modified item back to the server via a PUT request as an ItemViewModel.
First approach:
The simplest approach would be to include the Item's database ID, ItemId, in the ItemViewModel - so when I receive the item to be updated as an ItemViewModel, I can map it back to the existing item in the database.
This however sounds pretty unsafe to me, as anyone could modify the PUT request with any ItemId and affect items which don't belong to the user who executed the request. Is there anything I'm missing about this approach?
Second approach:
Don't pass the database PK ItemId in the ItemViewModel.
Instead use an additional form of identification: let's say that user X has 10 items. And they are numbered from 1 to 10 using a property named UserItemId(which also exists in the database).
I can then pass this UserItemId in the ItemViewModel and when I get it back I can map it to an existing Item in the database (if all was ok with the request) or discard it and reject the request if the UserItemId didn't match anything from the logged in user's items.
Is anyone using this approach?
Pros:
The user only has access to it's own items and can't affect anyone else's since it doesn't know the actual Item ID (primary key), and any modifications are restricted to it's items.
Cons:
A great deal of extra management must be implemented on the server side for this approach to work.
Any other approaches ?
Please consider that the case mentioned above applies to all entities in the database which a client side implementation can CRUD, so it's not just the simple case described above.
The proposed solution should work for the entire app data.
I know this question has been asked here and here but the first one doesn't have a satisfying answer and I don't think the second one really applies to my situation, since it just deals with the UserId.
Thanks.
EDIT
Please consider the Item above as an aggregate root which contains multiple complex subItems each with a table in the db. And the question applies for them as much as for the main Item. That means that each subItem is passed as a ViewModel to the client.
I should mention that regarding further securing the update request:
For the first approach I can easily check if the user is allowed to change the item. But I should do this for all subItems too.
For the second approach I can check if the user can update the Item as follows: I get the userItemId of the incoming ViewModel -> I get all the logged in user's items from the database and try to find a match with the same userItemId, if I get a hit then I proceed with the update.
I think your application is not secure, if you only hide the Id.
You must check, before changing the database entity, if the user is allowed to change the entity.
In your case you should check, if your Id from the authenticated user is the UserId in your item.
If your ViewModel ist similar or identical for your API you could use a FilterAttribute in your controller.
I am writing an application in asp.mvc. I have a view that displays a Product with specific id and on with that view user can modify the Product. There is a dropdown list with colors, that user can select. Range of available colors depends on user's permissions, not all users have access to all colors.
When user clicks "Save" button an ajax request us sent to server with ids of Product and selected color.
Here is the problem:
When user opens the page I check if he is authorized to edit the product with id provided in url and I display only those colors that user can access. But I have no guarantee that user modifies the ajax request sent when he saves the Product. So I can display Product with id 1, and colors with id 12, 13, 14, but user can manually alter the request and change Product id to 3 (which he is not permitted to edit) and select color to 15 (which he shouldn't even see).
In good old webforms this wasn't a problem, because id of product could have been saved in viewstate, and on server side I checked which index of dropdown was selected and then I knew what is the id of selected item (stored in viewstate or controlstate). How do you solve this problem in MVC? Do I have to check if user has access to each element twice, when I display the data and when I receive it, for example in "Save" request?
Even ViewState without protection and care can expose your web server to malicious content. Please note:
Because it's composed of plain text, the view state could be tampered with. Although programmers are not supposed to store sensitive data in the view state (credit card numbers, passwords, or connection strings, for example), it goes without saying that the view state can be used to carry out attacks on the server. View state is not a security hole per se, but just like query strings and other hidden fields you may have used in the past, it's a potential vehicle for malicious code. Since the view state is encoded, protected, and validated, it does provide more security features than other hidden fields that you may use for your own programming purposes.
as Dino Esposito states here.
You've got three options:
Protect (encrypt) your hidden fields (current productId and colors) and validate them on server after a user posts.
Use sessions (store current user's working context, i.e. productId and colors), in case option 3 is too resource consuming or you don't want to maintain huge amount of validation logic on server.
Validate permissions for the objects after user posts. In case option 2 cannot be accepted (you don't use sessions at all).
I agree with RononDex's answer. Session provides you with an easy means of storing data on the server for the user, without exposing that data in way they can manipulate.
So you could store the product ID like so:
Session["ProductId"] = however you get the id.
Plus you can store the colours:
Session["Colours"] = // Whatever you want, an array of int or List<int>
There are caveats with session state though, including that it can be wiped, be it by an expiration of that session (which you can control the number of minutes before that takes place), or an application pool refresh, so bear that in mind.
This might also be good reading for you:
http://brockallen.com/2012/04/07/think-twice-about-using-session-state/
So there are pros and cons to session state. If you decide to not use session state, and instead store the ID values in hidden fields in the HMTL, then please do consider hashing, or encrypting, those ID values so that a user cannot see what they are, or try to alter them.
TempData is used in cases to maintain state, it is stored on the server for one user request.
Im a new ASP MVC learner, Im working on a small pieces and getting stuck. The scenario is that user is creating new account in which accountID is automatically created by SQL. I want to pass this ID to the next step, let user input name and address. How would I pass this ID or any solution for this scenario? Think about passing data by TempData or Session but I'm not sure.
TempData will save the data until the end of your subsequent request.
There is also ViewBag/ViewData, which are really the same dictionary, are shorter lasting and they last only until the end of the current request.
Session lasts for as long as the user's session is open.
I believe TempData fits your bill, if "next step" means passing the data to a subsequent view, but if you need the data to be more durable, Session is the way to go.
I think you are approaching this incorrectly. You should have the user fill out all the information first, and then do all the registration, including creating the user and storing the data from the various steps all at the end.
If you do things the way you suggest, you will end up with partially registered users. They will create an account, and then maybe close their browser and never finish the rest. You will now have to write extra code to check all this every time they log in.
It's better to simply have your registration process do this all at once as an all or nothing process.
Just use the same process you would use for your login form. If the user is already entered in the database, you might as well treat them as a logged-in user that does not have a fully filled profile, yet.
In ASP.NET MVC, this would - in a lot of cases - be solved by setting the Forms Authentication cookie to the newly registered username
FormsAuthentication.SetAuthCookie(newUser.Logon, false);
I think that storing the user id in TempData or Session is the wrong scope for that. For all normal purposes, a user that just registered to your website can be treated as logged in after the record has been inserted in the user database.
You can try this way -
Create the user (username and password will be the values from your form):
WebSecurity.CreateUserAndAccount(username, password);
And then do this:
int userID = 0;
userID = WebSecurity.GetUserId(username);
Hope that helps.
This is probably a newbie question.
I have a table USER which contains info about login, pass and authorities. Depending on authority or role, detail information about each user can be found in one of following: Teacher, Student, Parent. When the User logs in, the information stored in USER table can be easly taken from security context.
I want to display first name and last name all the time in the header after log in - these can be fetched from the other tables.
My question is this: how do I handle storing one of these objects in session all the time? Or is it okay just to store User (its stored by spring) and then fetch particular table every time I need detail information?
I use spring security 3, hibernate, jsp, sitemash.
For more clarification:
I know how to deal with logged user and to restrict some content. Login details (id, pass, role) are stored in USER table and this is ok - I can fetch it and show whereever I want. The problem is that the details about a particular user (address, name, email, etc) are stored in in another table (STUDENT, TEACHER, PARENT - depending on the role in USER table). This is what I want to know on every page - for example to show his/her name.
TO cut it short -
1. you need to extend spring User to provide additional fields.
2. you need to implement UserDetailsService interface and reference it in the security context.
3. Now you can fetch your object in a controller like this: authentication.getPrincipal() - rememebr to cast to your type.
Additionaly - personally i always have AbstracController which is a base for every controller in my project. There, among others, I have method which returns current principal.