User authentication when using single database per client? - asp.net

My company is building an ASP.NET HR application and we have decided to create one database per client. This ensures that clients cannot accidentally view another client's data, while also allowing for easy scalability (among other benefits, already discussed here).
My question is - what is the best way to handle security and data access in such a scenario? My intent is to use a common login/account database that will direct the user to the correct server/database. This common database would also contain the application features that each user/role has access.
I was not planning to put any user information in each individual client database, but others on my team feel that the lack of security on each database is a huge hole (but they cannot articulate how duplicating the common access logic would be useful).
Am I missing something? Should we add an extra layer of security/authentication at the client database level?
Update:
One of the reasons my team felt dual user management was necessary is due to access control. All users have a default role (e.g. Admin, Minimal Access, Power User, etc.), but client admins will be able to refine permissions for users with access to their database. To me it still seems feasible for this to be in a central database, but my team doesn't agree. Thoughts?

We have a SaaS solution that uses the one DB per client model. We have a common "Security" database too. However, we store all user information in the individual client databases.
When the user logs into the system they tell us three pieces of information, username, password and client-id. The client-id is used to lookup their home database in the "security" database, and then the code connects to their home database to check their username/password. This way a client is totally self-contained within their database. Of course you need some piece of information beyond username to determine their home database. Could be our client-id approach, or could be the domain-name requested if you're using the sub-domain per client approach.
The advantage here is that you can move "client" databases around w/out having to keep them synced up with the security database. Plus you don't need to deal w/cross-db joins when you're trying to lookup user information.
Update: In response to your update... One of the advantages to each customer having their own DB is also the ability to restore a customer if they really need it. If you've split the customer's data into two databases how do you restore it? Also, again, you'll need to worry about cross-db data access if the users are defined in a DB other than the home DB.

I've always been of the opinion that security should be enforced at the application level, not the database level. With that said, I see no problem with your intended approach. Managing accounts and roles through a central database makes the application more maintainable in the long run.

You may want to look into using the ASP.NET membership provider for handling the authentication plumbing. That would work with your stated approach and you can still keep all of the authentication data in a separate database. However, I agree with Chris that keeping one DB will utlimately be more maintainable.

Related

How to secure database without authentication?

I am creating an Unity game where I want to have global top 50 score list with usernames. I use Firebase realtime database. There is no need for user to authenticate. I am not that familiar with database security and pretty beginner with this concept. I am using Rest Api from Unity Asset store because it was pretty easy to send and get data from databse.
How can I be sure that every score sent to database is from my app?
Add a dedicated user with password to your database
Somewhere in you app, add those credentials e.g. in a ScriptableObject / in some component
Always use those credentials to authenticate
Note that your app can still be decompiled and thereby cheated.
You can at least make it more difficult by encrypting the data etc.
The only way really around is to have an account and sessioning server to assure a user is locked in with a valid session.
If you don't use Firebase Authentication, you can't restrict who can access your database. Anyone will be able to issues a query, and they can even do it using the Realtime Database REST API. All they have to know is the name of your project.
Even if you do use Firebase Authentication, anyone may still effectively authenticate and access the database outside of your app using other public APIs.
My experience is that you can't stop dedicated "users" from cheating global at high scores. I made a small handfull of trivial games for windows phone with global top 50. Even if your game is unpopular, and you obfuscate your code, and you are on an unpopular platform, and you encrypt your network traffic: somebody is going to jailbreak their phone, decompile your app, and inject their own high score into your game before high scores are sent to the global list. The only way I ever came up with to combat this was to keep track of play sessions -on the server- to make sure their scores were theoretically possible based on how long they were playing.
Disclaimer: I don't know anything about Firebase
From what I can tell, you will need to set up access for Default and Public sections of your configuration to tell the database who can and cannot access your database. Here's their documentation on Get Started with Database Rules.
In general database access, no one should know the details of your connection to a database, so all calls should only ever come from your app.

Protecting sensitive customer data in cloud based Multi-Tenant environment

