Here's the issue at hand: I have developed an ASP.NET MVC3 application using Razor. I have also implemented a custom membership provider and overridden the ValidateUser() method. Within, I query my db and get a lot of user information in addition to the password auth.
At the moment, I am pushing this information, i.e. companyId, to static properties of a class. This works and I can display/use this information throughout my app. The problem arises when a user closes their browser tab. Upon re-opening the app, the user is authenticated via a cookie, so they don't need to re-login; however, those static variables are blown away.
So guys and girls, how would/do you conquer this issue? Should I append the extra info to the session cookie? Or perhaps a better solution?
Use the ProfileProvider in ASP.NET.
For application level variables, they are going to be subject to application pool recycles and similar "simulated" restarts related to users starting all over. These variables should be completely independent of user usage and should be able to be recreated easily. If you have variables that are user dependent or that can't be restored easily without some sort of outside intervention then you will definitely need a different method of storage.
If the data is user specific, storing it in the session cookie is probably the best idea. If the data is user-related but branches multiple users it should be stored in a database or a flat file somewhere. If the data has nothing to do with users specifically then it should just be in a database or configuration file.
Related
I have two different struts2 Applications, tried implementing SessionAware but still other application is not able to use the session variables set by first application.
If I am doing something wrong or is it not possible the way I am doing. Thanks
application, request, session and page scoped objects are only specific to one application.
Session variable is not the solution for your problem.
Let your Single Sign-On Application send those variables to both the applications as custom attributes. Just like the authenticated user name.
Or use a Database table to share the session info.
Note: You will run into race conditions unless app2 access is initiated from app1.
I am a relatively inexperienced programmer.
I have managed to build a web api which uses basic authentication as per the following:
https://weblog.west-wind.com/posts/2013/Apr/18/A-WebAPI-Basic-Authentication-Authorization-Filter which is working very nicely (forced over ssl obviously). Inside the OnAuthorizeUser i check the un/pw against an mssql database, via a call to an internal class called "DB" where all my database interaction occurs.
So all Controller methods are filtered by the Basic Authentication ("decorated" at the Controller level) however, access to certain Controller Methods also needs to be limited depending on the user - so there is a need to understand the user permissions. Based on my limited former ASP.NET experience I think I would have stored the relevant user details in a Session (or possibly cache) however I have so far steered clear of this based on wanting to stick to the concept of having a RESTful application etc
Rightly or wrongly, in playing around I realised I could use a private static (instance?) of my User class inside my internal DB class and populate it at the time of initial authorisation. I also added a public method (public User getThisUser()) to return the private User. From within my Controller methods I create an instance of DB and am able to check the values etc.
I was very worried that I would have issues with the "scope" of this "static" User, so to test, I created a Controller method to simply return the User information from DB.getThisUser(). In doing so I have found that I can log in as multiple different users (using different browsers concurrently for example) and each one consistently returns the correct user information (as logged in).
I'm still not entirely convinced this is "safe" however reading through the details of implementing something like ASP.NET Identity as a possible alternative makes my head spin and really seems like massive overkill in this case - I'm not using Entity Framework and after much searching I could not find a single example of NOT using an ORM (I need a solution to work with an existing DB).
Is this destined to fail? Do I go back to considering session or cache? Something else? I would really appreciate any feedback / advice on this from all of you who are more experienced than me. Thanks in advance for any help.
i think you're getting a bit confused.
an API is supposed to be stateless, meaning no session. Yes, you have a controller which translates into an endpoint.
You can hit an endpoint with all the information required to satisfy the request and this is it. Don't think of an API as an actual application where all requests are linked somehow. Instead, think of it at an application where each request is separate and can come from anywhere and any user.
How does the application know which user sent a request? Well, it doesn't unless you pass that information in.
You don't fire a request saying GetMeUserDetails. The api has no idea what you want. Instead you would say GetMeUserDetails for userId 12345. Now, since your request contains all the information required to satisfy the request, the API can now give you what you expect.
If some calls require authentication, you might use some sort of tokens to identify the user, but again, the information is passed in via the token.
You probably realize what static means and how it works. you are not going to see problems until you try to send two or more requests at the same time and then you'll realize that the first call now contains the details of the second request because well, static ...
When a user comes to our webset/webapp, we would like the user to be able to go around the site and do things as normal (currently the site consists of almost exclusively CRUD operations). That way the user can see what the site has to offer by DOING, before logging in.
We want to store all these operations in a session or temporarily in SQLAlchemy operations but not commited to the database.
Then, we'd like it if when the user creates an account or logs in, all those operations are done under that account name.
What is a good way to do this? Currently all our server-side functionality automatically does a SQLAlchemy commit after successful database operations. So I'm not sure if removing that and doing commits manually would be a good idea.
On the other hand, saving database operations in a session/cookie seems bad as well. Then we need to fake the database in cookies, which is ugly and a lot of work.
Note that we are using postgreSQL.
I think the best way would be to assign a temporary username to every user that visits the site & store that information in a SESSION cookie along with everything else they do while there. Then when they signup, you can move all those SESSION var's into the DB under their new username.
BTW, there's nothing wrong with saving anything in SESSION cookies, as long as you're using HTTPS (and it sounds like you should be using that for the site you've got). Anytime you're doing login stuff over HTTP, it's never safe/secure to store anything in cookies.
I am building an ASP.NET MVC3 app using Forms Authentication and I'd like to log out all existing sessions for a user when that user logs in. I'm trying to prevent multiple people at different workstations from logging in and working under the same account.
Is there a standard way of handling this? Logging out the existing session is easy, but I haven't come across a way to check for other sessions by the same account and log them out.
I have a few ideas on how to hack this, but I'm curious if there's an established method for this using IIS or the FormsAuthentication API.
Because of the statelessness of the web, you can't "log out" a session until they make their next request (for instance, session might be maintained in a cookie, which can't be written on the client outside of the context of a request-response interaction).
There is still a solution, which assumes you are using session state, and preferably you have a common base controller for all of your controllers requiring "Authentication".
Upon successful login, generate a token (a guid perhaps) and store that with the session. Also write this to a application-wide store (database or application context for instance) keyed by the userid.
In the Base Controller (or otherwise you'd have to create an action filter) check the token in session against the token registered for the userid in the application-wide store. If they don't match, log out the user using the standard SignOut() call.
You could use the Membership.IsOnline property which is based on LastActivityDate:
A user is considered online if the
current date and time minus the
UserIsOnlineTimeWindow property value
is earlier than the LastActivityDate
for the user.
I came up with an interesting way to solve the following problem and I want to know if there is a better way to achieve my objectives.
Basically, I'm creating a basic cms system users can register for their own microsite and have their own users. I'm using the asp.net membership api.
I wanted a way to isolate users of the various microsites from eachother so that a user authenticated with www.mysite.com/johns-site wouldn't also be authenticated with www.mysite.com/pauls-site.
I also wanted a way to associate a username with a microsite so that if a user is registered as bob on one site, it doesn't stop another user registering as bob for a different microsite.
To achieve this, I noticed that in the asp membership tables a user belongs to an application. Every time I receive a request, I have a method that switches the applicationName in the web.config based on the url.
This does meet my objectives in an easy way but feels a bit hacky. Is there an alternative way to switch applications for the membership provider?
It is possible to get/set the ApplicatioName property at run time however according to the below MSDN post it is not recommended as the property is not thread safe i.e. if multiple users are creating accounts for different applications at the same time it may not correctly allocate the ApplicationName per user.
Syntax:
Membership.ApplicationName = "MyAppName"
OR
Membership.ApplicationName = "MyAppName";
Further reading:
http://msdn.microsoft.com/en-us/library/system.web.security.membership.applicationname.aspx
Note:
You are updating the contents of the web.config file from the application code? If so this is most certainly "hacky". Plus editing the web.config will drop any active sessions (if your app uses session state of course).
I agree, it is a hack that will likely make you pay at some point.
The proper way to accomplish this would involve each virtual directory (or microsite as you say) each defining a <membership> element with the same connection string but different applicationName attribute.