How to authenticate, filter, and verify WCF-based oData result? - wcf

Can someone tell me if it's possible to do this with my WCF-based oData feed, and let me knlow what to search for or how to get started?
1) Authenticate - I'd like to make sure that the oData service is only accessed by someone who has already authenticated using the ASP.NET membership system
2) Filter - Suppose I'm returning a list of student classes... I'd like to make it so that students only see classes they enrolled in (based on username) and not the ones for that haven't yet been published.
3) Verify - I'm not sure if this is needed, but just in case some clever hacker finds a hole in MSFT's oData protocol, I'd like to verify the results of my Entity Framework data prior to streaming to the client. This would apply if there is a singleton DAL, thus creating concurrency issues. See 5:15 of this video for an example.
The test I want to do is verify that every row returned has a username column that equals the current session username.
[EDIT]
4) Encrypt - This is similar to #3, but I'd like to obfuscuate the primary key before it is sent to the client. In one case, the PK is the social security number and I don't want that being cached, or otherwise sent downstream. I would need to decrypt this on an oData write as well.

1) Authentication - as mentioned by Coding Gorilla above there's a series of posts on the WCF Data Services blog on how to implement different kinds of authentication.
2) Filter - this is exactly what query interceptors are for. See for example this article on MDSN http://msdn.microsoft.com/en-us/library/dd744837.aspx
3) Verify - if you think you really need to this, it might be a bit tricky. Currently WCF Data Services doesn't have an extensibility point which you could plugin easily to see the results being written out. You might be able to wrap the IQueryable instances returned by EF and do the verification when the results are enumerated, but I haven't seen that done yet, so don't know if it will work.
4) This will be tricky just in WCF Data Services. I would try to do this inside EF alone (not sure if it's possible though). The problem is that the key properties are used to address the entities, so they show up in URLs and queries. So you would not only need to decrypt them in the payloads but also in the query itself which would be a lot of work. Maybe somebody with more EF experience will know how to do this in EF alone (in which case WCF Data Services would see just the encrypted values and everything would work)

Related

Single API endpoint pros and cons

I am creating API and trying to figure out is planned approach any good.
That API is not public and it will be used by SPA and mobile app that I build.So I am thinking of GraphQL-like design but without posting json and with regular HTTP methods.
Something like this for GET methods:
Example 1 - get users with specific fields(_join indicates sql table join), ordering and limit:api.com?table=users&displayFields=id,name,email,address,tel,country_join&orderBy=asc&orderColumn=name&offset=0&limit=10
Example 2 - get users based on search parameters with all fields, ordering and limit:api.com?table=users&search=John&searchFields=name,email&orderBy=asc&orderColumn=name&offset=0&limit=10
I assume this is bad since REST is standard, otherwise I would see much more examples of this approach.
But why is this bad? For me it seems easier to develop and more flexible to use.
Is proper REST API for examples I provided easier to implement, safer, easier to use or cache?
The main difference I see between putting the variables in the url vs the request body are:
the length of the data as the url length is limited while the request body is not
special characters to be escaped in the url which can lead to long and unclear url
These are 2 pros in favor of data in request body, but I agree that data in url is much simpler to test and use as tou don't need an http client tool like curl or postman to validate your endpoints.
REST however has stricter conventions if you want to fully implement it:
use the right http requests (get, post, patch, delete and put) to implement crud operations on one single endpoint
return the right http code as a result
use standard data format for input and output (json or XML)
For better interoperability between systems it's advised to comply with REST and microservices design patterns.
For small applications we can follow some shortcuts and not comply fully. I have integrated several services so far and each time I can tell you no one of them implements standard REST :-)

Restful API design: how should user's and authority's endpoints be?

