I have a .NET Web API that allows clients to return details of People and associated data.
There are a number of non-fixed roles in the system (it's multi-tenanted) and each Role has access to particular fields e.g. Admin could see Date of Birth, non-admin can't.
The structure of the application is:
Client Controllers > Business/Service layer > Repositories > Database
Data access is currently being managed through a combination EntityFramework for Add/Update/Delete and Dapper for Queries.
My question is: is there a excepted standard/common of approach of filtering data at field level going to the client, and returning from a client before updating models in the database? Ideally if there was some sample code or application to demonstrate the approach.
My initial thoughts on this are to filter the ViewModels before they get sent to the client and perform checks before updating the EntityFramework models, but this seems disjointed. Also I'm not 100% on the best approach to this either way.
Other possibles I have considered are:
Use a formatter to remove data before being sent to client, and a custom security attribute to filter data before hitting the controller action.
Move away from EntityFramework and implement my own secure Data Access Layer to handle all of this
Implement the security at the database level
A ViewModel per entity per role, although I have discounted this as with non-fixed roles this can blow up quite quickly.
I'm not aware of any frameworks available that offer field-level security but lots of commercial products offer very configurable field-level security e.g. SalesForce, Microsoft CRM, etc.. and essentially I would like to implement something similar but on a smaller scale.
Related
I've searched a lot of posts and I have not been able to find a question which addressed my exact specific requirements. Here's what I'm trying to achieve:
Background:
I have a ASP.NET core MVC application. I'm trying to minimize the database trips by reusing the data which are not being changed regularly. I have 2 groups of data which I call Statics and Dynamics
Statics: They never change for the entire application life. (Entity types, Status names, etc)
Dynamics: They are specific for each login. (Business details, list of services, tax details etc. These will be different for each logged in user)
For the Statics, upon application start, I go to the database and store these values in the static fields of a static class. From this point forward everyone have this data without a single trip to the database. So far so good. Statics are being used in all layers; presentation, business, persistence. This saves me tons ot database trips.
My Problme
I want the following behavior for the Dynamics
Each time a user logs in, a data container (similar to Statics) is populated for that user only. So for as long as that user is logged in, she doesn't need to go to the database for her needs of anything in the Dynamics
When another user logs in, he gets his own set of Dynamic data container that he can use from anywhere in the application. From all the layers.
How can I achieve this functionality?
The Statics is a class in the Business layer and has it's own data manager which is being called upon application start up.
I need to have a similar setup for Dynamics with its own data manager which is being called upon each user log in to populate the Dynamics and reuse the data for the duration of log in.
Naturally I cannot use a static class and static fields because they will be overridden by each log in and all the other users get the incorrect data.
Many thanks in advance
I am now learning a concept of ASP.NET Core development and during my learning I have found out from the following article that a webpage needs to be protected from unauthorized access in order to prever from Cross Site Request Forgery Attacks.
I have followed several tutorials and for my own (learning) application I have:
Implemented the [Authorize] decorator on the top of my Controller (in my case it was API controller)
In the actual POST, UPDATE methods I have implemented if (ModelState.IsValid) call to check, if necessary parameters have been passed
Used ViewModels instead of actual Models that are used in a database when communicating with a website (or API in this case).
I have the following three questions:
1) Is this approach sufficient in order to protect my website? As an authentication method I am using simple CookieAuthentification. Or in other words (as this might be too broad question), is this approach on a right track to dishearten possible attacker?
2) In my current setup (of using ViewModels instead of real models) is [ValidateAntiForgeryToken] necessary? If yes, what purpose it serves?
3) Now the question (which I am most interested in) is regarding ViewModels. How can ViewModels protect my website from unauthorized attacks? I do understand that in my ViewModel I can only expose variables/properties that I want user to have access to (and hide the rest), but how can it protect my website, when I still need to expose my ID (primary key) (as without ID I cannot imagine how one would do e.g. DELETE / UPDATE calls)?
Any help in this matter would be more than appreciated as I am still learning this subject.
Web site security is a complex issue. Protections should be implemented that are commensurate to the sensitivity of data requiring protection.
1) Some level of Authentication is necessary to protect against an anonymous attack, where an attacker would have an infinite number of tries to get a successful attack.
2) [ValidateAntiForgeryToken] is required for any data change. Without it you could have a user who has successful authenticated and been given a valid cookie, that is then stolen by a malicious actor who has compromised the browser being used by your valid user, and use that stolen cookie to make unwanted data changes.
3) The use of ViewModels means that you have not exposed direct data calls to the database. Yes a malicious actor could modify data in undesirable ways, but is still limited to changes within the scope of your data layer. Without ViewModels it might be possible for an attacker to make changes that you never intended through SQL Injection. If you are using an ORM such as Entity Framework then the possibility of SQL Injection is less likely.
I currently have a layered architecture that is as follows:
Service Layer - This is the main interaction point with the domain.
Contains all the business rules, validation, etc.
Data/Repository Layer - This is the layer that handles all persistence of the data. Contains no business logic or validation. Contains basically Repository<T>, UnitOfWork (EF Specific) and all the EF things like DbContext, EntityTypeConfiguration's, etc.
Entity Framework
SQL Server
I am using an Anemic Domain Model, so basic POCO's that represent the problem domain.
I have a couple questions about exposing this via ASP.NET WebApi.
Where does the security live at? Basically things like does a user have the access to edit a record, or type of record. Can a user perform a specific action, etc. As well as things like Authentication/Role Based Authorization.
Should I use the WebApi as the actual service layer, or use it to expose my existing service layer over HTTP in a RESTful manner?
Given a basic example of say changing a name of a category, where do I enforce that the current user has authority to change said record? Do I rely on the Thread.CurrentPrincipal to get the Identity to check for a given role, and set that in the WebApi? Mvc Application?
Are there any good examples out there that show this type of situation I am talking about?
BTW - I am using ASP.NET MVC 5 to serve up the shell of the application (SPA) and then the front-end is going to be all AngularJS.
Regarding your first question about the level of security your services should have the correct answer is what I believe it should be a principle in all applications:
Services should have enough security to protect the data from unwanted users.
Once you create a service and make it public you are exposed to possible attacks of course having complex security rules may increase development time and some situations may create a decrease in performance; measure the level of the threat and plan your security accordingly.
WebApi was created with intention to provide services through Http/Rest all the principles and features build-in were made with that intention so regarding your second question and like you inferred at the end of it it is a service layer but an Http/Rest service layer.
WebApi uses an attribute Authorize to enforce security an as it is normally with .NET Frameworks you can inherit from it and extend it. You can learn more about it here.
And since you are using Angularjs and even though you will need MVC5 to use WebApi my recommendation is that you do not use MVC razor or any other server technology to render your pages.
I am developing an .net Winforms application and I need to secure the connection to the sql server 2008 database. I plan to create a webservice as a middle tier that will handle the authentication and that will provide data manipulation. Is there a better way to go with? Does .net have components or tools for that? What is the best technique?
Any info would be appreciated, thanks.
Define "secure". Obviously you wish to restrict access to data to users who really need that data. However, more information about the architecture is needed; is this an in-house app that will only ever be used inside a (secured) LAN, VPN or hosted environment? Or is this an app used on computers you do not control, that will transmit data over the Internet? How much security you need depends on what types of users will be using the software, from where, and how sensitive the data is.
MSS has pretty good security built-in. You can tie SQL users to Windows domain accounts, you can restrict "securables" (tables, views, SPs, etc) in myriad ways based on user or role, etc etc. I would first look at those capabilities, and seriously consider taking advantage of them in your security plan. One SQL user defined for use by any user of a particular piece of software, which has the permissions to do anything the software may require, is simple, common, and highly insecure.
If that's not good enough, or you want to fully abstract your data layer (for instance, if you need the software to be able to be pointed at any DB type from MSS to Oracle to MySql), then it might be a good idea to implement a Repository model with a service proxy. Like Brian, I encourage you to have a look at WCF. A WCF service is highly configurable, and can provide for independent authentication and for encryption. A well-designed WCF service will be very secure indeed.
Behind the service, you can implement a Repository pattern, which abstracts the details of how data is retrieved from the data store and exposes simple methods that return objects containing the data you want in a ready-to-use form. Now, your service methods will just map 1:1 to Repository methods, possibly with some translation to DataContract-serializable objects instead of the richer domain model available on either side of the service.
Have you looked at building a service tier, using WCF? WCF can bring a whole new layer of abstraction and security from the actual physical database.
WCF also allows you to use more secure bindings than a traditional web service allows, with built-in logging.
Also, check out this book sometime if you want a really good read on .NET Security:
The .NET Developer's Guide to Windows Security by Keith Brown
I have a 3 tier ASP.NET MVC 3 project that has a data layer, service layer then a presentation layer which calls upon the service layer to get data. I'm actually using the doFactory patterns in action solution.
I want to implement a custom membership, roles, profile provider but I'm not sure exactly where to put it. I was thinking of putting it in the service layer then have the provider call on the DAO objects to get the info.
Any other ideas?
You're thinking pretty well. Though the UI layer interacts with the client and takes their password, your service layer should process attempts the enter system.
Your action methods pass along the information to the service objects responsible for authorization.
Your service layer would have no idea whether it is in a web application or not.
The data layers is just the place where that information is stored, not where it is processed.
You might choose to keep the ID of the user in the UI layer, in session. On login the Service layer would take the username/password/whatever and return a UserID. Or, your action methods could pass in a session key into the service layer each time, to get the User information.
Edit due to comment: I'm doing this in my current project (couple $million scope). I have my security decisions in the action methods. (Though of course the tools for making this simple are objects from the Service Layer.) For example, if the current user doesn't have this role or that role, then redirect them to a rejection page, otherwise, do the thing. MyServiceLayerObject.DoThing() has no security inside it.
It's the simplest way for my app and many others. ("Simplest" means it will will be screwed up the least. When it comes to security, simple is good!) Since the Action method is the gateway to the functionality, having security in the service layer would just cause extra work and actually obscure what security was happening. Now, that's my app, where there is usually one place where each action takes place.
Your app may be different. The more different action methods and (especially) different components are using your Services Layer's functionality, the more you'd want your Service Layer functionality locked down with your authorization scheme. Many people feel that security should always be in the service layer, and that any additional security actions in the UI layer would be bonus redundancy. I don't agree with that.
Here is an existing implementation of Membership Providers in 3 tier world that I found when looking for the same thing...
http://elysianonline.com/programming/wcf-wrapper-for-asp-net-membership/
And here ...
http://elysianonline.com/programming/using-the-wcf-membership-provider/