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

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.

Related

How to secure Neo4j browser

Is it possible to secure the neo4j browser so users can only execute specific queries? I would like to provide generally open access to the browser, but not allow users to delete.
Neo4j 3.1.x security features include role based permissions. As a browser user must log in with a username and password, it is also subject to this security model.
The authentication and authorization section of the Neo4j operations guide should be helpful to you. The section describing native roles already available to you gives a good visual of what is allowed per role.
It sounds like the reader native role is the one that would make sense for browser users, as deletion requires write permissions.
Finer grained permissions are possible, but based entirely upon user defined procedures, so nowhere near as simple as using the provided native roles and permissions.
However, if certain users should only be able to run a limited set of well-defined queries, then custom roles and user defined procedures should do the trick.

MVC4 Simple Membership authentication with multiple databases or providers

I'm working on an MVC4 site using SimpleMembership to handle user accounts and role based authentication. We have another site and we'd like to implement a single sign on system allowing users from the existing site to log in to the one I am building. What would be the best way to achieve this and hopefully leverage to the existing roles based authorization I'm using on the MVC4 site. Is it possible to have multiple membership providers (i.e. use the built in one and if the user is not found, attempt to authenticate via a custom provider that I'll write (once I work out how!). Or would it be better to abandon the built in membership/roles and roll my own?
I also thought of letting WebSecurity check the local database and if the user is not found, query the 2nd database and if the users credentials are valid, create a local account for them. One issue with this approach is if a user called Fred registers on the MVC site, and then a user from the other site called Fred logs in, we couldn't create them a local account with the same username. We could prefix/suffix the username with some text to indicate that they are from the other site but then we lose the single sign on feature.
We will also want to integrate AD authentication for staff in the future.
So essentially I'm looking for the best way to authenticate users from multiple databases and keep using roles based authentication?
I've also done a little digging was wondering if ADFS might be useful for this.
Any help or advice would be greatly appreciated!
I recommend the use of an Identity server to handle all your login request and switching to a claim based authentication instead of a role based authentication if you can.
I personally went with Thinktecture IdentityServer
pluralsight.com have a good course on it.
Thinktecture IdentityServer is build on top of simple Membership and it supports multiple protocol such as
WS-Federation
WS-Trust
OpenID Connect
OAuth2
ADFS Integration
Simple HTTP
I recommend checking it
Good Luck

OAuth2 and role-based access control

I have a Rails app acting as an OAuth 2.0 provider (using the oauth2-provider gem). It stores all the information related to users (accounts, personal information, and roles). There are 2 client apps that both authenticate through this app. The client apps can use the client_credentials grant type to find users by email and do other things that don't require an authorization code. Users can also log in to the client apps using the password grant type.
Now the issue we're facing is that the users' roles are defined globally on the resource host. So if a user is given an admin role on the resource host, that user is admin on both clients. My question is: what should we do to have more fine-grained access control? I.e. a user can be an editor for app1 but not for app2.
I guess the easy way to do this would be to change the role names like so: app1-admin, app2-admin, app1-editor, app2-editor, etc. The bigger question is: are we implementing this whole system correctly; that is, should we be storing so much info on the resource host, or should we denormalize the data onto the client apps?
A denormalized architecture would look like this: all user data on the resource host, localized user data on each client host. So user#example.com would have his personal info on the resource host and have his editor role stored on client app1. If he never uses it, app2 could be completely oblivious of his existence.
The drawback to the denormalized model is that there would be a lot of duplication of data (account ids, roles) and code (User and Role models on each client, separate management interfaces, etc.).
Are there any drawbacks to keeping the data separate? The client apps are both highly trusted--we made them both--but we are likely to add additional client apps, which are not under our control, in the future.
The most proper way to use oAuth and other similar external Authorization methods as I see it, is for strictly Authentication purposes. All the business/authorization logic should be handled on your server part at all times, and you should always keep a central record of the user, linking to the external info per external type of auth service.
Having a multilevel/multipart set of access, is also a must, if you want your setup to be scalable and future-proof. This is a standard design that is separate from any authorization logic and always in direct relation to business rules.
Stackoverflow does something like this, asking you to create an actual account on the site after you login using an external method.
Update: If the sites are really similar you can subset this design to an object per application that keeps the application specific access rules. This object has to also inherit from a global object that has global rules (thus you can for example impose a ban application-wide or enterprise-wide).
I would go for objects that contain acess settings, and roles that can be related to instances of both application level settings and global settings only for automating/compacting the assignment of access.
Actually you can use this design even if they are not too similar. This will help you avoid redundant settings and meaningless (business-wise) roles. You can identify a role purely by the job title/purpose, and then impose your restrictions by linking to an appropriate acess settings setup.

Windows Identity Foundation and multiple user stores