Based on similar questions, i came to the conclusion that the most convenient way to design this endpoints to GET requests should be something like:
GET /v3/users/
GET /v3/users/{userId}
GET /v3/users/{userId}/authorities
GET /v3/users/authorities/{authId}
My question is how should be the next endpoints:
1. Create authorities
POST /v3/users/authorities
POST /v3/users/{userId}/authorities
2. Update authorities
PUT/PATCH /v3/users/authorities/{authId}
PUT/PATCH /v3/users/{userId}/authorities/{authId}
3. Delete authorities
DELETE /v3/users/authorities/{authId}
DELETE /v3/users/{userId}/authorities/{authId}
What do you think? Intuitively, i go with first option on all cases but maybe is not the nicest thing passing the userId from body (i see it nicer passing it from url). Or should i implement both endpoints maybe?
Second approach is cleaner and more standard.
PUT/PATCH/POST/DELETE.. /v3/users/authorities/{authId} - [1]
PUT/PATCH/POST/DELETE.. /v3/users/{userId}/authorities/{authId} -[2]
Here, for example, if you pass authId in uri, why not userId ? The standard you will be following here is "resource/{uniqueId}/attribute/{uniqueId}". Ideally in your back-end code, you first look up for the specific resource, and then look up specific attribute(s) for the same resource with the keys/ids passed in the uri. Id is omitted when the action is going to affect all the resources!
If you use the approach [1], it looks like you are trying to add/update/delete an authority for ALL users! Definitely that is not the case.
It is doable to send the userId in the form/post data, but not the correct approach. In your form/post data, you should send the values that are going to be added/updated (in case of PUT/POST). Something like {authType: 'Admin', isGlobal: true, effectiveFrom: '12/12/2015'}. Obviously, userId does not fit here.
First, let me say that I agree with the answer Arghya placed, but I do think there could be a case made for shortening those UPDATE and DELETE urls down to v3/authorities/{authId}.
Of course, this would assume that the authId is unique for that Authority across the application. I personally don't see a point in specifying a user. Either the person that is hitting that route has access to the resource or not.
Just remember that RESTful is just an architectural style. You should do what fits best into your technology stack and makes the most sense for you and the clients interacting with this API.

Using HTTP for REST API: automatically cacheable?

I was wondering, to make a "RESTful API" you need to satisfy the 6 architectural constraints listed below:
http://en.wikipedia.org/wiki/Representational_state_transfer#Architectural_constraints
Is it safe to state that when you are creating a REST API over the HTTP protocol, the "cacheable" constraint is automatically satisfied? Because HTTP already provides a cache system "out-of-the-box" through HTTP headers: http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html
So no need anymore to worry about that?
Maybe sounds like a stupid question, but I want to be sure. :-)
Kind regards!
K.
Let me expand a bit on the challenges of creating correct caching logic:
Typically, the backend of the API is a database holding all kinds of little pieces of information.
The typical presentation within a REST API can be an accumulated view (So, let's say, a users activity log, containing a list of the last user actions within a portal, something along those lines).
Now, in order to know if your API URL /user/123/activity has changed (after the timestamp the client is sending you in the "If-modified-since"-header), you would have to check if there have been any additional activities after the last request. The overhead of doing that might be the same as simply fetching the result again. So, in a lot of cases, people just don't really bother, which is a shame, as proper caching can have a huge impact on Web App performance.
Maybe this gives a bit more detail,
Jan
you are correct, HTTP already gives you the means to identify cacheable elements, but as your API will be generated by some server-side logic, you will still need to make sure the code "behind" your API will se the right HTTP headers and be ready and able to react to "If-modified-since" requests in an ideal world.
Creating a reliable "Last-modified" timestamp as well as checking against it reliably is actually quiet a feat ;-)
Hope this helps a bit,
Jan

Consuming a REST API endpoint from a resource ID

Lets consider the following flow to a RESTfull API:
API root
|
v
user list
|
v
user details
|
v
user messages
Suppose I have a client to consume the API, and I want to retrieve messages from a user with ID 42.
From what I've been studying, my client is not supposed to know how to "build" urls, and it should follow the links given by the API.
How should I do to retrieve messages for the user with ID 42?
The only way I can think is "walk" the whole API from it's root to user messages, which doesn't look very pretty or efficient to me.
Eg:
1 - GET / and get the link to the list of users
2 - GET /user/?id=42 and get the link to details of the user with the ID 42
3 - GET /user/42/ and get the link to user 42 list of messages
4 - GET /user/42/messages/ and finally get the user messages
Did I get something wrong? Is this the right way according to Roy's Fielding paper?
Or is it ok to just assume the messages url is "/user/{id}/messages/" and make the request directly?
Use URL templates in your API root. Let the client consume the API root at runtime. It should look for a URL template named something like "user-messages" with the value of "/user/{userid}/messages/". Then let the client substitute "42" for "{userid}" in the template and do a GET on the resulting URL. You can add as many of these URL templates you want for all of the required, often used, use cases.
The difference between this solution and a "classic" web API is the late binding of URLs: the client reads the API root with its templates at runtime - as opposed to compiling the client with the knowledge of the URL templates.
Take a look at the HAL media type for some information about URL templates: http://stateless.co/hal_specification.html
I wrote this piece here some time ago to explain the benefits of hypermedia: http://soabits.blogspot.dk/2013/12/selling-benefits-of-hypermedia.html
I believe what your real concern is should you go about implementing HATEOAS or not. Now as it's an integral part of REST specifications, it is recommended that each entity should have a link to it's child entity that it encompasses. In your case, API ROOT should show list of users with each "user" having a link (/root/users/{id}) to corresponding user's details. And each User details entity will contain a link to the list of "messages" (/root/users/{id}/messages) which, finally, inturn encompass the link to the actual message detail as well (/root/users/{id}/messages/{messageId}). This concept is extremely useful (and thus a part of the specifications) because the client doesn't need to know the url to where your entity is exposed. For example, if your users were on http://users.abc.com/rest/users/{id} but your messages were on http://messages.abc.com/rest/{userId}/messages/{messageId}, the user entity that encompasses the list of "messages" will already have link embedded to point to the right resource on a different server.
Now that being said, I haven't actually seen many REST implementations out there (I must admit I do not have TOO MUCH of an experience, but enough to give an opinion) where HATEOAS is being used widespread. In most cases the resources are almost always on the same server (environment) and the paths to resources are almost always relative to the root url.Thus, it doesn't make sense for the clients to parse out the embedded links from the object when they can generate one by themselves, especially when the client would like to provide access to a resource directly (View the message directly without getting the user entity provided you already know what the messageId is).
In the end, it all depends on how close do you want your REST implementations to that of specifications and what kind of clients are you going to have. My 2 cents would be: if you have time, implement REST with HATEOAS and feel proud about it :). There are libraries out there that will make this implementation (HATEOAS) somewhat transparent to you REST implementation (I believe spring has one, although not very mature. You can look at it here). If you are like me and don't have much time to go that route, I think you can continue with a normal REST implementation without HATEOAS and your clients will still be OK with it (or so I hope!)
Hope this helps!
I found this article about hacking urls: Avoid hackable URLs.
There is a very interesting discussion about the topic of this question in the comments section.

