Asp MVC, is session lost upon building solution? - asp.net-mvc

I 'm writting an application in ASP.NET MVC. Basically I have some pages which require user authentication. Upon user logon, I keep the user row in a session. So in my controller I can access to the user.ID without making extra queries.
When project is in debug mode I can only change things in the views. Not in the controller.
If I 'm not debugging, I can build the solution, and see the changes I made without running the project (with F5). BUT, it looses all session variables I have.
So basically for every no-matter how small change in the controller, I have to logoff, logon to see my changes.
Are those normal behaviours?

Like Dan stated, this is normal behavior. To make it easier (and slightly more robust) is to change your code slightly. This is of course assuming that you are storing more than just the User ID in session since you can access the User ID via Controller.User.Identity.Name when they are authenticated. So you perform the lookup of the additional data in the session object and if it doesn't return null then use it. If it does return null, then look up the additional information again based on the User ID and store it in the session again. This is the approach I take for storing information from Active Directory and it works great.

Yes, this is a normal behaviour of ASP.NET as a whole not just MVC.
If you need to recompile (e.g a change in controller or business object) you will be in a new session when you run in debug. Like you say, only changes in views or pages (which do not require a recompile) will allow you to see changes in same session.
Kindness,
Dan

Recompiling will clear all the current session data. However it will not clear your authentication ticket, that's stored as a cookie, so there's a few things you can do to avoid this.
If you only need to access the user id then use User.Indentity.Name
If you only need basic user data for display purposes, such as the user's name, then you can store that in a session cookie. Warning: only do this for displaying data unless you encrypt the cookie data, plain text cookie data shouldn't be trusted.
If your user data is more complex than that then access the data through a method that uses caching as suggested by Agent_9191
Add something like this to a base controller or extension method
protected UserData GetUserData() {
UserData user = HttpContext.Session["User"] as UserData;
if (user == null) {
user = UserDataRepository.GetUser(User.Identity.Name);
HttpContext.Session.Add("User", user);
}
return user;
}

Related

ASP.NET MVC4 How to post and retrieve data unique to a specific user

