ASP.NET Authentication advice needed - asp.net-mvc-4

I'm building a couple of ASP.NET MVC websites that will share a database (because they share data under the hood). That said, logins between sites will not be shared at the moment. For reference, I'm using NHibernate for data access with SQL Server under the hood (currently).
As currently laid out, the system has tables for Sites, Roles, Users, and Rights. Sites have sets of users, rights, and roles. Users can be in many roles. Roles have a set of rights. Users will be able to sign in with a username and password, but I don't want to paint myself into a corner - I might want them to be able to use a google or facebook login later.
Now, I'm a little confused as to which path to take with regard to securing the site. I'm not enamored of the old school membership and role providers for several reasons. Chief among these is that I won't be restricting very many things by roles; things will be restricted based on user access rights. I'm looking at the following few scenarios for authentication.
1) I want to be able to specify rights required to use a controller method via an attribute.
2) I want to be able to quickly query and see if a user is in a particular role or has a particular right.
So, I actually have a set of questions, but they are kind of intertangled. First, what should I do? Just a custom authorization attribute? Second, what's the workflow on login and the like? What are the steps required for this to work properly and securely?
I realize these are sort of noobish questions, but in the past I've gotten by with the old provider way of doing things. I don't particularly care for that and would really like some better suggestions. So I guess everything old is new again for me.

