CacheCow and ODATA in Web Api - caching

I'm looking at caching frameworks for my project and currently trying out CacheCow.
I have an odata enabled web api 2 project.
Simple controller test for a an Account entity.
Single get method that returns all Accounts. /api/Accounts. Cache works fine I can see the 304 response for subsequent requests.
Now if I do /Accounts?$top=3 - that doesn't use the cache, which I understand as is because the query string makes up the part of the cache key?
So, how would I make /Accounts?$top=3 read from the cache of /Accounts.
It's obviously the same data, I just want a subset and don't really want to hit the database to get it.
This is going to be even more important when using an AutoComplete control for example where its firing contains(Name, 'xxx') as the user types in the box.
Thx

Related

Dynamically Update Page in Application Requiring Authentication Via Azure AD

I am curious if anyone has a solution to this unique situation as I have a solution currently, though I feel it is not the most optimal.
The Situation.
I have built an MVC style web application that talks to a web API through http (authenticating via JWT). My web application is secured by appending authorization to its view controllers and redirecting to a Microsoft login endpoint - then directing back to the view where whichever given controller/function handles the request, connects to the API, appends data to the view, etc.
Preferably I would like to use JQuery/Ajax to submit http requests client-side and update a given view with whatever data the user may wish to see relative to the webpage they're on. This way I could control exactly what the user should see landing on the page any which way and submitting requests from web app to API. Also would enable better continuity between requests as there isn't actually a full refresh of the view. All in all it is my line of thought that this execution would lead to a nice user experience.
The Problem.
So the big issue that I have had to circumvent is CORS Policy. I initially attempted to use JS just as I said above but requests would be redirected to the login endpoint and blocked due to there being no CORS header appended to the request.
'So include a policy in your application and append an authorized header to your Ajax outgoing request' you might say, well... you cannot override CORS security around Microsoft's login endpoint.
My Solution.
What I have done simply instead is create HTML Forms around fields the user would pick and chose to specify what data they wanted from the API. Then carry over input data to the returned view via 'ViewData'
and using razor pages of course I can actually initialize JS variables via C# input.
Side Note
I use JS to transform the API data into graphs for the user to see. I am doing this with a JavaScript Library.
My Question to you.
This all leads me to ask then, is there a way to dynamically update a view without using JS? I require a method that can hit the login redirect without being blocked because the request initiated client-side.
Every solution I am aware in some way, shape, or form utilizes JS to make the request. So I am at a loss for how to truly get the functionality I am after without having my requests get blocked due to CORS Policy.
Thanks in advance y'all.

AJAX calls within MVC and Identity Server

