Database design with ASP.NET Identity - database

As we all know that we may extend the profile information based on ASP.NET Identity to another table or include it to the default table (ASPNetUsers).
Supposingly i only have two field to be fill in during registration (username and email) only, but upon completing registration, user may or may not opt to fill in extra profile information (such as sex, birthdate, real name etc).
I have two options in my mind but not sure which is the more appropriate way.
All profile information (username, email, sex, birthdate, real name) include in the default identity ASPNetUsers table.
Required registration information(username and email) for default identity ASPNetUsers table, while the extra profile information is in another table which is linked to the default identity ASPNetUsers table.
Or is there any better option? Hope that we may gain something new in this discussion.

I would go with option 2. As the profile is likely to change. More over if I need to take out the identity to some other server it is easy to take them there. or later to extend to federated identity(well.. this can act both ways due to sync issues).

You'll need to add custom properties as a Claim on user. Then in your views access these claims from ClaimsPrincipal.Current.Claims.
Claims on principal are available in the cookie, so no extra DB hits required.
I think this is the best and most performant solution
How to user claims in asp.net identity

I'm working on a project where there are several solutions using the same Authentication/Authorization project.
The authentication project is the only one that uses tables AspNetUsers, AspNetRoles, ...
By the other hand, other projects have their own "Users" table with the extra information that each one need.
If one project need "BirthDate" and other project needs "Sex", we are not going to put both in the common
authentication tables, giving to all projects extra information that isn't useful for each one.
Working that way we are also giving the "Single responsability" of Authentication and Authorization to
one project, avoiding the code repeating.
That's why I think that the second option is more scalable and maintainable.

Related

What is the right way to maintain user audit in a system designed to use external authentication?

I am using AWS cognito for user authentication in the application that I designed. And where ever there is a need for user audit in the application, I have used the id from cognito as if it is a foreign key from another table(I am using a relational DB).
Even though this works, this approach somehow feels improper. Is there any other proper way to design this?
In my application, the user logs in with his email address (common scenario). Hence, by construction the email address is a unique identifier both in cognito and in my database.
My database creates a user id for each new user, and that is the main identifier I use in my app (note that this identifier has nothing to do with cognito).
Cognito also assigns an id to each user (which it calls "username"), but I never reference that id (nor have I ever felt the need to reference it). I have been in production for several years, and I have never regretted this decision.
Upside of not linking user ids:
full flexibility (e.g. I can decide that I want to create a new user Object in my database for a particular cognito user. I can keep the previous user e.g. as a backup, even though it is not linked to the cognito user).
less work: i don't need to make sure the ids in my system are in line with those in cognito.
Downside of not linking user ids:
maybe it's faster to query cognito using the username field than the email field? maybe that could be an advantage for some use cases?

Schema recommendation for having same account for different websites sharing same database?

I really need to get some database design help. I have a platform where we have a table called users. It has a column called role for defining whether its a customer, provider, manager. But column email is unique. So at first we thought that its okay clients will make new emails. But then later it was not formidable. They wanted to use same email for both platform (Just like google single email for everything) So I want to really know the very basic idea of how Google maintains it. What should be the very basic db schema for it?
It looks like you need to break out roles from the user table.
If you are able to go this route;
user table - email as the primary key
platform table - platform id/name as the primary key
user/platform table - combination of email/platform id as the primary key
This will give you the ability to store and query when users have multiple platforms and/or roles.

Profile Management with Identity Server

So from what I have read on IdentityServer I should be storing details about the user such as first name and last name inside claims. How would a web application then be able to access the claim information? Since the User Info endpoint requires a valid access token representing the user, I suppose I would need to make an API that could access that returned the profile information of other users? Is this the right way to do it? (use case, web page needs to display contact details that are stored in claims of another user)
Also what would be the way for multiple language profile information be stored and retrieved in the claims? For example a user can have a name/title in multiple languages. I'm thinking of making [LanguageCode]_[ClaimType] (fr_first_name) naming convention and either adding all languages to just the profile IdentityResource or creating separate resources per language.
Your best bet is to set up a project using the IdentityServer4 QuickstartUI example and review that code to better understand how it all works. As of version 4, Identity Server is only focused on the sign-in / sign-out process and the various flows around authentication. They also provide a basic EF-driven persistence model, and they also support the ASP.NET Core Identity persistence model (also EF-driven), but both of those are not meant to be production-ready code.
Basically, persistence of user details is considered your responsibility. That being said, the cookies used for ASP.NET Core authentication greatly restricts how much data you can/should store as claims. The best model is to keep "real" identity provider (IDP) claims as claims, don't add new claims to that list, copy what you need into some other separate user-data table you manage completely, and use the unique claims identifier (almost always "subject id") as the key to your user data. This also makes it easier to migrate a user to another IDP (for example, you'll know user details for "Bob" but he can re-associate his user data away from his Facebook OIDC auth to his Google auth).
Basic persistence isn't too difficult (it's only 12 or 13 SQL statements) but it's a lot more than will fit in a Stackoverflow answer. I blogged about a non-EF approach here -- also not production-ready code (for example, it has ad-hoc SQL to keep things simple), but it should get you started.

