ASP.NET Membership Providers - Avoid setup in web.config - asp.net-mvc

I have a multi-tenant application where each tenant will have their own database. The ASP.NET MVC3 web application will look at the username passed in and determine which customer database to use to authenticate the user.
I can get this to work if I add multiple connectionStrings / membership Providers, I can get it to work.
I'd like a way to remove the dependency on the web.config.
Is there a way to configure SqlMembershipProviders via code and not tie myself to a web.config file? I'm thinking I could do it with a custom provider that I write, but would like to see if there was a way before heading down that road.

I've become less of a fan of using the ASP.NET Membership provider for my MVC projects that deal with user data in other ways. Instead, I use forms authentication and incorporate the password hash and salt as columns in my user database (similar to the schema) then manually set the forms authentication cookie.
This is actually not dissimilar from what the default MVC project scaffolding sets up. I just didn't like having to correlate my user records with ASP.NET membership records and I didn't make use of the associated profile or role capabilities.
If you go this route, then you have some options as to how to handle a multi-tenant scenario, but I seriously doubt you'll be able to (or want to, for that matter) get rid of the web.config altogether.
For some multi-tenant ideas, check out my answer in this SO question: SaaS: one web app to one database VS. many web apps to many databases

Related

Implement AspNet Core Identity or Work account Authentication

This is not like other questions you might find similar. My issue is way bigger.
Scenario:
I have 3 websites. All of them have a common database for authentication and stuff.
Problem is that i will need to expand to 2 more sites, which means more maintenance in login screens and so on. So i will dedicate time to make a "central website" to manage users, access, etc.
Also, Need to implement OpenId for Microsoft Works accounts (ie, Azure tenants).
DDBB User Model: (Simplified)
All users are in the same central database. Which does not contains
anything non-user related.
User is personal on all applications.
Users can have different Roles
Each "User-Role" is mapped to an application, a server and a
database.
Problem:
Created a site in AspNet Core, without any authentication done so I can do it myself since I found that mapping Aspnet Identity tables was no-go because of incopatibilities and overriding is way to complicated, specially when dealing with Managers.
So, Tried and got working a simple Authentication page using HttpContext.Authentication.SignInAsync and CookieAuthentication. Which works well and there is no need to use any of the Identity's implementation (which is not compatible with my backend).
But then I added UseOpenIdConnectAuthentication to have the OpenId auth, but I have no idea how to use it since its suposed to work out of the box when using Identity and when checked documentation they use this code in an controller action: signInManager.ConfigureExternalAuthenticationProperties and I do not have any SignInManager since Im not using Aspnet Identity.
Questions:
Is coping the source of ConfigureExternalAuthenticationProperties to make it work in my site an aceptable solution?
Should I continue to override all SignInManager methods and also probably implement other classes to make Aspnet Identity work with my model?
Tried Mapping the properties to my columns just to test it out and it gave me non debuggable errors, which i dont like to even think about the problems this can give me in the future. For example one error was that it coudnt parse byte[] to string.
How can I implement Microsoft Work Accounts authentication and Database authentication in the same AspNet Site?
Bonus topic
Recently I feel like programming is becoming Configuring instead of coding. Is it just me? Are we now Professional Configurers?
Thanks

Using SimpleMembership With WPF Applications

I started my project using ASP.NET SIMPLE MEMBERSHIP. Now I have the necessity to create a WPF application which can add users to SIMPLEM MEMBERSHIP tables.
In the ASP.NET, I've identified that this is the function to create new accounts:
WebSecurity.CreateUserAndAccount(model.UserName, model.Password);
What would you suggest to implement this feature in a desktop application. I was thinking creating a WCF Web Service, but I don't know how difficult could be creating it.
You could use WCF but probably the simplest solution is to include the Asp.net Simple Membership Tables as part of an Entity Framework Model and use the model from within your WPF app. Check out this post for more details.
That would, of course, require direct access to your SQL Server and either a SQL Server account with access to the tables referenced from the EF model would have to be used or the app users would have to have access to the SQL Server through integrated security (if using mixed mode authentication with your SQL Server).
Why bother?
I would simply have yours users go to a link and register for an account online through an asp.net page. Once registered, offer the WPF/windows client as a download. This stuff is already pretty much all built-in.
That link might help: http://weblogs.asp.net/jgalloway/archive/2012/08/29/simplemembership-membership-providers-universal-providers-and-the-new-asp-net-4-5-web-forms-and-asp-net-mvc-4-templates.aspx

Where should I start in choosing and implementing a ASP.net MVC 3 user/role system?