How RESTful is using subdomains as resource identifiers?

We have a single-page app (AngularJs) which interacts with the backend using REST API. The app allows each user to see information about the company the user works at, but not any other company's data. Our current REST API looks like this:
domain.com/companies/123
domain.com/companies/123/employees
domain.com/employees/987
NOTE: All ids are GUIDs, hence the last end-point doesn't have company id, just the employee id.
We recently started working on enforcing the requirement of each user having access to information related exclusively the company where the user works. This means that on the backend we need to track who the logged in user is (which is simple auth problem) as well as determining the company whose information is being accessed. The latter is not easy to determine from our REST API calls, because some of them do not include company id, such as the last one shown above.
We decided that instead of tracking company ID in the UI and sending it with each request, we would put it in the subdomain. So, assuming that ACME company has id=123 our API would change as follows:
acme.domain.com
acme.domain.com/employees
acme.domain.com/employees/987
This makes identifying the company very easy on the backend and requires minor changes to REST calls from our single-page app. However, my concern is that it breaks the RESTfulness of our API. This may also introduce some CORS problems, but I don't have a use case for it now.
I would like to hear your thoughts on this and how you dealt with this problem in the past.
Thanks!
In a similar application, we did put the 'company id' into the path (every company-specific path), not as a subdomain.
I wouldn't care a jot about whether some terminology enthusiast thought my design was "RESTful
" or not, but I can see several disadvantages to using domains, mostly stemming from the fact that the world tends to assume that the domain identifies "the server", and the path is how you find an item on that server. There will be a certain amount of extra stuff you'll have to deal with with multiple domains which you wouldn't with paths:
HTTPS - you'd need a wildcard certificate instead of a simple one
DNS - you're either going to have wildcard DNS entries, or your application management is now going to involve DNS management
All the CORS stuff which you mention - may or may not be a headache in your specific application - anything which is making 'same domain' assumptions about security policy is going to be affected.
Of course, if you want lots of isolation between companies, and effectively you would be as happy running a separate server for each company, then it's not a bad design. I can't see it's more or less RESTful, as that's just a matter of viewpoint.
There is nothing "unrestful" in using subdomains. URIs in REST are opaque, meaning that you don't really care about what the URI is, but only about the fact that every single resource in the system can be identified and referenced independently.
Also, in a RESTful application, you never compose URLs manually, but you traverse the hypermedia links you find at the API endpoint and in all the returned responses. Since you don't need to manually compose URIs, from the REST point of view it's indifferent how they look. Having a URI such as
//domain.com/ABGHTYT12345H
would be as RESTful as
//domain.com/companies/acme/employees/123
or
//domain.com/acme/employees/smith-charles
or
//acme.domain.com/employees/123
All of those are equally RESTful.
But... I like to think of usable APIs, and when it comes to usability having readable meaningful URLs is a must for me. Also following conventions is a good idea. In your particular case, there is nothing unrestful with the route, but it is unusual to find that kind of behaviour in an API, so it might not be the best practice. Also, as someone pointed out, it might complicate your development (Not specifically on the CORS part though, that one is easily solved by sending a few HTTP headers)
So, even if I can't see anything non REST on your proposal, the conventions elsewhere would be against subdomains on an API.