How is breeze.js handling security and avoiding exposing business logic - breeze

We are considering breeze js to build enterprise applications.
The awesomeness of breeze is that we can execute queries right from the client browser. This allows to constructs dynamic queries based on the users input without loading unnecessary data. I have found that using Breeze we can create business logic that reduces data traveling/transferring by 1/10 or even more when using a lazy loading strategy. using queries like these
Hooray breeze!!!
But what about Business Logic security,
For example, We could have a repository in which we could conceal, hide and obscure our business logic; and then use MVC Web API controllers to just make calls to those repository C# classes. so Breeze JavaScript talks to the WebAPi controller and the WebApi controller talks to the C# repository. The Controllers will always be kept very simple and easy to read, but the Repository may end up having lots of business logic for the company using the application. So if a hacker uses, for example, the Google Chrome developer's console to inspect the JavaScript code, all he/she will see are things like GetCustomers(), GetProductsForThisId(54). There is not much information that can be seen (or stolen) there. Because 90% of the Business Logic will live on the C# repository on the server .
How is breeze.js handling that ?
If we start moving the queries and business logic "from the controller's C# to the breeze JavaScript", we have to consider that our system is membership based. I think the more queries we expose to the client in JavaScript, the more vulnerable our software becomes, and the more we tell hackers how to hack our website and possibly steal information.

Security is a vital concern. It is wise to think carefully about the data and logic exposed on the client. How can we refine these sentiments into a concrete question suitable for an SO answer?
Nothing about Breeze should cause you to expose business logic to the JavaScript client. You can (and should) lock such logic safely inside your repositories and/or controller methods.
But I struggle to understand how client queries themselves are the kinds of business logic that need protecting. Where's the danger in a query for a customer whose name begins with 'A'?
You may rightly worry about a query for customers with net worth > $100,000. But the fault is not in the query. The fault would be in exposing such customer information to unauthorized users by any means, whether through a Breeze where clause appended to a query or a call to a service named GetCustomers().
The place to block unauthorized access to customers is on the server and you can do that as easily inside a Breeze controller action method returning IQueryable as you can in your GetCustomer() method. The burden falls on you in either case to impose the necessary security constraints on your controller and within the methods that you expose.
You write the controller. You write the repositories. You have access to the user's permissions. You are in complete control with an uncompromised ability to expose as much or as little as you wish.
FWIW, your Breeze EntityManager can call service methods that do not return IQueryable<Customer>. It can call Web Api controller methods such as IEnumerable<Customer> GetCustomers() or Product GetProductForId(int id). In my opinion you will lose the flexibility of Breeze's query facilities without gaining any security. But that's just my opinion. Breeze will support your choice, whatever it may be.
I'd be happy to try to answer a more specific "how to" question.

would like to add that you can restrict users that are not authorized from quering by using the attributes in webapi if you get 401 code back from the server just popup a login screen and redo the work needed after the user is logged in
so a user may try to get data about an order but he won't get it unless he is authorized to do so

You can to a lot of stuff using breeze.js
First of all check my answer regarding security here
How to handle authorization with Breeze JS?
Also although breeze.js can be used like a normal ORM on the client (which can be extremely helpful at times), you should keep your business logic in web api controllers and expose only the necessary stuff using OData queries.
If you need any data manipulation logic, then you should do it on the server using a specific method for that.
Only UI logic should be present on the client, also consider that there are several performance implications if you start performing multiple queries directly from the client. Either expand the entity graph to load more results or use more specialized methods that return object. Breeze will introspect the results and consume the entities happily without implications.

Related

Exposing Large Data Models via OData and WebAPI