I would flee the Membership provider from MS like the pest. It was already badly implemented when it came out with .NET 2.0, and the recent refresh is no better.
Roles, Users, ..that's not bound to the Membership provider, you can use those on your own. Set up Authentification, create a httmodule that handles said Authentification (a simple userId for the Context.User.Identity suffices)
All you need is a User that derives from IIdentity and in your httmodule
string[] roles = new[] {"Admin", "CoolDude"};
HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(user, roles);
..and now in your mvc controller simply add the necessary authentication attributes, game played !
Make custom roles, custom mvc attributes, or query if a user is in a specific role directly
if (HttpContext.Current.User.IsInRole("Admin")) { ...

Related

Realistic Usage of Identity and Roles in .Net 5.0

I am fairly new to coding in the .Net environment. I am having trouble finding "real-world" examples on authentication/authorization using Identity. Most examples I come across are primarily textbook examples that use the ASP .Net registration template.
I am trying to find guidance on where to look (yes, I Googled and I get very unrealistic/unusable use cases or "classroom" examples) or how to do this.
I work for a small school and I am trying to build an application (possibly Blazor - just experimenting with various technologies now) that allows both students and employees to login into a portal and view their relevant data. I have an Employee table and a Student table based on POCO classes. When I add identity to the project it creates Users and Roles tables as well.
I would like to have the "Users" table based on the Student and Employee tables - not have a separate users table. I do not want to have a "registration" option either. I would like the option for an Admin (which would fall under an "Employee") to be able to add users, but not use a registration page.
How would I implement Identity and Roles without using all the extras added? I am using .Net 5.0.
Thank you for your time and pelase forgive the English - it's new to me as well.
I understand what you're trying to do. It IS possible to Create a Custom AuthenticationStateProvider
But unless you have a VERY robust database already, I wouldn't do it. Getting the default system set up and migrating users will take at most an hour. Setting up your own custom authorization system is likely to take you MUCH MUCH longer.
Having different users in different tables is not a good design plan. They all have names, phone numbers, e-mails and so on-- put them on one table.
Hi Derrick and welcome to the community! #Bennyboy1973 is correct, in that both your Students and Employees are all "Users", so they should all be stored in the same table. To add to that response a bit, probably the simplest way for you to manage them is by using Roles, so the Students could be in one role and the Employees could be in another. By having a role attached to each, you can then use the roles as a filter in your queries and you could also restrict the access and actions each type will have based on the role they are in.
Regarding having administrators add the users to the database without public access, this can be done as well. Once you get the default identity system up and running, you can scaffold out the whole system so it can be modified, and probably the easiest way to achieve what you are after is to then modify the default registration (signup) page so that it requires the user to be authenticated to reach it, and then implement a confirmation email to activate each new account.
There are a few things with this approach that you need to be aware of as well.
Since the admin will be setting up all the other user accounts, you should modify the email confirmation chain to require a password reset at some point. The administrators can have access to the user's information as needed but shouldn't have the user's passwords.
Identity Server will store passwords in an encrypted format, and you'll need an initial user in your database. What this means is that you will have to "seed" an initial admin user into the database that you can use to sign in and get started with everything else. You'll have to research how to do this, as it isn't as simple as just accessing the database directly and adding the user and roles because of the encryption. The program you build should be designed to do this for you on either the first run or if you are connecting to a new database, using a username and password that you know. It will then store the user properly that you can use to sign in as Admin, then change the admin password. This makes the whole thing more secure.
This all sounds like a headache, but it's worth it to work through and know how it all fits together. The, as mentioned in other answers, you can migrate existing data into the database.

How should I implement user authentication/roles for an Electron desktop app?

I'm designing the architecture for a college project and I don't know how to deal with the user authentication and authorization part of it. The project is a desktop Electron app which would need two types (hence the roles) of users. They both need to be authenticated in order to use the app, and depending on their identity, they will have different authorizations. Since the project is meant to be used by teachers and students as part of a laboratory class after it is done, I don't think more than 30 people will be using it at the same time.
My first thought was using a PostrgeSQL database in AWS for this and implementing the authentication myself, but this means that users will have to sign up and create a new profile, which means remembering yet another <username/email, password>. Trying to avoid this, I read a bit about OAuth 2.0 and OIDC, and how it can be used to authenticate and authorize users without implementing either of those tasks oneself, but rather delegating the task to OIDC. I created a free account with Auth0 and thought about using it for the OIDC integration but after reading about 40 pages of an "OIDC integration handbook" they offer for free, I could not know if I would be able to distinguish my user base through these roles or tags as I mentioned. I just followed the steps in the tutorial handbook and tried to understand how the auth flow worked, but that didn't give me any information on my question.
So all in all what I want to know is: is it possible to implement this with Auth0 (free account) without having to use a third-party database solution (such as PostgreSQL with AWS)? If not, what would you recommend me to look into? Preferrably a solution that will let me discriminate between the two types of users BUT at the same time taking advantage of the OIDC implementation of Google for example.
There are 2 separate solutions here:
DESKTOP AUTHENTICATION
The 2 standard requirements are:
Use Authorization Code Flow (PKCE)
Login via System Browser
You listen for a login response via one of these mechanisms (I prefer the latter):
Loopback web server
Private URI scheme OS notification
My blog has some tutorials + code samples that use Electron. You can run both of the above listening options and see what you prefer.
API AUTHORIZATION WITH ROLES
You need to make roles available to the API via claims. This can be done by either of these mechanisms (I prefer the latter):
Including roles in access tokens via Auth0
Get the API to read user roles from its own database
My Authorization blog post discusses building up a claims object in an easy to extend way. The main objective is usually for API OAuth processing to result in an object something like this:
class UserPrincipal {
// The technical user id from the access token
string sub;
// The user id from your own database
string userId;
// The user's roles
string[] roles;
}
Given that object you can do things like this:
Use role based authorization when needed
Serve up user resources after login from your application data
TO SUMMARISE
Auth0 will meet some of your requirements and may be all you need in the early days. You will probably need to manage non OAuth user data in your API at some point though.
Happy to answer any follow up questions ..

Does it make sense to split user identity and profile?

While writing a solution from scratch based on microservice approach (more specifically it is Azure Service Fabric) I came to an idea of splitting the user Identity (which is login credentials, claims, etc.) and user profile (which may contain some social info like avatar, links to social networks, birthday, etc.).
For the identity, I'm going to use IdentityServer4 (stateless ASP.Net Core) and for storing all these data I'm thinking of an Entity Framework + SQL. The profile will be managed and stored on different microservice (stateless as well) with a connection to Cosmos DB (via Mongo DB API), thus making it a NoSQL storage.
Are there any disadvantages of such an approach I'm not aware of?
You're conflating a bunch of things here. First, you have your actual "user" entity persisted to the database. There is no good reason to split a "profile" from this, as it's all just data about the user. If you're using Identity to manage users, roles and such, it was designed to be extensible from the ground up, meaning put user data on the user entity. A separate profile entity only serves to necessitate an join for no purpose.
At a higher level, once the user has been authenticated (via Identity Server), you have a principal. That principal is basically just a set of claims tied to a particular "identity" (i.e. the authenticated user). The claims come from multiple places, it could be data on the user record, roles, or even third-party claims such as when an external login account is utilized. Where the claims come from is mostly inconsequential.
Long and short, there's no reason for a separate profile entity and especially no reason for an entirely different service to work with profiles. That profile service would inevitably have to utilize a user service, so there's a hard dependency between the two: a clear sign that it's no a true separate service. In fact, this only makes the rest of your app that much more complicated as then you're having to work with both a user service and profile service depending on what piece of the user you're after.

Using AD for Authentication and Asp.Net Identity for Authorization

I am quite confused about one requirement that i've received and how to correctly fullfill it...i hope that someone can help me figure out something.
I have to add Authentication/Authorization to an existing MVC 5 intranet application that will be used only by the customer's intranet users. This web app hosts an AngularJs application that uses a set of WebApi (hosted inside the same intranet and used only for intranet purposes).
The application will be used by different kind of users that can have different grants (e.g: can create things, can modify things, can delete things) and those grants must be declined for different Countries (consider the Country as, conceptually, a subsite). So a User can be the "administrator" (considering the administrator as a User with all grants) for the France, but be a simple user for Germany and not authorized at all for the other countries.
The requirement is to use AD for Authentication, but not for Authorization purposes.
I am not an expert of security and i did some research to try to understand the possible solutions. The most important thing i have understood is to separate the Authentication from the Authorization.
From a simple Authentication point of view, it's easy to use AD (or Windows Auth).
What i am missing is how to perform the Authorization part.
I have seen a lot of tutorials for ASP.Net Identity with Individual Accounts, all it's clear and easy, as it's using the UserManager to perform lookups on the db for the users to verify the authentication, and from there take the roles data(saving those info in a cookie).
I need to understand what should be the correct way to handle my scenario.
The user should log in using it's domain credentials, then i should receive a response from AD, if ok i should get the corresponding user from my db and retrieve its role data...correct?
If so, how could i perform those tasks.
Is it a wrong way of solving the problem?
And if so, how can i do that?
What is the best way to "pass" the auth/entication/orization token to the WebApi in order to secure them as well?
One last question...could it be possible to fulfill the requirements by using only AD (not relying on the db for grants)?
Sorry for the (most probably) dull questions but i'm feeling like i am missing some VERY key points.

Simplemembership Provider ASP.NET MVC 4 Password Format

I have moved along nicely migrating to simplemembership. The only thing that is hanging me up now is how do I configure password settings such as whether it's hashed, clear, or encrypted, etc. I don't believe it will be in the web.config any longer.
Simplemembership is Designed around a specific view of users, roles and profiles
The existing providers are focused on traditional membership - a user has a username and a password, some specific roles on the site (e.g. administrator, premium user), and may have some additional "nice to have" optional information that can be accessed via an API in your application.
This doesn't fit well with some modern usage patterns:
In OAuth and OpenID, the user doesn't have a password
Often these kinds of scenarios map better to user claims or rights instead of monolithic user roles
For many sites, profile or other non-traditional information is very important and needs to come from somewhere other than an API call that maps to a database blob
What would work a lot better here is a system in which you were able to define your users, rights, and other attributes however you wanted and the membership system worked with your model - not the other way around.
You can't retrieve passwords with SimpleMembership, but you can let the user reset them. There is no workaround.
You must use some other membership provider, such as the standard SqlMembershipProvider, which may also not allow you to retrieve a password in clear text.
The days of retrieving a password in clear text is over, as this is a major security risk if it ends up in the wrong hands.
Hope this clears up some of your thinking about what you wish to achieve.
Some reading:
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
Migrating from ASP.NET Membership to SimpleMembership in MVC4 RTM
http://brockallen.com/2012/09/02/think-twice-about-using-membershipprovider-and-simplemembership/
SimpleMembership does not allow you to choose the password format.