We are building a multi-tenant cloud-based web product where customer data is stored in single Database instance. There are certain portion of customer specific business data which is highly sensitive. The sensitive business data should be protected such that nobody can access it except the authorized users of the customer (neither through application not through accessing Database directly). Customer want to make sure even the platform provider(us) is not able to access specific data by any means. They want us to clearly demonstrate Data security in this context. I am looking for specific guidance in the following areas:
How to I make sure the data is protected at Database level such that even the platform provider cannot access the data.
Even if we encrypt the Data, the concern is that anyone with the decryption key can decrypt the data
What is the best way to solve this problem?
Appreciate your feedback.
"How to I make sure the data is protected at Database level such that even the platform provider cannot access the data"
-- As you are in a Multi-Tenanted environment, First of all you would have to "single tenant your databases" so one DB per customer. Then you need to modify the application to pick up the database from some form of config.
For encryption as you are in Azure you would have to use the Azure Key vault with your own keys or customer's own keys. you then configure SQL to use these keys to encrypt the data. see here and here
if you want the database to stay multi-tenanted, you would need to do the encryption at the application level. However this would need the application to know about customer keys, hence I dont think that this would be a valid solution.
"Even if we encrypt the Data, the concern is that anyone with the decryption key can decrypt the data" - yep anyone with the keys can access the data. For this you would need to set the access controls appropriately on your key vault.. so the customer can see only their keys.
In the end as you are the service provider.. the customers would have to trust you some what :)

ASP.NET Application Connection String and SQL Server Security / Permissions

I am deploying an ASP.NET application and SQL Server (2008) database on a live (production) server. The physical server is running both SQL Server 2008 and IIS 7 - it is provided by a hosting company and is not part of our internal network.
I have a couple of questions regarding database security and the connection string for the ASP.NET application.
Previously I would create a database user and specify the SELECT/INSERT etc. permissions for each table - but my issue is that there are 50+ tables in this database, so doing this would take a long time.
The application requires SELECT/INSERT/DELETE/UPDATE on each table.
Is there a better way than specifying the permissions for each table individually?
Is there an equivalent of integrated security for a live web server - what are the drawbacks?
Or is there a way of elevating the access rights for a particular user to full access for a particular database
Also how would the connection string change?
I just looking for some expert advice, just someone to point me in the right direction and a link to some documentation on how to achieve a better way of doing it.
Many thanks.
You have essentially three unrelated questions in your bullet list, not one.
The first one is a better fit at ServerFault.com, as it deals with SQL Server, not necessarily a programming question.
However, Google paid off, and here's a method for doing it: http://www.tech-recipes.com/rx/2298/sql_server_2005_easily_grant_select_all_tables_views/
Alternatively, you can just assign the user to the correct groups as described in #Oded's answer here: TSQL granting read and write permissions to all tables
For the second one, Integrated Security, yes, there is a way to use integrated Security with ASP.NET. See this article: http://msdn.microsoft.com/en-us/library/bsz5788z.aspx
The biggest drawback is that it's more to configure. it's a non-standard (but supported) configuration, so maintenance programmers may not have seen the setup before.
Also, if you're doing this, there could be security concerns if you're using an account that has permissions elsewhere. Be sure to follow the principle of least privilege. It might be best to create a Domain account specifically for each website, so if one gets compromised, it limits the damage that can be done. You know your security concerns better than I do, so this may or may not be relevant advice, but it's something to consider.
Finally, (and this is probably too obvious to point out) it would be foolish to use a real person's UserId. If that person leaves the company and their account is removed, the website will obviously break.
Now that I've found an answer for the first question, the third one becomes moot.
You can create or use an existing database role. Then you put the user into that role to allow that user to have all the permissions you need. For example, you might put the user account you are using in your connection into the db_datawriter role given the scenarios you described.
See http://msdn.microsoft.com/en-us/library/ms189121%28v=sql.105%29.aspx
This article also related to how you could elevate a user's permissions.
Integrated security will work--it just requires that the login used on the computer that is making the connection be recognizable by the database server (in the same or in a trusting Windows domain).

In SAAS architecture, how do I handle db schema and MVC user logins for multi-tenants

