Realistic Usage of Identity and Roles in .Net 5.0 - asp.net-core

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.

Related

What is a good practice when setting up a users table? Looking at some newbie tutorials, but not sure how to "really" do it right

I'm tinkering around with building a rest API that connects to a database. I'm following tutorials, but the table set ups are all really basic and one of my issues has been that in the "real world" the way its done is a lot more complex and different :(
However, I'm wondering for my actual application (really small) how can I properly set up the User table?
For example, I have set the primary key to userid because that should never be changing. Is it fine to use long for the userid?
Also, is it fine to lump a bunch of things together that are related to the user.. in the User table? I know its a stupid question.. For example, I want to know if the user has signed up for the service, so isMember. Or, is the user signed up for fast service, so hasFastService. Or, should these things be put into a UserAttributes table by the userid?
Finally, I looked up UUIDs and I'm wondering where those fit in, in which scenarios, etc.
Thanks
I'll try to answer this based on my own experience of creating users table in a project recently. The things you have to take care are basically these:
Authentication: Determine your login process and things like credential fields, user types (admin/guest/normal), whether OAuth is required or not, etc. before creating the users table. For example, whether you need a username/password to authenticate or email/password or either "username or email" with a password. The modern practice is to do away with a "username" since its redundant - an email is unique and acts as a username for all intents.
OAuth: If you are giving facebook/google/twitter logins, make provisions for that in your users table. How will you determine whether the user was a normal signup or a social login signup? A field such as "login_method" or something is useful in this regard. A second field called "user_type" maybe created for identifying the type of user account: admin/guest/employee/etc.
Profile fields: Its upto you to determine profile variables. In my last project, I used a few fields like FirstName, LastName, Theme, Timezone, etc. for the profile, but your mileage may vary.
For user-ids, it is usually best to have an auto generated integer primary key which is available in all modern databases.
Needless to say, never store the actual password in the password field. Just has your password and store the has instead. When the user logs in, you can hash the user-input and compare with the user table value.
Finally, DON'T confuse the user table by including related data like clients, employees, etc. All clients are users, but all users are not clients! Keep your design flexible, so as to include all kinds of users like admins, employees, etc.

SaaS Billing and Multi-tenant starter kit

I'm just about finished with a solution built with ASP.NET MVC. Apart from a few bits and pieces, I only have security to do. I was wondering if there is some sort of starter code somewhere which I can build into my application (or build my current files into) which will do the following:
Subscription page for tenants (think they are called tenants, see note below), which will assign a administrator to the account.
A way to invite others to join and work on the tenant's data.
User groups and roles to limit what each of these other users can see/do.
Standard Login/forgot password pages
It doesn't need to handle billing, but if it does, it's an added bonus
My understanding of a tenant here is a person that signs up and then invite others to access their data. It is also be called vendor sometimes.
I'm sure there must be something out the box, because the above are features of most SaaS apps nowadays. I'm aware that I will need to add clauses to all existing queries to ensure that tenants don't see each other's data.
Any solutions that anyhow know of? Please let me know. Thank you

Azure Membership details - how to store user/login details for multiple applications in one MS SQL database

I'm trying to design MVC4.5 website on Azure with latest EF but stuck in setting up membership and role base authentication.
I'm somewhat lost in MembershipProvider, SimpleMembershipProvider and ExtendedMembershipProvider.
I found that unlike SqlMembershipProvider the SimplememberShipProvider is not designed to store multiple applications (through ApplicationName and ApplicationID) in a single database and map users accordingly so that business can run multiple applications with only one database.
I hear all praises of SimpleMembershipProvider, my question is how should the database/providers be designed so that I'm able to store user's in association with respective applications in a single database. User registration info must be completely independent from same user name in other application. I also need new features of Open Authentication.
Broadly, my queries are:
Is it possible to use SimpleMmebershipProvider to differentiate between multiple applications in a single database.
I'm thinking to modify existing schema structure made by SimpleMembershipProvider to include ApplicationId column , but then how would even a custom provider that is inherited from Extended membership provider add ApplicationId against any user.
Is there any other provider available or any article that would guide in implementing custom membership provider with custom database design along with features of open authentication.
Or am I going with completely wrong approach?
Answering to the queries of BernardG
Do you want a "head" url/site, then redirect users to the proper
application, or
No, sites should not appear related nor will be redirect to other.
Do you want a user to enter into any application and
then be redirected to another one he is registered in.
Again no, each application should have it's own registration process. Further two applications can have same username but these accounts would not be related.
Can a user register into any application?
Yes.
If not, how do you limit that?
Not limiting.
What do you mean by this?"User registration info must be completely
independent from same user name in other application."
Refering to answer to point 2, if there are 4 applications with one database and a user registers for one application, he must need to register again to have access to other application. Hence for any user the sites must not appear related.
Do you want to duplicate users info into each applications?
As per my understanding of the question a combination of username and email address (considering this combination makes any user account unique) can again be stored against another application even with different profile information.
Actually I'm used to the classic membership approach used in ASP.net 2.0 and I'm missing the application Id column for separation.
If I may, I believe your question has a lot more to do with design and establishing clearly the features you want, rather than a specific membership provider, knowing that you can do about anything you want with SimpleMembership.
My questions, and I believe those are the questions you have to ask yourself before going further, are:
Do you want a "head" url/site, then redirect users to the proper
application, or
Do you want a user to enter into any application and
then be redirected to another one he is registered in.
Can a user register into any application?
If not, how do you limit that?
What do you mean by this?"User registration info must be completely
independent from same user name in other application."
Do you want to duplicate users info into each applications?
It looks to me that this is all about database(s) design, and analysis, for your real needs. Once that's properly done, the part about membership tables will be easily solved.

ASP.NET Authentication advice needed

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")) { ...

User authentication design, are users people?

The application is written in Ruby on Rails but the problem I am facing is more a design matter than language related.
the system provides service to a number of users to maintain a registry. So it relates persons to things. As such it has a model called Person representing owners and it has a model called User representing those who manage the registry.
Now a new requirement has arisen to allow People to log in and be able to change personal details which it was not required for the original design.
The question is how to refactor the application to allow this new requirement in?
One easy solution is to create Users for each person who request login credentials and link user to person entity but that is not very DRY as some fields such as firstname, surname etc. are in both classes and in particular, that is precisely the data people will be able to change. Besides User and Person are stored in separate tables.
The other possibility I was considering is to make one to extend the other but having data in separated tables it makes it a bit messy. Additionally the logical extension would be User <- Person as an user is (generally) a person but thinking on the implementation Person <- User is quite a lot easier.
One last option could be to scrap User and move login credentials into Person leaving logon fields empty for those who won't log in and half of the fields empty for those just login in.
Can you think of a better solution?
You could think about how this should ideally work if you were to write the application bottom-up, and then figure out how to make a reasonable compromise between that and your current setup. Here are some generic inputs.
As authentication is involved, you need an "Identity" that can be authenticated. This can be e.g. an email address and an associated password, with email verification.
An Identity can potentially be associated to multiple "Roles" and someone authenticated with the identity can choose which role to perform, e.g. "I am now an administrator" vs. "I am now a regular site user", and the role defines the user's current rights for the logged in identity. Or if you don't need that level of complexity, you can say that an Identity is a (single) Role.
You need some tracking between possible "Rights" and the Role the user is performing. E.g. the simplest setup could be the Identity or Role has some boolean can_edit_profile or can_modify_registry properties.
Whenever a user attempts to perform an action which requires certain Rights, it is simply a matter of looking up the corresponding rights set for the Role being performed by the user, to check whether the user is allowed to proceed.
For your application this may just involve adding a 'can_change_registry' property for your user objects, and check whether that property is True for any code accessing that part of the site.