I have been playing with Thinktecture IdentityServer3 and am keen to use it as the product looks great. However, I don't fully understand how to accomplish my flow which is probably fairly common:
Create Identity Server using Implicit flow
Setup an MVC web site
Setup a separate Web API
So far so good, as demonstrated in the examples on the site. I now wish to call the API using AJAX calls directly but for this i need an access token. It seems like a large overhead to have to route these through the MVC site itself (again, in the examples).
How can I accomplish this flow? Would it essentially blend the MVC and Javascript Client samples or is there a smoother way so the user only has to sign in once? Perhaps send the access token in a hidden field but then how would it renew?
Any help on understanding this would be great.
I've managed to come up with a solution which seems to work, not sure if it's best practice though...
Expose a method on the MVC site at AJAX/AccessToken
Method should be locked down with Authorize attribute to ensure the MVC part of the site is authenticating properly with IdentityServer
Method returns the users Access Token which was generated through the above call via MVC controllers
In JavaScript, simply use this endpoint to get an Access Token and then call the API manually
The call to get the Access Token should be secure as its within the same domain/authentication model as the MVC site itself
I've put up a sample here for anyone interested:
OIDC-Website
Check out the form post client to see the endpoints being called explicitly. You will need to hit the token endpoint to get your access token.
You should be able to use these endpoints in your AJAX calls, store the received claims and tokens in a cookie and take it from there.
Note that to renew the access token, you will also need to store the refresh token. The Implicit flow does not allow for refresh tokens (you'll need to use the Authorization Code Flow or the Hybrid Flow).

Should I use a Web API 2.2 custom filter or message handler?

I am building a Web API service which will accept 2 of 4 possible tokens in the header. These tokens are used for different purposes but will all be able to be resolved (using lookup in a DB and other operations) to a couple of key pieces of user data.
Only a limited number of endpoints in my controllers will need to receive this information and so I need to know if I should be building a message handler (I believe this is executed for all requests) or a custom action filter (attached via attributes to the specific endpoints.)
Which method is most appropriate for retrieving data from the request header, using it to retrieve user information and populating the header/request with the retrieved data for the controller to use?
Token is an over-loaded term but if you are using "token" as in security token meant for authentication, you can create an authentication filter. If your tokens are just identifiers using which you pull more data from a data store, action filter is a good choice. As you said, message handlers run for all requests (per-route or global granularity) and may not be a good candidate. However, message handlers run earlier in the pipeline and action filters run just before the action method. So, in future, if any other component in your Web API pipeline needs this data, action filter could be too late. If you know for sure only controllers will ever need this data, action filter is probably the best place, given the granularity they provide.

Can requests via Ajax to make direct db queries ever be made secure?

Suppose you would format your urls so that you could make direct model queries with a request using Ajax.
Making a query in Django:
MyModel.objects.get(id=4)
Making a query via request to url using Ajax:
/ajax/my-model/get/id/4/
The problem is that this presents a huge security problem, any user that knows how to make requests via Ajax could query the database by recognising that the url corresponds to a query of a specific model. However, if these kind of queries could be made secure, it would allow for much more well structured/reuseable client side code imo.
But I simply don't see how this can be made secure. I just want to make sure if this suspicion is correct.
Never trust input from the client. I think this is a very general rule in web development and applies to any request the client does. I think you have a couple options here:
use Django's internal Authorization mechanism. This is not authentication! Like this you can limit resources to be accessed to specific users only. Also look into reusable django apps, which seem to take some complexity out of that topic.
validate every input from the client. This is mostly for requests which are supposed to change data).
use an API framework like django-tastypie or django-restframework, which are easily plugable with your models and offer authentication and authorization out of the box.
In Django, such views will be protected by its authentication mechanism. It is possible to design the view so it will only allow specific users to query specific queries.

Hot Towel/Durandal/Breeze.js: how to vertically secure data calls?

I'm new to the whole client-side SPA world. I'm using the above technologies, which seem quite promising. However, one huge snag that I can't get over easily is the lack of built-in security. I had to manually roll out the user authorization, which IMHO should be part of the framework.
Now that I have that sorted, I'm getting major headaches with vertical security: where one user is logged in but can easily access other users' info by changing a few parameters in the browser console. I could pass the userId with every call and then compare it with the one on the server, but I was hoping that there would be an overarching solution that doesn't pollute the breeze data calls with user ids.
For example, let's say there's a call from the data service like this:
function getItems(){
var query = breeze.EntityQuery.from('Items').expand("Person");
return manager.executeQuery(query);
}
this will get all the items, not good. So let's limit by userId:
function getItems(userId){
var query = breeze.EntityQuery.from('Items').where("userId", "==", authentication.userId).expand("Person");
return manager.executeQuery(query);
}
in the second example, we get the userId from the authentication service, which stored the userId when the user was logged in. However, a malicious user can easily go the browser console and change that value.
Of course, I could pass the userId using withParameters(...) and compare it with the current one on the server, but I'd have to do that for every call, which doesn't seem right. Is there a better way to secure calls with the trusted user id?
#Ali - I understand your pain and your concern. You are right to fear any form of so-called security that relies on information passed in the URL. Fortunately there are excellent answers to your concerns and Breeze apps work well with them.
For example, have you studied the ASP.NET Breeze/Knockout Template? It uses Forms Auth for authentication and guards the Web API controller with an [Authorize] attribute. Only logged-in users can access any of the controller methods.
That authentication also sets the IPrincipal which the Web API controller makes available through its User property. You'll see User passed to the constructor of the TodoRepository. In that repository you'll find guard logic to restrict query and saves to just the Todo information belonging to the requesting user.
Look at the network traffic. You won't find any user identifying information in the URL or the request/response bodies. You will see an encrypted authentication cookie in a header.
An obvious flaw in the example is that the client/server traffic takes place in the clear. You must add transport level security (HTTPS) before you go to production. But this is a demo after all.
Why not just do this in the controller?
If the Web Api is secured with [Authorize] then you can get the users ID in the controller and make sure that the data returned is for the currently logged in user.

Resources