Our requirement is something like this.
We are building a multi-tenant website in ASP.NET MVC, and each customer should be able to create their own users as per predefined user roles.
We are thinking about to create a schema for few tables which would be common for customers. So customer can login to system according to their schema logins and we need not to alter any queries to serve all of them.
We are referring http://msdn.microsoft.com/en-us/library/aa479086.aspx Shared Database, Separate Schemas.
Can someone suggest on following
1. After creating schema how to authorize user against a particular schema
2. Is this possible that without any changes in queries db can serve multi-tenants
Thanks in advance
Anil
After much research, I can say that, although it takes more development up front and more checks along the way, shared database and shared schema is the way to go. It puts a little bit of limits on how easily you can cater to a client's specific needs, but from my point of view SAAS isn't about catering to a single client's weird needs. It's about catering to the majority of clients. Not that it's a SAAS but take iPhone as an example. It was built to cater to the masses. Rather than focusing on doing everything it's built to be one-size fits all just by its simplicity. This doesn't help your case when it comes to authoriztion but it'll save you dev hours in the long run.
If you are asking this in the context of SQL Server authentication/authorization mechanism, i can asnwer this question with saying that every user has a default schema which helps query engine to find out required object in the database.
SQL Query Engine will look at the user's default schema first to find the required object (table). If it founds the object in user's schema then use it, otherwise goes to system default schema (dbo) to find it.
Check this article's How to Refer to Objects section to find out how it works. The article also has some information about security concepts related to schemas.

Database Authentication for Intranet Applications

I am looking for a best practice for End to End Authentication for internal Web Applications to the Database layer.
The most common scenario I have seen is to use a single SQL account with the permissions set to what is required by the application. This account is used by all application calls. Then when people require access over the database via query tools or such a separate Group is created with the query access and people are given access to that group.
The other scenario I have seen is to use complete Windows Authentication End to End. So the users themselves are added to groups which have all the permissions set so the user is able to update and change outside the parameters of the application. This normally involves securing people down to the appropriate stored procedures so they aren't updating the tables directly.
The first scenario seems relatively easily to maintain but raises concerns if there is a security hole in the application then the whole database is compromised.
The second scenario seems more secure but has the opposite concern of having to much business logic in stored procedures on the database. This seems to limit the use of the some really cool technologies like Nhibernate and LINQ. However in this day and age where people can use data in so many different ways we don't foresee e.g. mash-ups etc is this the best approach.
Dale - That's it exactly. If you want to provide access to the underlying data store to those users then do it via services. And in my experience, it is those experienced computer users coming out of Uni/College that damage things the most. As the saying goes, they know just enough to be dangerous.
If they want to automate part of their job, and they can display they have the requisite knowledge, then go ahead, grant their domain account access to the backend. That way anything they do via their little VBA automation is tied to their account and you know exactly who to go look at when the data gets hosed.
My basic point is that the database is the proverbial holy grail of the application. You want as few fingers in that particular pie as possible.
As a consultant, whenever I hear that someone has allowed normal users into the database, my eyes light up because I know it's going to end up being a big paycheck for me when I get called to fix it.
Personally, I don't want normal end users in the database. For an intranet application (especially one which resides on a Domain) I would provide a single account for application access to the database which only has those rights which are needed for the application to function.
Access to the application would then be controlled via the user's domain account (turn off anonymous access in IIS, etc.).
IF a user needs, and can justify, direct access to the database, then their domain account would be given access to the database, and they can log into the DBMS using the appropriate tools.
I've been responsible for developing several internal web applications over the past year.
Our solution was using Windows Authentication (Active Directory or LDAP).
Our purpose was merely to allow a simple login using an existing company ID/password. We also wanted to make sure that the existing department would still be responsible for verifying and managing access permissions.
While I can't answer the argument concerning Nhibernate or LINQ, unless you have a specific killer feature these things can implement, Active Directory or LDAP are simple enough to implement and maintain that it's worth trying.
I agree with Stephen Wrighton. Domain security is the way to go. If you would like to use mashups and what-not, you can expose parts of the database via a machine-readable RESTful interface. SubSonic has one built in.
Stephen - Keeping normal end users out of the database is nice but I am wondering if in this day and age with so many experienced computer users coming out of University / College if this the right path. If someone wants to automate part of their job which includes a VBA update to a database which I allow them to do via the normal application are we losing gains by restricting their access in this way.
I guess the other path implied here is you could open up the Application via services and then secure those services via groups and still keep the users separated from the database.
Then via delegation you can allow departments to control access to their own accounts via the groups as per Jonathan's post.

Resources