There is so much information and terms here I find it hard to start think about users. What options would I have for creating a user-based ASP.net MVC 3 web app? I've read of membership, providers, authorization, authentication, session, cookies, roles and profiles, but I can't seem to get a grasp on the big picture of how user-things are handled.
What are the pros/cons of using a built-in microsoft solution here? What is it even called?
Can I use my own database only (I want to work database first)?
In my mind I think like so: I have users and roles in a database. Users have roles. I want to deny access to some actions depending on if the user is logged in and has a specific role. Am I over-simplifying the issue? Where should I start?
At the moment I'm thinking of doing a 100% home brew system like when I was developing using PHP but since there's so much info I feel like that would not be a good approach here.
You want users and roles, i.e. you want to authenticate users and authorize them with privileges using roles. I would highly recommend not rolling your own, as you would in PHP. Instead, I recommend using the .NET "Provider" services -- specifically, the MembershipProvider (for authentication) and the RoleProvider (for authorization).
You can still use the Providers with your own db, they are not exclusive to or exclusive with code first. However, I would recommend NOT storing application-specific user information in the Provider's user or member tables. Instead, you can have your own code-first User, and link it to the membership system through the user's username.
The reason I recommend this is because it reduces the amount of work you have to do. You need not worry about encrypting or hashing passwords -- the provider does it for you. You have full API to control your users and roles through the System.Web.Security namespace.
As for Profiles, this is a separate Provider service that you do not need to use. It allows you to store information about users whether or not they have registered for a user account in your system. Technically you can have "anonymous users", but anyone who has created a password-based login is instead referred to as a "member".
Regarding cookies, authentication of a user in .NET is done through the FormsAuthentication class. After you have authenticated a user using System.Web.Security.Membership, you can call FormsAuthentication.SetAuthCookie to write their authentication cookie. This fully integrates both the User and their Roles into the Controller.User property, which implements the IPrincipal interface. You can use this object to get the user's name, and find out which roles they are in.
Reply to comments
I answered a very similar question here. Basically, it's up to you whether or not to have the membership in a completely separate db than your application, but I consider it good practice, because I have done this quite a bit and I have no complaints. Especially if you are using code first, since you can lose your entire db if you use the DropCreateDatabaseIfModelChanges or DropCreateDatabaseAlways initializers.
There is also a new membership provider. I think the NuGet package is called "ASP.NET Universal Providers", and they are in the System.Web.Providers namespace instead of the old System.Web.Security namespace. I haven't had a chance to work with them yet, but from what I gather, they are more compatible with code first. For one thing, the tables aren't named like aspnet_Foo, and there are no views or stored procedures created in the db. The table names are just normal dbo.Users, dbo.Roles, etc.
As for linking the provider users with your app (content) User entities, see the answer I linked to above. The easiest way to do this is to just have a field in your content db for UserName, and link that to the provider db's UserName. No foreign keys necessary, since you integrate them at the app-level, not the db level.
I think you should first start with built-in solutions, they're easy to extend if someday you'll need something more (even if to write a good providers for authentication isn't really trivial. Start reading this article, it's a good start point).
I don't think to write everything here is a good idea, it's a big topic and I should simplify everything too much so I'll post some links I found useful.
Just to start, with text from MSDN:
Authorization determines whether an identity should be granted access to a specific resource.
Authentication is the process of obtaining identification credentials such as name and password from a user and validating those credentials against some authority.
Imagine users and roles as Windows users and groups. For example a web-site for forums may have a user named AUser with following roles: User, Editor, Moderator. In that web-site they may grant a set of allowed actions: User may enter new posts, Editor may change posts of other people and Moderator may close or delete posts or topics. In this way single web pages don't need to know users but just roles (the DeletePost method of PostController may be decorated with [Authorize(Roles = "Administrator, Moderator")]).
Start reading this very introductory article, it provides additional useful links.

ASP.NET MVC, forms auth or custom when using EF 4?

I'm new to the ASP.NET world. Since I want to use the ORM it seems I would want an Entity to represent the User or Member or whatever, not some data tucked away by the forms authentication api. In fact I don't see how I can live without one.
How do people deal with this? Roll your own authentication? Or is there a best practice for incorporating forms authentication with the Entity Framework?
In short, since I need a User and Role Entity for queries anyway, should I skip the forms auth or find a way to use it?
Thanks
EF and Forms Auth are really two different areas. You can use Forms Auth without ASP.NET Membership very easily and roll your own provider with very little effort.
This tutorial will show you how:
http://msdn.microsoft.com/en-us/library/ms172766(VS.80).aspx
With ASP.NET MVC you should really use standard Auth since you can manage access to controllers using attributes for Roles very easily.
FormsAuthentication on its own does not care about the identity store and can validate only credentials stored in the web.config <credentials> section, through the Authenticate method. Standard implementations of the login page use the static Membership class to manage the identities and credentials in the MembershipProvider specified in the config file (usually SqlProfileProvider).
However, you don't have to use the membership provider functionality of ASP.NET to maintain your identities and you can still use FormsAuthentication just fine. The forms authentication control flow shows that forms authentication deals primarily with creating and maintaining the auth ticket for the user in a cookie. It does not deal with the user identity or profile itself, as it does not care about those.
Thus, you can safely use EF to maintain your user profiles, including credentials and do authentication of the provided credentials in your login page, while still using FormsAuthnetication.

ASP.NET Membership Alternatives

I have always stayed away from asp.net membership as it seemed bloated, and (at the time) untestable. In the case of asp.net MVC specifically, does anyone use an alternative solution for assigning roles to users, and storing some addition information for the logged in user? Any recommendation? Is it crazy to just roll your own, just implementing the functionality you need?
ASP.NET membership uses a provider model for the storage. SqlMembershipProvider inherits encrypting/hashing password functionality from the abstract MembershipProvider class. But you could also inherit from MembershipProvider and get that functionality in a custom provider if you wanted.
If you use the SqlMembershipProvider, you get a fully working membership database with full password management (checking, changing, resetting, invalid password attempts) and user management (CRUD ops, locking out users).
All of that is at an API level. You can create whatever UIs you want against the API.
Using the SqlMembershipProvider doesn't require you to use the Roles Provider or the Profile Provider or any of that other stuff, and you can roll your own for those things without impacting membership. At the very least I would recommend using the well-tested SqlMembershipProvider as the core of your security for the basic stuff.
I have successfully implemented DotNetOpenAuth as a membership and role provider. It is not a full implementation but handles most common scenarios.
They provide VS templates to get you started.

Resources