I've been research WIF a lot recently and am still quite a bit confused about some of the specifics. I understand that if you're using ADFS that it's great, but that is not my scenario. Within my organization there are at least 3 main security systems. I have tried to get the company to use AD for all internal uses, but it's just not going to happen. In order to create a unified programming model, I've contemplated building add'l STS's for authenticating/authorizing.
Is this really wise? Most of the stuff I've read says just use ADFS. If not, then don't bother. Is it worth using WIF for the unified claims model when the process of creating custom STS's can be difficult?
What do you do in a case where not every user has an AD login to map to. For example, we have many seasonal employees that never actually log in to a machine with a personal account. The machine is logged in in the morning by a supervisor and the employee scans his/her badge and the employee id is used.
We are creating a new application whose code base will be accessed by at least three different sets of users. One group is internal (using AD) the other two would probably use asp.net default membership (okay, so two different sets of user stores). I'd love to be able to use WIF to unify authorization/auth, but with WIF it seems to want to go in the opposite direction. It de-emphasizes authentication and just kind of assumes it's all good when in many case that is the main concern. How could I leverage WIF in this scenario, if at all?
I've tried reading this article:
http://msdn.microsoft.com/en-us/library/ff359105.aspx
and I read up on StarterSTS which I still need to read up on a bit more. I've also watched the videos by the author of StarterSTS. I'm failing to really put everything together. It feels like WIF won't be useful for me, but I feel like it should since all I'm really after is a unified model of authentication and authorization. Thanks
What you want is similar to the Federated Identity model. You can build a Federated STS (like StarterSTS) that would normalize your claims for your application. You can then use something like ACS / AD FS V2 to federate these Identity Providers. Reading the Claims Based Identity Guide is a good start as well. When you Claims enable your application you can add more and more Identity Providers and use the Federation Provider to control the claims and set rules.
We just released a new version of the guide on CodePlex (the docs and code) while it goes through the production process.

Implementing multi-database, multi-provider authentication system

We have started building an asp.net mvc application. Application will consist with one main database with users, projects, common tables etc... and many databases (all with the same structure) with a data relevant to a particular project. Use can have some global roles (stored in a main database) and some project specific roles (stored in a project database) and each user can be linked to many projects.
My goal is to build an authentication system that will support classical username/password authentication and also an OpenID authentication (we are using DotNetOpenAuth for this purpose) and authorization system that will support the roles system which I described above.
But I run into several question:
1.) I think that we should support both (username/password and Ppenid) authentication options for a single user, so that username/password users won't need to create additional account when they decide that they will use an OpenId and I think that we should support several OpenId's for a single user like SO does (if some provider is down).
2.) I think that the best database for this would be:
table Users (UserId (PK), LastActivityDate)
table UsernameLogins (UserId (PK,FK), Username, Password, IsApproved, IsLockedOut, LastLoginDate, LastLockedOutDate, etc...)
table OpenIdLogins(OpenIdUrl (PK), UserId(FK),LastLoginDate)
table Profiles(UserId(PK,FK), DisplayName(Unique), Email (Unique), FirstName, LastName, Address, Country, etc...)
table Roles(RoleName (PK), RoleType(1=GlobalRole,2=ProjectRole).
table UserRoles(UserId(FK,PK), RoleName(PK)).
3.) Should I create my own providers (MembershipProvider, ProfileProvider, RoleProvider)? Its seems that MembershipProvider is not so appropriate for an OpenId authentication (and of course I can only support just basic methods (GetUser,ValidateUser))? Should I implement MembershipProvider just for username/password logins? I think that ProfileProvider and RoleProvider wouldn't be that hard to implement? Should I just use FormsAuthentication and use my own "services"?
We are also using NHibernate and Spring for DI.
Any advice will be appreciated.
Thanks!
1.) I think that we should support both (username/password and Ppenid)
authentication options for a single
user, so that username/password users
won't need to create additional
account when they decide that they
will use an OpenId and I think that we
should support several OpenId's for a
single user like SO does (if some
provider is down).
That seems reasonable. I like how you're designing in for users to have multiple OpenIDs. StackOverflow limits users to just two, but users often have more than that and may want to bind them all. I think username/password is a fine option if your target audience demands it OpenID. StackOverflow is a great example of how simple login can be when its pure OpenID. It can make login less busy to not offer username/password. But again, providing both as options seems most customer-focused since it gives them choice. A future version of DNOA will offer an integrated version of the InfoCard Selector into its OpenID login system so that you can even accept InfoCards directly, but have it look and feel just like an OpenID so your system won't require any changes.
2.) I think that the best database for this would be: <snipped/>
That looks like a reasonable schema. As you've discovered, separating the credentials tables gives you the greatest flexibility.
3.) Should I create my own providers (MembershipProvider, ProfileProvider, RoleProvider)?
MembershipProvider certainly doesn't fit OpenID very well. If you were only supporting OpenID login I'd say throw it out and don't bother implementing your own. The RoleProvider works perfectly with OpenID so that's a keeper. I've heard from others that ProfileProvider needs a MembershipProvider in order to function. I don't know if that's true. But ProfileProvider requires that you use the ASP.NET Membership SQL database schema, which I think is poor if you can write your own db schema which you've done. And if you're writing your own db, storing additional data about your users should be trivial so you shouldn't need the profile provider.
If you go with both username+password and OpenID, then having a MembershipProvider that you implement yourself would likely be possible, but in my experience most MembershipProviders that include any OpenID code are kludgey and even have security holes. So I'd still avoid the MembershipProvider if OpenID has any place in your system.
I wonder...is support for multiple OpenIDs that important. It seems like this is more the role of the OpenID provider. For example, I use ClaimID and I get what essentially amounts to "identify forwarding" (in the sense of email forwarding) so that I can rebind it to different identities. Now I don't rebind providers frequently but a provider could do this (i.e. when you get redirected to their login page they could ask you which identity you'd ultimately like to present). So the question is...is this really the applications job to implement?

Resources