I have an EF model with about 200 tables, 75 of which I'd like to expose via REST in an MVC app. I started by adding a WCF Data Service (WCF-DS), pointed it to the EF context, and bam, I had the entire database mapped to REST URI's with full OData syntax support in about 2 minutes.
Next I tried to create the same REST URI space with WebAPI. When I tried to add a WebAPI OData Controller the first thing it asks for was a Model Class and when I was done creating the controller (and copying all the required ODataConventionModelBuilder code into the WebApiConfig) I only had one REST endpoint! My impression now is that WebAPI is not well suited to expose entire EF models with a lot of brute force.
So my questions:
Am I missing a way to map a bunch of WebAPI endpoints to a EF model in one fell swoop?
(Maybe T4 templates that build all the WebAPI code when I generate my EF model??)
Are there any compelling reasons to consider WebAPI vs WCF-DS to expose large URI domains?
(Some say that the benefits of WebAPI are to have fine grained control over each and every MVC/HTTP request but that seems counter-productive if the goal is to conform to the OData spec. I'm not sure I want to have 75 controllers and 1000's of lines of code that would tempt my dev colleagues to change one entity's behavior that would result in different behavior from other entities.)
(For cross cutting concerns such as security, caching, or performance throttling WCF-DS seems to have sufficient configure-ability with Interceptors and its DataServiceConfiguration class. Are there any features of WebAPI that would do better here?)
Thanks.
Update: I found this article by Julie Lermon that helps a bit: http://msdn.microsoft.com/en-us/magazine/dn201742.aspx
Since I have only exposed EF model using WCF DS, I can't comment on Web API questions. But we never really had a reason to replace WCF DS with Web API for our model because as you also noticed, EF and WCF DS play so nicely together that you basically get an OData feed for free. On a client side the situation is different: we started with WCF Data Services Client that is trying to mimic Linq to Entity Framework, but is has so many limitations that I ended up writing my own OData client (you can read about what made us unhappy with WCF DS client part here).
Coming back to server side: our domain was large, we had 80+ tables with almost 1000 columns. And we even supported all CRUD operations using batch updates (OData analog of transactions). While I would recommend to think twice before exposing database record update operations over OData protocol due to design principles, we haven't had any technical issues with that approach.
It is my opinion that Web API + OData extensions is highly overrated for a large majority or use-cases, and my argument is that OData is fundamentally data-oriented while Web API has come to become a great fit for general-purpose APIs, which include service-oriented APIs.
Your use-case is, I believe, a prime example of a very data-oriented layer since you don't seem to want to add much domain logic on this tier (server-side of this HTTP API). And WCF-DS works great for that, especially if you're merely wrapping an EF model which does 90% of the work for you (as you've already observed).
Of course it would be a different story if you were modeling more intricate processes at that layer (in that tier), so exploring both options like you did is always a very good idea. Normally the obvious choice should come naturally, either you'll be writing a lot of redundant code with Web API (go with WCF-DS) or you'll be fighting with WCF-DS's very rigid framework by playing with odd entities and not-very-RESTful OData actions (go with Web API alone).
Web API with its OData extensions stands somewhere in the middle, although it's not always clear what advantages it provides over custom WCF-DS providers. I guess it's nice for people who already know Web API or ASP.NET MVC, and may be a requirement if you want open source. I personally wouldn't debate on this technology with technical arguments, except for the few gotchas one should know about (but which have nothing to do with its design). I've ranted about all of this a while ago, should you want more, but I stress again that there are no hard truths in any of this -- discussing architecture and design is in no-trivial proportions a matter of opinions.
Update: WCF-DS was killed.

Using breeze js not to interact directly with DBContext

I'm very new with breezejs and having a few questions.
I think that breezejs has very nice features so I can replace my own datacontext. However, I don't want breezejs to interact directly with the dbcontext layer. In fact, in my application, the Service layer only exposes ViewModels - not even the real Business models - to the Controllers . So i'm not so sure whether I can use Breeze or not, since in few Breeze's examples, I only saw Breeze interact directly with DBContext.
Thanks.
=========================================
Thanks Ward for the answer,
About the features that I like from Breeze is that it will help to reduce a lot of time to build my own client-side view models. And to build a SPA, maintaining client-side view models is really painful for me, especially my application have desktop app client and other hand-held device's apps as well. Also, to handle the mapping from a JSon object to Knockout - which means with each view models, I will need a mapper as well.
Currently, my architecture is like this:
Server-side:
Repository layer <=> Service layer <=> Controllers (with the Web API that exposes to Client-side)
Controllers only can get the data (in format of a View Model) by sending request through Service.
So, my question is whether it is possible to make use of Breeze to query and also its integration with knockout.
Breeze never works directly with your DbContext; it works with the service model that you expose through endpoints on your service (e.g., Web API controller methods). But you certainly get the most value from Breeze when the client can query and save entities that are structurally the same as entities on the server.
You can retrieve ViewModels with Breeze - you can call almost any HTTP service method with Breeze. It's not clear to me how Breeze would help you manage those ViewModels on the client once you had retrieved them.
What features of Breeze seem "very nice" to you? Your answer to that question will help you determine if Breeze can be helpful with your preferred architectural style.
Querying data through Breeze without API controllers using DBContext directly should be no problem, saving might be harder but still manageable. I think the most complicated part is to get metadata to the client.
According to this SO answer, samples for exposing metadata from other sources that DBContext directly should be out in a week or so.
Meanwhile, check BreezeJS spa-template sample as there is repository pattern involved on the server side which makes it similar to your data access setup.

Using Repositories and service references in MVC controllers

I'm having some trouble with deciding on a solution for my mvc application.
Background.
We have an EF model which we perform operations on via WCF Services (not data services).
I have an MVC application which has a number of Repositories that talk directly to the Services and return WCF types back to a controller which is calling the repository method, a type called for example WCFUserEntity (it's not actually prefixed with WCF).
Inside the controller I plan to automap the WCFUserEntity to a ViewModel entity.
What is bugging me about this solution is that because i'm returning WCFUserEntity to the controller I have to have a reference to the WebService proxy in my controller which doesn't sit well with me, i'd like my controllers to know nothing of where the repository has got the data from. So another option for me is to do the automapping inside of the repository and return the ViewModel entity to the controller, i can't find much around which supports this idea though, so really what i'm looking for is validation of this 2nd solution or help with a 3rd.
thanks, Dom
You may want to consider a third option.
The use of ViewModelBuilders.
in your controller they would work like this:
var myViewModel = myViewModelBuilder.WithX().WithY().Build();
WithX and WithY would be methods that would add stuff to your viewmodel internally (within the builder, for example WithCountriesList() if you want to add a dropdown showing the countries in your view) and the Build method would return the internal viewmodel after adding all the bits with the WithXXX methods. This is so because most of the time you may want to add lists for dropdowns and things that are not part of your original model (your userEntity in this case).
This way, your controller doesn't know anything about how to build the viewmodel, your repository is also agnostic of viewmodels. All the work is done in the Builder. On the downside, you need to create a ViewModelBuilder for each ViewModel.
I hope this helps.
How I would approach this might require some architecture changes, but I would suggest you approach your WCF API to return ViewModels instead of entities.
For starters, think about bandwidth issues (which would be an issue if you are hosting the WCF in Azure or the cloud). If your ViewModel is only using a few specific properties, why waste the bandwidth returning the other data? In high traffic scenarios, this could cause a waste of traffic that could end up costing money. For example, if your view is only display a user and his questions, there's no reason to send his email, answers, point count, etc.. over the wire.
Another issue to think about is eager loading. By having the WCF service return a ViewModel, you know you have all the data (even when it pertains to related entities) required from the view in one trip to the WCF service. You do not need to get the WCFUserEntity and then ask WCF for WCFDocumentEntities that are related to that specific user.
Finally, if your WCF API is built around ViewModels then you have a MUCH clearer understanding of the business processes involved. You know that this specific request (and view in the system) will give you this specific information, and if you need different information for a different view then you know that it's a completely different business request that has different business requirements. Using stack overflow as an example, it makes it trivial to see that this business process is asking for the current user with his related questions, while this business process is requesting the current user with his related answers.
Using ViewModels in your data retrieval WCF API means that your frontend layers do not necessarily know where the data came from, it just knows that it called a business process and got the data it needs. As far as it knows the data layer connected to the database directly instead of WCF.
Edit:
After re-reading, this actually looks like your 3rd option. Most research on the net don't talk about this option, and I don't know why, but after having some similar frustrations you are having (plus others listed in this post) this is the way I have gone with my business layer. It makes more sense and is actually (imho) easier to manage.

How should I do authentication in a ASP.Net MVC site?

I have a site which has an area that requires authentication. Right now I use the roles attribute on all the controllers in that area, and I run a query to retrieve that users ID, and all their settings.
It seems like a code or design smell to me that I am retrieving the userid and settings each time a controller in that area loads up? I'm not sure if I should be using sessions, or if ASP.Net MVC 2.0 provides some unique way to handle this. Another concern is security.
Overall, I don't really know which way to turn. Design wise I would like the userId and settings retrieved only once when the user logs into the area. Right now I grab the userId each time a controller loads up, and then if required, I query the database for their settings each time as well.
One of the rules about security is that you shouldn't try to do it yourself. There are many pitfalls in doing an authentication system correctly without leaving loopholes or backdoors. Thus, in that regard, you might consider the SqlMembershipProvider that comes with .NET. It can be used with MVC and provides the means to get roles and the current security context, is easy to setup and configure and will be more secure than rolling your own.
If you are not using SQL Server, you have a couple of choices. One solution would be to use something like SQL Server Express or SQL Server Compact Edition to maintain the credentials. Another solution would be to mimic the SqlMembrershipProvider database schema and then write a custom provider that communicates with that schema.
The last choice would be to write a custom MembershipProvider class. While this is still rolling your own, it forces you into the structure of the MembershipProvider so that you can swap it out at a later date for a different one (e.g. ActiveDirectoryMembershipProvider) and provides a common interface for interacting with credentials and logins which for example enables easy use of the built-in Login control.
If you are already using a MembershipProvider and are asking about storing additional user-specific data, then I would suggest the SqlProfileProvider with all the caveats I mentioned above about the SqlMembershipProvider. the ProfileProvider provides a structure for maintain user-specific data with the currently logged on user.
For more information:
Introduction to Membership
Implementing a MembershipProvider
ASP.NET Profile Providers
You could also implement a custom identity. They are very easy to implement, and they let you store whatever user information you want in Identity, which is then stored in the cookies that Identity puts down, so you're not hitting the DB every time to get that info.
Just create a new class that inherits from GenericIdentity, and you'll be on your way.
You of course have to be careful how much info you put there since it's in a cookie, but usually user related information in the case you're talking about here isn't so big.
We use a custom identity to store a few bits of info about the user, and it works out pretty well.
You could store an object in session that holds all the required user information. You will just need to add a property in the Controllers, Views or other base classes where you want to retrieve the user information/profile. This would be the authorisation info as opposed to any authentication info (eg Forms authentication)
You might try "Windows Identity Foundation". I've been using it on one of my projects for a while. It allows for "claims-based authentication", which basically means that you get to designate "claims", strings of information that describe the user when she logs on.
Once logged on, the user's claims can be read from the HttpContext.Current.User field. You can also use "Role" claims that seamlessly integrate with a role-based authentication schema; meaning that you can give the user a "manager" role claim and then use `if (User.IsInRole("manager")).
As an added bonus, WIF makes it very easy to re-use your login screen in other applications.
All in all, it's very flexible, but the documentation is very poor. I've asked and answered a number of questions about "Windows Identity Foundation" on StackOverflow.
We have done this quite a few times in the past. Similar to what Thomas mentions, what we have generally done is implemented a new Membership provider based on the Microsoft SQL Memberhsip provider to do this. We inherit from the base MembershipUser class and add any custom properties we would want to have on the user object. You have to implement a database read for the Membership provider on the GetUser implementation, so you can consolidate your extra properties you need into that database read.
If you are using SQL server, Microsoft has release the 2.0 code for it. You can get more information at Scott Gu's blog.
http://weblogs.asp.net/scottgu/archive/2006/04/13/442772.aspx
If you want to start from scratch, they also have good resources at MSDN.
http://msdn.microsoft.com/en-us/library/f1kyba5e.aspx
and
http://msdn.microsoft.com/en-us/library/6tc47t75.aspx
Once you have implemented your provider, you can then add the Membership user to the Items collection of the current web context to get access to it from your code. The non extended properties from the base base user class are also available on the Request thread like normal.
With the Microsoft release of the 2.0 version of the source code , we found it helped us alleviate some concerns that exist about reinventing. Another thing to consider for your implementations is based on your scenario, you can bypass implementing some of the code. An example of this would be the CreateUser code if you are hitting a back end system that already has the credential information.
It seems like you're relatively happy with your authentication process but you want to explore other options for session/settings.
My suggestion has to do with settings only (roles, preferences, etc.)
In my opinion, having to traverse the whole technology stack from UI to Business Tier to DB tier to DB is sometimes a bit overkill.
For data that isn't likely to change during a session, this adds a lot of overhead... There are potentially several data transformations happening (DB (Relational Format) -> ORM -> Web Service XML Serialization -> Web Tier deserialization).
You might consider a session system that doesn't rely on a heavy RDBMS system or on the ASP.NET Caching / Session model. There are options that are very performant and that scale well.
You could use RavenDB by Ayende Rahien (Built for .NET). Its main goal is to provide low latency, high performance access to schema-less JSON documents.
Using this solution, you would set up ravenDB in the web tier so that access to data is very quick.
The first time you authenticate and retrieve settings, you would store the userID and settings information in this session DB.
Every time you load your controller after that, the settings data is accessible without having to go back to the RDBMS.
This DB could also be used to cache other web related data.
As for security, the settings data makes it to the web tier regardless of the method you use. This solution would be no more or less secure than the other options (more secure than an unencrypted cookie). If you needed to, you could encrypt the session data - but that will increase your overhead again.
Just another one of the million options to consider.
Good Luck,
Let us know what you decide!
Patrick.

Where to put auditing or logging?

I'm currently working on an ASP.NET MVC project using NHibernate and I need to keep track of changes on some entities in order to be able to make some reports and queries over the data. For this reason I wanted to have the data in a table, but I'm trying to decide where to "hook" the auditing code.
On the NHibernate layer:
PRO: Powerful event system to track any change
PRO: Nothing can be changed in the application without notice (unless someone uses raw SQL...)
CON: As I have a generic repository... then I have to filter out the useful entities (I don't need to track everything).
CON: I don't have easy access to the controller and the action so I can only track basic operations (update, delete...). I can get the HttpContext at least to get some info.
On an Action Filter at Controller level:
PRO: Full information on the request and web application status. This way I can distinguish an "edit" from a "status change" and be more descriptive in the audit information.
CON: Someone can forget a filter and an important action can be taken without notice which is a big con.
Any clue?
Update: See how to Create an Audit Log using NHibernate Events.
I think doing this at the repository level is a much better fit. Mostly because you may, in the future, decide to add some method of access to your repository which does not go through MVC (e.g., a WCF interface to the data).
So the question becomes, how do you address the cons you've listed about doing it on the NHibernate layer?
Filtering out the useful entities is simple enough. I would probably do this via a custom attribute on the entity type. You can tag the entities you want to track, or the ones you don't; whichever is easier.
Figuring out what the controller really intended is harder. I'm going to dispute that you can "get the HttpContext"; I don't think it is a good idea to do this in a repository, because the separation of concerns. The repository should not be dependent on the web. One method would be to create custom methods on the repository for actions you'd like to track differently; this is especially attractive if there are other aspects of these edits which behave differently, such as different security. Another method is to examine the changes by comparing the old and new versions of the objects and derive the actual nature of the change. A third method is to make no attempt to derive the nature of the change, but just store the before and after versions in the log so that the person who reads the log can figure it out for themselves.
I'd rather put it in the data (NHibernate in your case) layer. Putting it in the controller and asking other people (or yourself, in the future) to implement controllers accordingly conflicts with object-oriented design principles.
I do this with NHibernate. Objects that require auditing implement an IAudtable interface and I use an Interceptor do the auditing on any object that implements IAuditable by intercepting OnFlushDirty, OnDelete, and OnSave.

Resources