Converting Single DB ASP.NET Site into MultiTenant - Membership and Roles Dilemma - asp.net

I'm in the process up changing a single SQL DB website (ASP.NET/VB.NET) into a multitenant app, where each client has their own database.
In the old site, all the ASP roles, logins and providers pointed to the single database.
Now we have multiple databases, I'm wondering what would the best architecture/techniques to use. There is one database that configures the tenants, such as the company name, various settings (that would normally be in a web.config) and the connection string to their tenant database.
Should we have all the membership & role stuff in the single database that configures the tenants or do we have membership & roles in each individual tenants database? Option 2 seems tricky because I think ASP.NET only likes one set of RoleProviders defined in the web.config.
Has anyone tried this before or got any recommendations?

If you're using the ASP.Net Membership model with the built-in providers' then putting them into one DB is the easiest as you indicated.
One option, and I've not tried this, is to define in your web.config file a provider for each tenant. This would allow each tenant to have their own membership db, and allow you to avoid username collisions between the tenants (if this is a requirement).

You should be able to configure the the ASP.NET membership database connection string at runtime. This thread has a few options including a custom membership provider or changing the value early on in the request lifecycle via Global.asax.cs.

Related

MVC4 membership connection using Entity Framework

I created a DbContext connection using Entity Framework and have "DbContext" connection string in my web.config file.
Then, I tried to log in, and my website required me to have another "defaultConnection" string for creating user tables.
In this case, do I need to have two connections? Or should I have one connection by somehow combining the two?
Which is better performance-wise? I started building my project using Internet Application template.
By default for membership and roles, the ASP.net infrastructure uses the default membership and role providers that stores that membership and roles data in different database. Run your application and if you register for a user from login page you can see the database at location "App_Data" folder created. The database is different hence the connection string is different. You are using entity framework so there are 2 ways to go from here.
1) Change the connection string and use the same default asp.net membership and role providers to store data in the database that your entity framework configuration is using. By this I mean the default membership and role providers use the database that you EF configuration points to.
2) Use EF to manage the membership and roles data. So the users and groups would be entities manages by the DBcontext as other entities.
I have recently implemented the second approach. The ASP.net membership provides hooks (extensibility) to implement your own providers and register them in the web.config file. Then create the User and Role entity and include them in DBContext. Of-course before registering the providers you need to implement them first by deriving from MembershipProvider and RoleProvider abstract classes. These classes are in `System.Web.Security' namespace.
You can follow this project for more details http://codefirstmembership.codeplex.com/
I believe the connections to separate database will not have any impact on the performance. As in the web model even if you use same database for incoming requests we have to make connections to database separately and the incoming requests can come concurrent. In fact keeping the database separate will take to database load to another server. But now you have 2 servers to back up and maintain. This will not be maintainable unless you want your membership data to be separate for some reasons like it is shared by other applications also.
I would suggest combining the two, since at some point you will probably want foreign key's from various tables to the Users table.
I would have one connection in the web.config, "DefaultConnection".
Then when you initialize your DbContext, use the DbContext(string) overload to use the DefaultConnection, like so: var context = new YourDbContext("DefaultConnection");
That way your data and Users/Roles tables live together, happily ever after.

ASP.NET - with multiple sites sharing the same database, how can I manage the username a password?

I have multiple websites and a Windows app that share the same database. Is there a way that I can manage the database username and password across all web.configs and app.configs? I'd like to be able to change the username and password, and then have all websites and apps use the new name. Is there something that I can use that will automate this? I currently store the username and password in a connection string.
You may have to write some custom code in your Windows app to support it, but ASP.NET Membership will let you share usernames and passwords among multiple apps.
http://msdn.microsoft.com/en-us/library/yh26yfzy.aspx
ASP.NET membership supports facilities for:
Creating new users and passwords.
Storing membership information (user names, passwords, and supporting
data) in Microsoft SQL Server, Active Directory, or an alternative
data store.
Authenticating users who visit your site. You can authenticate users
programmatically, or you can use the ASP.NET login controls to create
a complete authentication system that requires little or no code.
Managing passwords, which includes creating, changing, and resetting
them . Depending on membership options you choose, the membership
system can also provide an automated password-reset system that takes
a user-supplied question and response.
Exposing a unique identification for authenticated users that you can
use in your own applications and that also integrates with the ASP.NET
personalization and role-management (authorization) systems.
Specifying a custom membership provider, which allows you to
substitute your own code to manage membership and maintain membership
data in a custom data store
Also, see this SO question for some additional info.
Keep the user name and password in the registry.
Build the connection string on the fly using a class
All web sites and Apps should have the same class
By the way, the registry is more secure than the web config.

Advantage of implementing my own role based authorization instead of using Membership?

I read this article here
http://www.codeproject.com/KB/web-security/RolesFormsAuthorization.aspx
What is the limitation of Membership that would require me to implement my own ?
The primary limitation is using the arbitrary database design of the Membership provider along with being relegated to the Membership API.
I have always found the membership provider API to be kludgy (at best) and the database design it requires to work out of box to be atrocious. I have never once used the builtin membership to fruition ... I think ever but absolutely not in any application I have in production.
So to sum it up, the primary reason to not use the membership provider out of box is the database design will not match your design and you will have a hell of a time trying to use your application database + membership database together or you will have a large amount of insidious data duplication of users, ASP.NET user vs application user.
Personally I've found the standard membership provider extreamly flexible. But one reason could be to allow your website to authenticate users against a legacy database containing usernames and passwords created by a different system, or to authenticate against a web service.

ASP.NET ApplicationId

I've read somewhere that ApplicationID is a unique id for a website (IIS site path). But I'm still confused.
When and why do I need this?
I'm trying to implement asp.net membership for a website and I'll create some additional SQL tables (such as Companies, Services, etc) other than asp.net membership tables. So; do I need to include an ApplicationID column to these custom tables? Why?
The application ID is stored in a the aspnet_Applications table in your membership database. When you first enable the ASP Memebership provider, the application name that you set in your web.config is entered into this table. From then on, the membership provider uses your application name to determine which users can login for user authentication in your app.
To answer your second question, no, unless you have a unique need/requirement to do so. Reason: The asp.net membership is setup so that you can host multiple possibly distinct applications using one membership database. This is nice in that you do not have to create a different database for each one of your sites for authentication. Unless you will have multiple/distinct applications hitting these other tables that you have mentioned, you do not need to worry about assigning the appID to them as your users are already logged in.

asp.net webservice user management across pages

I'm developing a site that will display confidential readonly information,
with data fetched from a WCF service.
My question:
What is the best approach to user management across different information pages.
The service returns a collection with customer info after a secure login.
My idea is to have a Customer object class that is stored in session.
Is it possible to use things like HttpContext.Current.User.Identity.IsAuthenticated
followed by HttpContext.Current.Session["UserId"] without using a database with role-based security?
Would I be better off with a combination of local database, Linq to SQL or datasets rather than using
just class objects for data fetched from service?
thanks,
nakori
If you have no need of tracking the user's identity within your application, just use session as you indicated.
But the HttpContext.Current.User.Identity.IsAuthenticated and such relies on the user having authenticated with your site in some way or another (or it will always come back as false). Authenticating with the web site doesn't necessarily need a database though. You can setup users directly in web.config, xml files, or use AD or some other authentication mechanism that doesn't use a traditional database.
But unless you need to authenticate the users, you can probably do what you want using the server's session object and/or cookies.
You don't need a local database - but best practice is to have the user authenticate. The two options are via a database and or via AD if this is an internal site.
You might as well create a new WCF service to perform the authentication since you've already got your database functionality separate. This will also let you access databases that aren't local.

Resources