Currently i'm searching for a technique to create a named user license system
with asp.net mvc. For example a customer has bought 10 user licenses, it should
only be possible, to log in 10 times parallel.
The problem I'm struggeling with, is the fact that there is no permanent
connection in web technologies. (Between client and server, besides using web sockets or some similar things).
Or is there a well known and good alternative?
Thank you very much!
A possible solution (which may or may not be the right one for you), is to store the amount of sessions a user currently has and is allowed to have in two columns in your database.
Let's say you have the functions login(username, password) and logout(username), or something similar. Then, you need two new columns in your database, one storing the maximum amount of sessions a user can have, e.g. maxSessions , the other one containing the current count of sessions a user has, e.g. curSessions.
Now you can check with every call of login(username, password) if a user has reached the maximum of allowed sessions, and deny his access to your service. If he hasn't, add 1 to curSessions, then run your other login code. If logout(username) gets called, remove 1 from curSessions, and run your logout code.
If I understood your question the right way, this is what you were looking for.
Related
My Problem:
My app has number of pages/resources that should be accessible by guest users but only after providing correct pair [Resource Code - Unique Token] (each page has one Page Code and multiple unique "Tokens" issued for each user). Tokens are generated beforehand and stored in DB. After accessing the page, user will be able to interact with multiple other resources belonging to particular page.
How I organized this so far:
Page asks user to provide token and checks it with records in DB. If this is a correct token for resource requested, it writes cookie and then, every time user interacts with the resource or its content, controller will every time read cookie and check [PageCode-Token] pair with database before continuing the action.
Question:
Is there any other, more elegant and efficient approach? Should I use Session instead? I feel a bit bad about querying DB every time.
This depends on how many users access your service, if the volume is too large it would be recommended to create a cache where all tokens are stored, thus avoiding a database overload. However if the service is not widely used this is not necessary as a database can handle a lot of requests.
You could create a cache in two ways, using ready-made software or create a small cache within the project itself.
If you choose to use software, I would recommend Redis, it is a cache database that stores values with or without a timeout, ie after a while the tokens are deleted.
Keep in mind that this does not prevent you from making requests to the database, but you will always make requests to the cache first (Redis) and if the value does not exist, it is necessary to search within the database.
But if you choose to create your own, you will need to do most things manually and always knowing how much resources can be allocated. It may be more advantageous to use software than reinvent the stone.
I have somewhat of a thought problem, where I'm not sure if what I already built can be done a lot more efficiently, so that's why I'll share my 'problem' here. (to be clear, everything I have built works, I'm just looking to make it more efficient).
I have a webapp made with MVC & SQL which has a log-in system etc for users.
A user has a status, which is an enum, and can be active, blocked etc and is stored in the database (along with other user-data).
Within my webapp I have made a custom AuthorizeAttr. for authorizing users on every call made (applied as a global filter).
However, the 'normal' authentication is based on the cookie, which does not change when I would change the user-status in the database. For instance, users can de-activate another user in the same group (when being Admin). These database changes are not taking immediate effect since by default the authorization only verifies the cookie, and the cookie is based on the status when logging in.
To fix this issue, I added some additional logic to my authorizationAttr, which on every request calls the database for the current user status (the enum), and then simply does some checks whether the user is allowed to continue, or a redirect is required.
Calling the database on every request seems (even just for 1 enum) seems to be a bit taxing on the server/db especially when the webapp would grow in popularity (= lots of users).
One idea I thought of was to cache the enum in session cache but for short periods of time (like 60 seconds), this would save some database calls, but obviously the user can still use the webapp for max 60seconds after being de-activated.
I could be wrong in thinking that these database calls are actually that taxing of course.
Any ideas for improvement?
how do you know that checking status per request is too expensive? did you measure performance cost of checking user status in the database? have you created your custom cache without actually measuring the cost of simple solution? do you use ORM like hibernate? they have 2nd level cache built in so often there will be no roundtrip to the database.
i think it's way better to stick to the KISS principle rather than creating custom solution for a difficult problem. even if your database will be the bottleneck then usually buying additional hardware once is cheaper than maintaining overcomplicated solution for years
if your application grow, first thing you throw away is relation database
Have you considered using ADO.NET DataSets for your requirement? If you don't have multiple front-ends you could possibly read the login statuses initially into the dataset. All read/write operations could be made to this and you could later save your changes to the actual database. In case you have multiple front-ends, would it be possible for you to restrict all read/write/modify operations of one group to a single front-end instance? Because I guess you could use the dataset approach in that case as well.
C# - ASP MVC - .NET 4.5 - Bootstrap - Razor
I have a form wizard (http://vadimg.com/twitter-bootstrap-wizard-example/examples/basic.html) that is used to setup a complex object (obj1). A property of obj1 is a List<obj2>. On one step of the wizard I want to add multiple obj2's to the list. Since obj2 is slightly complex as well, I thought I would use another wizard to help build it. Except I need to persist this List<obj2> on wizard 1, while I'm off in wizard 2 building another obj2.
My first thought was to use a session to hold the List<obj2>, I was just wondering if that's a good option, or if there would be a better one? The user may leave from Wizard1 to go to Wizard2 and come back multiple times.
There's no perfect answer here; each approach has trade-offs. But here are some options that I can think of (and these are independent of ASP.NET/C#)
Session (as you suggest)
This will store data in web server memory (by default). If you have a lot of users, this could be a problem.
You risk the information being lost when the user gets a new cookie/the session times out.
Potentially better performance that a db, depending again on the number of users
Database (as you mentioned)
Could cause more database traffic.
Can save information for user even if they close a browser, switch computer, the power goes out, etc.
Maybe a separate NoSQL database just for transient wizard data would be worth trying.
Cookie (store data on the user's computer)
Users can potentially tamper with/view the data
There is a limit on cookie size (4 KB each?)
Local storage (HTML5)
Similar to cookies
But not such a small limit
Not every browser supports it (may need polyfill)
Form/Post/Hidden/ViewState
You could just post the data and drag the information from response to response
But this gets really annoying with back buttons & timeouts
Lots of work, and again, the user can tamper with the information
I have a small web application that has multi-language support (en, de, it, fr, nl, sl, hr). This application is accessed constantly from a lot of users that use it for a short time (the time to fill their data to get an internet access code).
I have a problem with setting the culture similar to this thread:
InitializeCulture change language of domain
I know how to do it, it's just that I'm not sure which state-management to use. I wanted to ask for suggestions which method to use. Those are my thoughts:
Session - the easiest way and the more elegant, but it's server side and I have a lot of requests so I fear that the server can get too overloaded
Cookie - easy to implement and it's client side, but some users have cookies disabled in their browser
QueryString - not so easy to implement in this phase, but it's client side and can be easily tested because the application has only 3 forms (3 URLs to add query string parameters)
I'd like to hear your ideas and suggestions.
Thank you in advance!
Actual persistence store would actually depend upon the scope/life-time of culture selection. For example, if it's user specific selection that has to be persisted over sessions then you can use database or persistent cookie where cookie will remember for a machine and database will remember across machines. The retrieval (from database) will happen when it's needed - and the value can be cached into ASP.NET cache (will need different key per user) or session or view-state (if its single page application) etc.
You shouldn't worry too much about putting that into session if you are already using session state for something else. In such case, it doesn't really consume any significant memory. If you have log out function then you can explicitly clear the session state and release that little bit of memory. If you don't have log out functionality then you can use small value for session timeout.
Good afternoon - I have a pretty general question today - I've been tasked with creating a web application to manage some basic information on customers. It's a very simple application, but what I don't know is what to keep in mind to develop the site around supporting multiple users at their own domains or subdomains of our url?
How would I restrict users from logging in to each others portion of the app?
I've seen mention of database scoping in similar questions on Stack Overflow, could anybody elaborate on best practices for an implementation like this?
Are there any new features in MVC3 to support multi-tenancy? I am facing this issue with MVC2 and my eCommerce site where we decided we wanted it white-labeled and customizable for multiple shop owners, and don't know where to begin in implementing these features in an existing application. Any input is appreciated.
edit
To elaborate on multi-tenancy, what I mean - in the context of a store for example, multiple users sign up for their own store at www.mystore.com and are each given a unique subdomain to access their own instance of the store, at user1.mystore.com, user2.mystore.com etc. Each store would have customers with order histories, and those customers would have logins. I would need to restrict customers of user1.mystore.com from logging in at user2.mystore.com without a new account, and likewise prevent user2.mystore.com from accessing user1.mystore.com's customer history.
I implemented a complete MVC multi-tennant app. Here are some links I found handy and some sample apps:
http://msdn.microsoft.com/en-us/library/aa479086.aspx
http://codeofrob.com/archive/2010/02/14/multi-tenancy-in-asp.net-mvc-controller-actions-part-i.aspx
http://www.developer.com/design/article.php/10925_3801931_2/Introduction-to-Multi-Tenant-Architecture.htm
http://msdn.microsoft.com/en-us/library/aa479086.aspx#mlttntda_cc
http://lukesampson.com/post/303245177/subdomains-for-a-single-application-with-asp-net-mvc
http://code.google.com/p/multimvc/
http://www.paulstovell.com/widgets
http://www.agileatwork.com/bolt-on-multi-tenancy-in-asp-net-mvc-with-unity-and-nhibernate/
http://ayende.com/blog/3530/multi-tenancy-approaches-and-applicability
http://weblogs.asp.net/zowens/archive/tags/Multi-tenancy/default.aspx
http://cloudsamurai.codeplex.com/
http://cloudninja.codeplex.com/
http://msdn.microsoft.com/en-us/library/hh534484.aspx
http://blog.maartenballiauw.be/post/2009/05/20/ASPNET-MVC-Domain-Routing.aspx
http://blog.tonywilliams.me.uk/asp-net-mvc-2-routing-subdomains-to-areas
Even starting from scratch, you are in for a world of hurt. The MVC framework does very little to help you address the issues.
Most likely you are about to spend a fair amount of time restructuring your database.
The first step is that you are going to create a table to house your "Tenant" list. Then you need to add this TenantId to just about every table in your system to make sure no one steps on each other. You can skip any tables that are global in nature. One example might be a list of Status Codes.
However, everything from users to the data they have etc will have to have this ID. Also, modify all of your indexes to take tenantid into account.
Once you have that, you'll need to modify all of your queries to take the tenantid into account.
One column of the tenants table should be the portal url. Like customername.oursite.com or whatever. This way you could point multiple urls to the exact same code. When the site needs to use the current tenantid just look it up based on the URL the passed in.
If I was doing this, I'd plan to spend about 1 to 2 hours per table in the database to make it "multi-tenant". Obviously some tables (and their queries) will go faster; others will take longer.
Incidentally, this doesn't cover things like customizing the UI (look / feel) per tenant or anything of that nature. If you need to do this then you'll have to either create a directory on the server for each tenant to hold their style sheets or load it directly from the DB (which has it's own issues with regards to caching).
Typically, you design for this at the beginning of the project. Refitting an already (or almost) complete project is a PITA.
Finally, test, test, test and do more testing. You will have to make sure that every single query pulls only the data it absolutely needs to.
There has been some talk of multi-tenancy support in Sharp Architecture (based on MVC 3) found here: http://www.yellowfeather.co.uk/2011/02/multi-tenancy-on-sharp-architecture-revisited/
Not sure if that really helps you with your existing application, porting over would be a bit of a job.