A collegue of mine needs to implement custom logging of WCF messages, for debugging purposes, but also for traceability (logged data will be saved for future reference and verification).
Examples like this one, Capture XML In WCF Service, shows how to do this for the host, but he needs it for the client application.
Can anyone help me/him with some pointers to what to look for, or where to start?
Since we need to talk to a database to log the data, a simple configuration change to log to a file on disk, like this MSDN example, Configure Message Logging, is not enough for our needs.
This is a C# 3.0 application for .NET 3.5.
The example you cited: it is very similar/dual for the client. Instead of IDispatchMessageInspector, there's IClientMessageInspector. Instead of IServiceBehavior, use IEndpointBehavior, etc. The OM will steer you in the right direction.
Related
I have made a C# application , now I want to create custom survey (actually sending data automatically to me, about - crashes , usage duration etc.) to enhance my application .
How can I do it ?
You may do this:
Host a REST service at your server, the common way is to add a WebAPI controller in ASP.NET MVC project.
On the client application create a System.Threading.Timer instance and set desired schedule to send the statistics. Or just send them each time user starts your application.
Send statistics to your REST service using WebClient/HttpClient.
Tutorials:
Get Started with ASP.NET Web API 2 (C#)
Call a Web API From a .NET Client (C#)
Sorry for the rough reception you received with that one comment. Many of us understood you weren't asking for us to write code for you, and I think you had a legit question.
You might want to also look at the .Net Trace capabilities. While you won't get data sent to you automatically, there's a built-in, easy-to-use framework that's unobtrusive and let's you gather statistics. Here are some links to check out:
The Trace Class
How to Add Trace Statements to Code
See also
Trace Listeners
So there you go. Another possible way to approach this.
I'm using ServiceStack but am not sure how to approach what must be simple and common concepts. Perhaps this should be posted as two separate questions.
How would I provide the server URL to the client? It's not inherently a ServiceStack problem but would like to know if there's something out of the box which I've missed. I'm thinking either through a config file for a client desktop application or perhaps a web service discovery mechanism, if such a thing exists.
edit: I am referring to the base / root URL of the server, where the clients are desktop applications (in some cases deployed in house). Most ServiceStack examples use a hard coded "localhost:82". So a mechanism to discover the real URL is needed..
To generate a RESTful service I would like to provide links (href's) so that a client could potentially navigate without knowing too much about the service. Is there a simple way to do this? Is it a matter of extending my response DTOs and pushing these details? From a separation of concerns POV it doesn't feel like the best way to do this.
Thanks!
I think that the built in ServiceStack metadata page can help you out on both accounts. It should be available to you automatically at http//:[service_root]/metadata. For example:
http://www.servicestack.net/ServiceStack.Northwind/metadata
You could provide this URL to a customer, and they should be able to interact with the service without issue. It provides detailed information on all service operations, different ways to call them, and even sample request/responses in supported content-types.
You can provide operation descriptions to help clarify even further by decorating your request DTOs with the [Description] attribute.
[Description("This is a service description for thinger.")]
public class Thinger
{
}
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.
I would like to have a Traffic COP or Controller WCF Web Service that doesn't do anything with data but instead gives orders to another WCF Web Service to do so.
Could someone give me an example of how this might be able to be done. It would be preferable that I was not getting into any APM stuff. Instead just an observer who later gets to spin another one way contract to a WCF Web Service when it needs to after it sees that there are no more other WCF Web Services with the same meta data in memory or processing currently.
If this is impossible please say so. Unless you know a small example of how it is done. Maybe a pointer where somebody has already covered the topic?
Thanks apolfj
I don't really understand your question, but maybe this will help:
MSE is a "service virtualization" approach
Stocktrader has a WCF load balancer included in it.
Maybe one of them will fit your needs.
Having a 'traffic cop' service that all traffic goes through before it gets to the actual web service for processing will add extra overhead to your solution. Then you also have issues like once you've logged a call going to a particular web service, how do you find out if the response was successful? Then you hvae to do more logging of some sort and finally return the result to the client. If I understand what you were saying correctly (which I'm not entirely sure I do) you would be looking at something like;
Client -> TrafficCop -> Service1
Client -> TrafficCop -> Service2
OR
Client -> Service1 -> TrafficCop
...depending on where you want the entry point and what you need to do.
I would probably remove the traffic cop web service entirely and implement some API's for your service to implement and have each web service log some information before a service operation is called and after the operation has completed. I'd recommend you take a look at this link; http://msdn.microsoft.com/en-us/magazine/cc163302.aspx which covers behaviours, operation invokers and paramter inspectors.
This way each web service can log information, check access, rules, report errors before and after execution to a database or another TrafficCop web service if you really want. But I'd probably be inclined to just stick all that information in its own database. Thus each web service (depending on what you're doing) may have connections to two databases. One for the web service itself (if that's needed) and one to the TrafficCop / logging database.
At a later date you then may choose to add a website that pulls all the information out of the traffic cop database and allows you to easily browse / search it. It could highlight warnings or other issues your web services logged.
Summary
If all you need to do is logging and related functionality I would consider having each web service log and / or check rules and other things before and / or after a service operation is invoked. At a later date you could consider adding an admin site that surfaces all this information so you can easily keep an eye on how your web services are performing. You may even like to log information like how long it takes to respond to certain requests.
If this is not what you are after I would suggest you add more information and continue to keep your original question up to date.
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...