Users Vs Members

This is more like a question for an advice rather than a precise answer...
In my CakePHP app, I will have backend users and frontend members. They have completely different roles and permissions (users are application managers, members are visitors that register on the website without any access to the application backend). Should I use different tables for these two authorization types, or should I just manage them with a role parameter and bind tables to their profiles depending on it, and why is one solution better than the other?
Use the same table and role or type field. You will have only one login and it will be easy to manage the accounts.
Use ACL or a custom permission system to allow them to different controllers/actions.
For permissions, I have 3 ways to do it :
The strict-role way :
Every role of your application has access to functions with their prefix, but not any other prefix.
Ex : admin has access to admin_edit, but not customer_edit
You add a role varchar or enum in your users table, the routing prefixes in Config/core.php and you allow the access in a AppController::beforeFilter : each role is allowed to access to his prefix only.
The hierarchical way:
Your application's roles are ordered in a hierarchical way, where a role has access to his prefix and every prefixes under him.
Ex : admin has access to admin_edit and customer_edit, but
customer has not access to admin_edit
You add a role varchar or enum in your users table, the routing prefixes in Config/core.php and you allow the access in a AppController::beforeFilter by checking for each $this->request->params['prefix'] which roles can has access to it.
The custom way:
You need your admin to access to some functions, but not all. You need another role to access some functions admin can access, and some functions admin cannot.
Ex : admin can access to admin_edit and customer_edit, but not
customer_create or user_stat. customer can have access to
customer_edit, customer_create and user_stat, but not admin_edit or
user_edit
Use ACL. It's not the easiest way to manage permissions into your application, but if you want specific permissions, it's the best way. So remember this : only use ACL if you really need it.
I agree with cornelb: one table only. Here are some additional reasons:
If you add foreign key constraints, it might be messy to make them refer to both the app managers table, and the visitors table. Always when you want to point to a user, you'd need 2 fields, instead of 1 (a field pointing to the managers table, and one to the visitors table — and exactly one of them has to be null). And what if you need 2 user id fields in a row, with foreign keys? Then you'd suddenly need 4 fields. Simper with all keys pointing to just one table (and user type decided by the above-mentioned field).
Sometimes you might want the user id be part of a primary key — but that's more complicated, if you have two different user id fields, one in each table. Because then the database cannot guarantee that each user id is unique — you'd have to do it yourself at the application level.

Alternative choices beside Silverlight AspDotNetMembershipProvider

i'm doing with silverlight 4 for consultation booking system. what i wondering is, in my application required multiple kind of user register and login. admin having different format of admin ID, lecturer having different format of lecturer ID. i'm trying to implement with silverlight for role and authentication merchant. i think might because of silverlight membership can be done easily with asp.netmembershipprover, i could not find any resource to edit the default form for it or custom made the membership merchant for my application. may i know is there any article or resource you know on how to implement this, or any idea you can suggest to me ?? Thank you
Resources i found:
http://www.silverlight.net/learn/graphics/file-and-local-data/isolated-storage-(silverlight-quickstart)
i thinking of using the isolated storage to store the user logged in boolean but sound like not so secure
http://msdn.microsoft.com/en-us/library/ee942451(v=vs.91).aspx
the resources mention of using the default asp.net membership but no comment on how to edit the default set.
You can use default MembershipProvider to manage general user information such as username, password, security question, login etc. Then you create additional table to store your own information, of course you need to create Page to manage these data by yourself.
Table: aspnet_users
UserId
UserName
...
Table: YourCustomData
UserId
AdminId
AdminText
...

Resources