I am new to RESTful web services. We are taking the REST route for building our public web services to be consumed by out clients.And i had a few questions.
Are there any kind of limitation with pure REST webs services? and if yes then would a hybrid REST web service take care of those limitations?
I am thinking about using SSL + Hash Message Authentication Code (HMAC) in Authorization header for security along with IP based based filtering. what do you guys think about it?
Are there any good client side tools for testing?
Currently i am using the following
http://code.google.com/p/rest-client/
And what about some kind of client side code generation tool?
The following links are my source of info.
http://msdn.microsoft.com/en-us/library/dd203052.aspx
Link
The first thing to keep in mind is that a REST service should be stateless, which is very different when compared to a SOAP/RPC type of service interface. Using REST methodology requires you to rethink how you want your clients to interact with the service, breaking down the interactions into clear and concise method calls.
REST
+ Lightweight messages, very little overhead (other than the XML itself)
+ Easily readable results, can easily test with a web browser
+ Easy to implement
- Looser interface, loose type checking
SOAP
+ More rigid, with a strict contract definition
+ Plenty of development tools available.
Looking through the WCF MSDN documentation, WCF SOAP support was integrated from the start while REST support is a recently added feature. I myself am having a hard time finding documentation for authentication/security for REST services, as most of the documentation is directed towards SOAP.
Client side generation tools: I haven't come across any for REST services as REST doesn't define a service contract as SOAP does. WADL is an attempt to do that for REST services.
http://en.wikipedia.org/wiki/Web_Application_Description_Language
http://wadl.codeplex.com/
I'm interesting in reading more responses dealing with authentication and security, as I'm looking into that myself.
This is a good starting point of a WCF REST WebService:
REST / SOAP endpoints for a WCF service
(BTW: Stackoverflow has nice REST kind of urls.)
You can test a REST service with just a web browser (Go to the url and get the XML or JSON). Fiddler is also good tool, and FireBug-plugin for FireFox. I usually make a thin service-interface project and a separate (unit-tested) logics-project.
For authentication I would first generate a Guid and a timestamp. Then based on those a hash (.NET supports SHA256 and SHA512). The Guid can be stored to server (database table) to map it some concrete numerical id. Then you can have a rest url like:
/myobject/1?timestamp=20100802201000&hash=4DR7HGJPRE54Y
and just disable the hash & timestamp check in development environment (e.g. with AOP). With timestamp I would check that the stamp is between 15 minutes back and forward in time (=should be enough to prevent attacks).
Will your service be visible to the public/internet and is your client a jQuery or Silverlight -client? Then you still have a problem: You don't want to include a secret key in the client software code.
So you need to generate hash in server and some kind of cookie to store the client session. (This can be done e.g. with a separate login-page/application in a folder with different config-file.) I remember that this book did have something on the topic:
If you want to enable the HttpContext when using WCF, you need to set <serviceHostingEnvironment aspNetCompatibilityEnabled="true"> under <system.serviceModel>.
Then you can check current user identity from HttpContext.Current.User.Identity.Name.
However, if you want to make a pure REST service then you don't use cookies, but a HTTP Basic Authentication coupled with SSL/TLS for each call.
I think that it's easy to make a client with just LINQ2Xml or jQuery so maybe client generation is not needed.
Or you can also have both, a SOAP and a REST interface, and use a service reference to make a client.
One thing to keep in mind is that you can take REST as a philosophy (everything should be reachable by a clean URL, without hidden strings attached) or as a dogma (you have to use PUT and DELETE even if that means a lot of hardship down the line).
The emphasis is on simplification - like using simple data types for params instead of stuctured pileups, nor clobering interface for superfluous reasons (like towing giant page "title" in a url), not using headers which are not well known and de-facto standard.
So, you can design perfectly RESTful interface using just GET and retain usability and testability from web browsers. You can also use any standard authentication methods or several of them for redundancy depending on your actual target audience. If you are making an app to run on a corpnet with standardized credentials and tokens you can continue using that. If you are doing something for very general access you can use combination of GET args and/or cookies - keeps your URL-s clean for 99.99% of users.
You can even serve both JSON and XML (like Google maps for example) and still be RESTfull, but you can't do full scale SOAP (complex input types etc). You can do limited SOAP - simple types for requests, always expressible as GET args, people still get WSDL for documentation.
Hope this paints flexible enough picture - the way of thinking above any strict dogma.
Related
I have read many articles in the web so far, about the differences between WCF and ASP.Net web API. Unfortunately I could not come up to a clear idea about what will serve my purpose. Most of the Articles I have read highlighted on the design point of view of the two web services. But I am confused what will work best for my project and why? Here is my brief description of the project.
I need to create a communication channel between two servers (both are written in C#). The servers will communicate using messages (certain type of commands). The messages sometimes can be only acknowledgements, and sometimes the messages may contain instructions to do some computation. For example, one message can be draw something, or send an SMS etc. And not necessarily the messages will involve any database transactions. But the messages can sometimes send large text files as payload (around 1-5 MB maxm). What I believe WCF is very will surely do this, but can I do the same with ASP.net web API. Because so far all the example I have seen for ASP.Net web api: they are good for RESTful services that manipulate some kind of DB store (GET, PUT, DELETE). But in my case I will need to expose service points that will
do some kind of processing such as return the value of a computation, sending and acknowledging messages, etc.
Not just manipulating a DB-store.
So, what should be the best and simplest way to do so? It is needed to be mentioned that I did not find any straight forward example of achieving this using ASP.Net web API.
The Question you have asked is an overly-broad or primarily opinion-based, and its hard to give an example for what you have asked.
Important Points:
Firstly, if you are going to create a service which would be used on different platforms, then go with WCF.
Secondly, if you are creating internet service which is going to use external resource, then go with Web API.
Web API is the best choice if you are going to create a service for low bandwidth devices or mobile devices to access client.HTTP
request/response is also more readable as compared to SOAP because it
contains header, body, etc. which makes it complex.
Just take few minutes and read the below article, until you get complete understanding of few principles.
Original Source Can be found Here, Here and Here.
To whom choose between WCF or WEB API :
Choose WCF when you want to create a service that should support special scenarios such as one way messaging, message queues, duplex communication etc.
Choose WCF when you want to create a service that can use fast transport channels when available, such as TCP, Named Pipes, or maybe even UDP (in WCF 4.5), and you also want to support HTTP when all other transport channels are unavailable.
Choose Web API when you want to create a resource-oriented services over HTTP that can use the full features of HTTP (like URIs, request/response headers, caching, versioning, various content formats).
Choose Web API when you want to expose your service to a broad range of clients including browsers, mobiles, iphone and tablets.
Why to choose Web API
Web API doesn't have tedious and extensive configuration like WCF REST service.
It is very simple, creating service with Web API. Where as With WCF REST, service creation is bit difficult (requires clear understanding of configurations).
Web API is only based on HTTP and HTTPS and easy to define, expose and consume in a REST-full way.
Web API is light weight architecture and good for devices which have limited bandwidth like smart phones.
My Opinion:
Simplest way to do so - Web API (Since you dont have any examples for this)
Hardest Way is (Configurations) - WCF (Better go with WCF, since you have examples)
I hope this gives you a clear idea about what to choose...
First things first, RESTful is a stateless and uniform interface norm that can be applied to web services. It doesn't have to be automatically and only plain old CRUD service backed by a DB.
In the real world, we can hardly say that all web REST API respect fully the norm, in fact they don't most of the time, especially the stateless part.
For your message based API, especially if it's bidirectional and event based, you can use websockets and consider the REST API a way to expose an uniform, stateless web interface to create those. And yes you can use websockets with ASP.NET WebApi there's plenty of tutorial out there, even for the newer ASP.NET Core.
The "between services" interactions part is no different than the usual Web browser <=> Web service, you're just using C# code instead of JS for the client.
I can hardly recommend WCF that uses SOAP since it's hardly portable considering the web standards nowadays. For instance if want to use a browser client instead of another ASP.NET service, well you'll have to do additional code client side to handle supports.
You can use WCF websockets, providing the almost all the advantages of WCF SOAP.
tl;dr :
You can mix RESTful and Websockets, it can actually be better than going full REST or full Websockets
It's personal preference to use SOAP over websockets but do comes with a potential technical debt considering what you want to do afterwards
Message API between services is no different than a message API between a service and a browser
WebAPI is not just good for RESTful webservices. You can easily send requests to a WebAPI controller and handle it the way you want : calculations, sending messages, interact with a CRM, interact with DB or anything else.
WCF was created to manage SOAP based webservices and brings extra complexity. It handles TCP, Mime...
If you just need to handle HTTP requests, the simplest way is to go with WebAPI.
I would suggest Web API if it is for RESTful services as WCF was never made to serve as Restful services although you can serve as one where as Web API was made particularly for this.
I have N quantity of "clients", and each one has to implement a web service for my .Net app to consume. I dont want to add a service reference for each client because they can change at any moment, as well as the URLs, so I store the URLs on a database and dinamycally create the endpoint depending on which client I want to access.
I was wondering if I have to force my clients to write the same type of services(either WCF or JAX-WS) or I can still connect to one or another without writing some kind of conditional logic.
ie. If JAX-WS then "do this" ELSE IF WCF "do other stuff"
Also I was wondering if adding WS-*(wshttpbinding) security would add more complexity for the interoperability(or interchangeability) of the two technologies.
Any comments about this approach would be greatly appreciated.
It's possible to implement this without having to use an if-else , all clients/implementations (.NET and Java) must to use the same contract (WSDL) which should not be a big issue.
For the WS-* this is quite easy using only .NET BUT it's hard (not impossible) to get it working from .NET to Java so I usually end up doing basicHttp using SSL with either basicauthentication (username/password) or certificates. This is a lot easier than wsHttpBinding from .NET to Java.
Like Cheeso says, start with the WSDL, i.e. create a client and service in .NET, this will give you a WSDL, then take that WSDL and use it to implement the Java clients.
Start with WSDL first. If you don't know what this means, google it.
This does not guarantee interoperability but it gets you a long way on the path.
As for adding WS-*, yes, that introduces an additional level of interop challenge.
I am developing a REST client which will talk to a project management service called attask.
Their REST API is convenient because it returns simple JSON that is easy to use in my code. Because of this I decided to build the interface with jQuery. I quickly discovered that I cannot use AJAX from my site to the Attask API because of the Same Origin Policy.
My first thought was to develop a server-side rest client using RESTSharp that would act as a bridge between my javascript and the Attask API.
Before I could get started with that implementation I discovered JSONP. This is new to me. It turns out that the Attask API supports JSONP. jQuery supports JSONP natively so suddenly I'm back to making a complete jQuery interface with no need for server-side intervention.
My question is, is there a reason not to use JSONP? Would there be any benefit to going the extra mile and building the server-side REST client and using real AJAX calls?
Just bear in mind that JSONP is exactly what you're looking for: a workaround for the Same Origin Policy. With that will come all the security problems that the Same Origin Policy was intended to avoid. The upside is that you get to choose a specific domain that you trust. The downside is, if that domain decides to violate your trust they can now run arbitrary javascript code on your web pages, allowing them to send any information they want to their own servers.
If you trust 'em, go for it. If you don't, set up your own server-side proxy.
I have a web service written in C# using SOAP. A client has requested the same service be available as a REST based service.
Is there a clever/quick way I can achieve this, or am I looking at a rebuild from new?
SOAP based services are built with a completely different set of constraints than REST services. If the services is simple then the end result of the two approaches may look somewhat related, but in reality they are two completely different approaches.
SOAP and REST are different not only conceptually but mechanically.
Conceptually SOAP methods are pretty much RPC, remote procedures. So your web methods look like "GetListOfCustomers" and "DeleteCustomer". While in REST you model Customers as resources and use HTTP verbs on these resource. To get the list of customers client will send HTTP GET and server will return customer representation in XML, JSON, HTML or custom format. Customer representation may have embedded URL links that will allow client code to delete customer for example. This is called HATEOAS
Mechanically SOAP is a layer on top of HTTP. Layer that ignores and reimplements existing HTTP capabilities like envelop, verbs, caching, encoding etc. As opposed to REST that relies on all these HTTP features. So mechanically REST is simpler because there is no additional layer that SOAP has.
When you were asked to make existing SOAP service to be available as REST it probably implied purely mechanical aspects. You probably need "XML RPC over HTTP" which will require some work on your part but may not be as hard as redesigning API from SOAP/RPC to REST/HATEOAS.
The solution will depend on how you implemented the SOAP web service.
This is not a "conversion". You will be writing a REST-based service to do the same sorts of thing that your SOAP service does. If you developed your SOAP service correctly, then you will be able to reuse much of the code. You will then be able to deploy a single service that serves both requirements.
Disclaimer: I've tried Googling for something that will do what I want, but no luck there. I'm hoping someone here might be able to lend a hand.
Background
I have a .NET class library that accesses a secure web service with the WSE 2.0 library. The web service provides a front-end to a central database (it's actually part of a data-sharing network spanning multiple customers) and the class library provides a simple wrapper around the web service calls to make it accessible from a legacy VB6 application. The legacy application uses the class library to retrieve and publish information to the web service. Currently, the application and class library DLL are both installed client-side on multiple workstations.
The Problem
The catch is that the web service we are accessing uses HTTPS and a valid X509 client certificate needs to be presented to the web service in order to access it. Since all of our components live on the client machine, this has led to deployment problems. For example, we have to download and install per-user certificates on each client machine, one for each user who might need to access the web service through our application. What's more, the web server itself must be accessed through a VPN (OpenVPN in particular), which means a VPN client has to be installed and configured on every client machine. It is a major pain (some of our customers have dozens of workstations).
The Proposed Solution
The proposed solution is to move all of this logic to a central server on the customer site. In this scenario, our legacy application would communicate with a local server, which will then go off and forward requests to the real web service. In addition, all of the X509 certificates would be installed on the server, instead of on each individual client computer, as part of the effort to simplify and centralize deployment.
So far, we've come up with three options:
Find a ready-made SOAP proxy server which can take incoming HTTP-based SOAP requests, modify the Host header and routing-related parts of the SOAP message (so they are pointing to the real web server), open an SSL connection to the real web server, present the correct client certificate to the server (based on a username-to-certificate mapping), forward the modified request, read the response, convert it back to plaintext, and send it back to the client.
Write a proxy server by hand that does everything I just mentioned.
Think of completely different and hopefully better way to solve this problem.
Rationale
The rationale for trying to find and/or write a SOAP proxy server is that our existing .NET wrapper library wouldn't have to be modified at all. We would simply point it at the proxy server instead of the real web service endpoint, using a plain HTTP connection instead of HTTPS. The proxy server will handle the request, modify it to so that the real web service will accept it (i.e. things like changing the SOAPAction header so that it is correct), handle the SSL/certificate handshake, and send the raw response data back to the client.
However, this sounds like an awful hack to me me at best. So, what our my options here?
Do I bite the bullet and write my own HTTP/SSL/SOAP/X509 aware proxy server to do all this?
Or...is there a ready-made solution with an extensible enough API that I can easily make it do what I want
Or...should I take a completely different approach?
The key issues we are trying to solve are (a) centralizing where certificates are stored to simplify installation and management of certificates and (b) setting things up so that the VPN connection to the web server only occurs from a single machine, instead of needing every client to have VPN client software installed.
Note we do not control the web server that is hosting the web service.
EDIT: To clarify, I have already implemented a (rather crappy) proxy server in C# that does meet the requirements, but something feels fundamentally wrong to me about this whole approach to the problem. So, ultimately, I am looking either for reassurance that I am on the right track, or helpful advice telling me I'm going about this the completely wrong way, and any tips for doing it a better way (if there is one, which I suspect there is).
Apache Camel would fit the bill perfectly. Camel is a lightweight framework for doing exactly this kind of application integration. I've used it to do some similar http proxying in the past.
Camel uses a very expressive DSL for defining routes between endpoint. In your case you want to stand up a server that is visible to all the client machines at your customer site and whatever requests it receives you want to route 'from' this endpoint 'to' your secure endpoint via https.
You'll need to create a simple class that defines the route. It should extend RouteBuilder and override the configure method
public class WebServiceProxy extends RouteBuilder
{
public void configure()
{
from("jetty:http://0.0.0.0:8080/myServicePath")
.to("https://mysecureserver/myServicePath");
}
}
Add this to a Camel context and you'll be good to go.
CamelContext context = new DefaultCamelContext();
context.addRoute(new WebServiceProxy());
context.start();
This route will create a webserver using jetty bound to 8080 on all local interfaces. Any requests sent to /myServicePath will get routed directly to your webservice defined by the uri https://mysecureserver/myServicePath. You define the endpoints using simple uris and the dsl and camel takes care of the heavy lifting.
You may need to configure a keystore with your certs in in and make it available to the http component. Post again if you've trouble here ;)
I'd read the camel docs for the http component for more details, check the unit tests for the project too as they are chock full of examples and best practices.
HTH.
FYI: To have the http component use your keystore, you'll need to set the following properties
System.setProperty("javax.net.ssl.trustStore", "path/to/keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "keystore-password");
You should look into WCF, which supports the WS-Addressing protocol. I believe I've seen articles (in MSDN, I think) on writing routers using WCF.
You should also get rid of WSE 2.0 as soon as possible. It's very badly obsolete (having been replaced by WSE 3.0, which is also obsolete). All of its functions have been superceded by WCF.
I believe an ESB (Enterprise Service Bus) could be a viable, robust solution to your problem. There is an open source ESB called Mule, which I've never used. I did mess around with ALSB (AquaLogic Service Bus) a while back, but it would be expensive for what you are describing. Anyway, the thing that you would want to look at in particular is the routing. I'm not sure it would be a simple plug 'n play, but it is indeed another option.
You can also do this with Microsoft ISA Server, a commercial Proxy/Cache server. It will do many of the things you need out of the box. For anything that is not possible out of the box, you can write an extension to the server to get it done.
ISA Server is not free.
ISA is now being renamed to "Microsoft Forefront Threat Management Gateway".
It is much more than a web proxy server, though - it has support for many protocols and
lots of features. Maybe more than you need.
There is a service virtualization tool from Microsoft available on Codeplex called the Managed Service Engine which is intended to decouple the client from the web service implementation. It might fill the bill or give you a running start. I haven't really investigated it thoroughly, just skimmed an article in MSDN and your description reminded me of it.
http://www.codeplex.com/servicesengine
http://msdn.microsoft.com/en-us/magazine/dd727511.aspx
Your security model doesn't make sense to me. What is the purpose of using HTTPS? Usually it is to authenticate the service to the clients. In that case, why does the server need to keep the clients' certificates? It is the clients who should be keeping the server's X509 Certificate.
Why do you need to go through VPN? If you need to authenticate clients, there are better ways to do that. You can either enable mutual authentication in SSL, or use XML-Security and possibly WS-Security to secure the service at the SOAP level. Even if you do use SSL to authenticate clients, you still shouldn't keep all the client certificates on the server, but rather use PKI and verify the client certificates to a trusted root.
Finally, specifically for your proposed proxy-based solution, I don't see why you need anything SOAP-specific. Don't you just need a web server that can forward any HTTP request to a remote HTTPS server? I don't know how to do this offhand, but I'd be investigating the likes of Apache and IIS...