Company Name? Claim? New Column? - identityserver4

I am planning to use Identity Server 4 and Asp.net Core Identity together. My website that will be talking to Identity Server 4/Asp.net Core Identity will be expecting that a company name comes back with each user.
Should I create a new customer table called Company and in the Asp User table add a column linking them together.
Or should this be a claim?
I know when I authenticated my user and they are sent back to my main site, I will have a company table and they will be linked but just not sure for the purposes of identifying them.
I feel like it should be a claim but I want to double check since I am new to all this.

In terms of using IdentityServer, technically everything is a claim. The "user" object IdentityServer returns will have all the properties mapped as claims. In that sense, it really doesn't matter which approach you go with.
However, it's generally better to keep data on your user table, if it makes sense to. Something like a foreign key relationship is especially valuable to exist at a database level, as there's more value to that than simply getting a company name.
Storing data as claims is most useful when that data is transient or not applicable to every user. Typical examples include things like third-party access tokens, such as from Facebook. Storing that on the database-level would inevitably result in denormalization of your database table, so it makes more sense to use a claim.

Related

ASP.NET Core: how to hide database ids?

Maybe this has been asked a lot, but I can't find a comprehensive post about it.
Q: What are the options when you don't want to pass the ids from database to the frontend? You don't want the user to be able to see how many records are in your database.
What I found/heard so far:
Encrypt and decrypt the Id on backend
Use a GUID instead of a numeric auto-incremented Id as PK
Use a GUID together with an auto-incremented Id as PK
Q: Do you know any other or do you have experience with any of these? What are the performance and technical issues? Please provide documentation and blog posts on this topic if you know any.
Two things:
The sheer existence of an id doesn't tell you anything about how many records are in a database. Even if the id is something like 10, that doesn't mean there's only 10 records; it's just likely the tenth that was created.
Exposing ids has nothing to do with security, one way or another. Ids only have a meaning in the context of the database table they reside in. Therefore, in order to discern anything based on an id, the user would have to have access directly to your database. If that's the case, you've got far more issues than whether or not you exposed an id.
If users shouldn't be able to access certain ids, such as perhaps an edit page, where an id is passed as part of the URL, then you control that via row-level access policies, not by obfuscating or attempting to hide the id. Security by obscurity is not security.
That said, if you're just totally against the idea of sequential ids, then use GUIDs. There is no performance impact to using GUIDs. It's still a clustered index, just as any other primary key. They take up more space than something like an int, obviously, but we're talking a difference of 12 bytes per id - hardly anything to worry about with today's storage.

Securely store data for multiple party's in a single table

I'm certainly no DBA and only a beginner when it comes to software development, so any help is appreciated. What is the most secure structure for storing the data from multiple parties in one database? For instance if three people have access to the same tables, I want to make sure that each person can only see their data. Is it best to create a unique ID for each person and store that along with the data then query based on that ID? Are there other considerations I should take into account as well?
You are on the right track, but mapping the USER ID into the table is probably not what you want, because in practice many users have access to the corporations data. In those cases you would store "CorpID" as a column, or more generically "ContextID". But yes, to limit access to data, each row should be able to convey who the data is for, either directly (the row actually contains a reference to CorpID, UserID, ContextID or the like) or it can be inferred by joining to other tables that reference the qualifier.
In practice, these rules are enforced by a middle tier that queries the database, providing the user context in some way so that only the correct records are selected out of the database and ultimately presented to the user.
...three people have access to the same tables...
If these persons can query the tables directly through some query tool like toad then we have a serious problem. if not, that is like they access through some middle tier/service layer or so then #wagregg's solution above holds.
coming to the case when they have direct access rights then one approach is:
create database level user accounts for each of the users.
have another table with row level grant information. say your_table has a primary key column MY_PK_COL then the structure of the GRANTS_TABLE table would be like {USER_ID; MY_PK_COL} with MY_PK_COL a foreign key to your_table.
Remove all privileges of concerned users from your_table
Create a view. SELECT * FROM your_table WHERE user_id=getCurrentUserID();
give your users SELECT/INSERT/UPDATE rights on this view.
Most of the database systems (MySQL, Oracle, SQLServer) provide way to get current logged user. (the one used in the connection string). They also provide ways to restrict access to certain tables. now for your users the view will behave as a normal table. they will never know the difference.
a problem happens when there are too many users. provisioning a database level uer account to every one of them may turn difficult. but then DBMS like MsSQLServer can use windows authentication, there by reducing the user/creation problem.
In most of the scenarios the filter at middle tier approach is the best way. but there are times when security is paramount. Also a bug in the middle tier may allow malicious users to bypass the security. SQL injection is one thing to name. then you have to do what you have to do.
It sounds like you're talking about a multi-tenant architecture, but I can't tell for sure.
This SO answer has a summary of the issues, and links to an online article containing details about the trade-offs.