I have been learning how to use ASP.NET MVC4 and have been getting my head around authenticating users and user roles and posting data using the entity framework to SQL.
However I have not been able to find any guides/resources (maybe I don't know the correct term) for posting and retrieving data that is unique to an specific user. For example how would a user only see the entries that they created if it was a site that stored data that is personal to each user.
What patterns/designs does one use when trying to do this?
Creating a sandbox of data for a specific is usually tied to authentication. You can access this many ways through ASP.Net.
First of all, every user gets identified even if they never log in. They get a session identifier. It essentially creates a small place in memory for this user where you can store any user related information. Think of Sessions as walled gardens for each user.
Session["UserFullname"]
This works, but realize Session is limited by time, so it is very volatile. Utilize it, but don't depend on it.
The next method is to authenticate a User. This is done using Cookies, but usually handled transparently for you by ASP.Net Membership or other authentication providers. To access the authenticated User you just need to use a simple line in your Controller actions.
// User is the property
User.Identity.Name
Both these methods can store information about your user that you would use to query data specific to them.
Select * From Orders Where UserId = *User.Identity.Name*
Note that both Session and User are accessible through HttpContext.Current as well, as long as you are in a web environment.
HttpContext.Current.User
HttpContext.Current.Session
You won't need to access them this way unless you are not inside your Controller, or inside of another class that doesn't already give you access to the HttpContext. I don't recommend this way either, since your code could be used outside of a web application where HttpContext is not available.
I hope that makes sense, and please feel free to ask me questions.
This is not so much about mvc, but more about the problem of relating data to a specific user. You have to ask yourself, how would you identify a piece of data to a user.
The way you would do this is to tie the data to the user in the data store somehow.
In a relational database you would do this by having a User table and using the unique key on that table to insert data into another table such as Order. Order would then have a User Id.
When a user logs in, you could store that ID in session and use that to filter out orders based on the id.

Pass POCO around in a Asp.Net MVC application

I am having an Asp.Net MVC 3 app where i need to pass around a Viewmodel to different Views and i am wondering what is the correct approach to accomplish this.
Once the user logs in and gets the user object,i need to use the same user object to Views such as ViewUser, EditUser etc.I am currently passing the User id(Once the user logs in succesfully) in #html.actionlink method as objectroutes and getting the user object from the database every time.
Is this the right approach ? I didnt want to use Session.
Thanks !
Why don't you want to use Session? It's designed for this very scenario... to cache data that will be needed for the duration that a user is logged in.
When a view alters the User object (EditUser), just update the Session at the same time you update the database.

AuthorizeAttribute MVC - restrict access to user created content

So I read about how implementing your own authorization routines are bad!
http://www.nashcoding.com/2011/02/05/using-the-forms-authentication-membership-provider-on-appharbor/
And I got scared, because I've been implementing my actions as such (example, preventing access to account details if authenticated user is not the logged in user)
public ActionResult DisplayAccount(int someid){
Account a = context.Accounts.Single(a => a.id == someid);
// currentUserId() returns userid from FormsAuthentication
if (!a.owner == currentUserId()){
/* Not Authorised! */
}
}
Which apparently means it will break if ASP decides to cache my action (so the action doesn't even get executed).
So I'm now looking into using AuthorizeAttribute to do what I need to do, which is
prevent access to an action if not authenticated
check if authenticated user has access to the retrieved resource
However whenever I think about it, I can't think about how to implement the 2nd point. Roles don't work because its on a site wide level, but within the application there users have roles as well (e.g. Owner, Moderator, Contributor, User etc.), and they only have these roles within their respective parts of the application (e.g. owner of thread, contributor to wiki, moderator of forum etc.)
I have run into several examples of overriding AuthorizeCore. I can sort of imagine creating multiple AuthorizeAttribute subclasses for each resource I have (luckily not many), But just by looking at it, does that mean I have to query the database everytime I hit that action to ensure that the logged in user should be able to access that data, then query the database in my action to get the model, instead of doing that in my query?
So my questions are
am I getting too worried about caching too much? Will any of the following happen
website caches user A details, which is rendered on user B's screen?
website caches admin version of a page (with edit controls), and normal user sees cached version?
Using AuthorizeAttribute is a given, but how do I achieve what I need to do in point 2 without having to hit the database prior to the Action? Or what is the best way to achieve it in any case.
Or do I only use AuthorizeAttribute to determine if the user is logged in, and do other checking logic in my action?
Anyway, I hope this post isn't treading on any old paths (I couldn't find anything on this that I found definitive)
Edit: I guess, if I don't enable caching this problem wouldn't occur, is this correct?
Edit: for now, I am going to going to use vanilla AuthorizeAttribute, then check resource level access in my actions, then make sure I don't use caching for any authenticated actions. Hopefully will get more answers for this over the week.
I used the following approach in a recent project, by creating a DataRightsAttribute that used an enumeration for each supported model type. It works by first extracting the id from the route data, formcollection or querystring. Then it queried up the model type determined by the enum, and did the appropriate check to see if the current user is authorized to access it.
Usage was like this:
[DataRights(ModelType.Customer)]
This was used alongside AuthorizeAttribute (which we overrided), and never noticed any problems with caching.

Integrity of Hidden Fields: Asp.NET mvc

We have been using asp.net mvc for development. Sometimes, we need to put some hidden fields on form that are shoved in the model by modelbinder (as expected). Nowadays, users can easily temper the form using firebug or other utilities. The purpose of hidden field is mostly to provide some information back to server on as is basis and they are not meant to be changed.
For example in my edit employee form I can put EmployeeID in hidden field but if user changes the employeeID in hidden field, wrong employee will be updated in the database. in this scenario how can we keep the integrity of hidden fields.
You need to enforce security to ensure that the person doing the modification has permission to do so. I'd also put the id in the URL typically rather than a hidden field, relying on the security to ensure that people don't modify things that they shouldn't be able to. If they do have permission to modify the item when changing the id manually, it shouldn't be a problem. The important thing is to make sure that a person can't change the id manually and get access to something they shouldn't. Enforcing server side permissions solves this problem. You can easily do this using Roles in conjunction with the AuthorizeAttribute.
if user changes the employeeID in
hidden field, wrong employee will be
updated in the database
This is a major security hole in your website. In everything you do with web development, no matter how clever someone's code might be or how much you think you'll be ok as long as users don't do something, remember one golden rule: Never implicitly trust data received from the client.
In order to modify anything in your website, the user must be logged in. (Right?) So in any attempt a user makes to post a form to the website (especially one which can modify data), double-check that the user submitting the form has permission perform the action being requested on the data being specified.
Ideally, every action which isn't completely public and unsecured should have a server-side permissions check. Never, ever trust what the client sends you.
One potential alternative would be to store that static, single-use information in TempData on the server and not pass it to the client where it could be tampered with. Keep in mind that by default TempData uses Session and has limitations of its own - but it could be an option.

How to automatically maintain a table of users that have been authenticated by IIS 7.0 using Windows Authentication

I want to build and maintain a table of users. All users that access the ASP.NET MVC site are authenticated via Windows Authentication so they're bound to have a unique username. I'm grabbing the user name from:
System.Web.HttpContext.Current.User.Identity.Name
I feel like I could go two ways with this.
Anytime the user table or any tables that references the user table are accessed, I could add the user if it doesn't exist. I'm worried this might be very error prone if user's existance isn't checked.
Anytime the user visits any page on the site, check if that user exists in the db and if they don't exist, add the user. This may have a lot of overhead as it'll be checked every page change.
I'd like to hear which of these is the better solution and also how to implement them.
I think a better way would be something similar to the option two.
Anytime a user visits a page, check a session variable to see if that user was checked against the DB. If the session variable is not there, check if that user exists in the DB, add the user to your table if necessary, then set the session variable.
That way you don't have to hit the DB on every request.

Resources