What is the best way to handle user profiles in a database?

Almost every web application now allows you to setup a basic profile (Even Stack Exchange does). The question is how should you be storing the data in your database?
Should you just add more columns to your users database table, or should you setup another table called user_profiles that has a foreign key of user_id?
This is quite subjective:
Separate table
easier to fetch user without profile
when some user doesn't have a profile (one-to-one optional relationship), you don't pay anything in terms of storage
sharing profile (?!?) - can't imagine such a scenario, but...
Single table
no JOINs required when loading
related information in one place
strong one-to-one (typically every user will have a profile, maybe created implicitly) relationships tend to be merged to single table

Authentication Database Fields

I am implementing an authentication system into an existing database system. Currently, the database has a "Person" table that includes things like: First Name, Last Name, Date of Birth, Email (username), etc. This is the primary table for a user.
I need to add the following fields for authentication: Password, IsLocked, LockDate, LastLoginDate.
Would you suggest putting these fields in the Person table or would you put them in a new Authentication table? My original plan was for "Person" to simply contain data about that person, not necessarily about authentication.
The other approach could be to store the password along with the email in Person, but then place the authentication data in a separate table. This way, the username and password would be in the same place, but the meta data would be in its own entity.
Anyone have any thoughts?
Thanks for the help!
Keep them separate so that users can query the system for information about a Person without necessarily having access to their account credentials.
This also has a nice side-effect where not all Person entities may have accounts.
Keep the account information separate. Your current business requirement may be for each person to have only one account, but it could come up in the future that a person needs to have multiple accounts, or even that you need an account that is shared by multiple people. Having a separate table for authentication means that such future changes will have a smaller impact on your code.
Also, from the perspective of protecting authentication information, the fewer people/processes that can access the account data the better off you'll be. It's much easier to implement table-level access than column-level access.
I don't think it makes much sense to create a seperate table for Authentication data. Authentication can't exist independently of the Person, as far as I can tell - and there doesn't seem to be a way one Person could reasonably be associated with two Authentications (or vice versa).
In other words: There's a 1:1 relationship between Person and Authentication, so why split it off?

Database user tables and permissions

I'm making a db system project for college that requires online log-in for people to read information on their payments. I have a "person" table that stores information on people, and they have a unique identifier that will be their user name, with the password being generated somewhere else (given how the system works, this part represents no problem at all). However, sometimes some people won't be directly involved in the data inside the database, and instead they will have a password granted to them that will be stored inside the database.
Now. How do I assign "roles" to these users stored inside the database? By the way I'm working with Oracle and JSP as my host language.
Well, you have to either
use Oracle's native support for roles,
store the data you need in a table, or
derive it from something you have available outside the database.
For native support, see, for example, docs.oracle.com for CREATE ROLE.
For storing the data you need in a table, you might be able to use something as simple as
create table user_roles (
user_id integer primary key references users (user_id),
user_role varchar(20) not null references user_roles (user_role)
);
If you do that, pay close attention to permissions on that table. You don't want users to be able to escalate their role.
For deriving it from something outside the database, you might be able to use something like
network login name,
IP address,
cookie, or
something else.
I'd be a little surprised if any of those work well, though. Most of them will probably require storing something in the database, too.
When I need roles within a database application, I usually rely on CREATE ROLE.

Resources