Web Service Consumption C# - c#

Hi I have One wsdl file at my local machine. I tried testing it through SoapUI by sending an XML request with Header and SAML token asserted. When i added the WSDL file to my project's web reference, I can see the functions/operation which i want to consume and all its parameter which are to be passed but I cannot find a way to add header and SAML token to it.
Also the URL i have to hit is a HTTPS url so i have to add client Certificates.
All this i have tested over SoapUI and i am getting the response.. Al i want is how to send a request through dotnet code when my WSDL is at local. Since i am working for some Highly secured client i cannot reveal any code. I am posting this question on an assumption that this may be a common problem faced by people.
Please demonstrate your solution with an example.

You should consume your service with Wcf. That will allow you to abstract the transport details away from the client code. With this method you can have separate configurations between the server and client (production using HTTPS, plus no client configuration required, no HTTPS for local dev machine). There are tons and tons of great tutorials on WCF here and on the internet at large, so I'm not going to post a big long example here, but Google is your friend.

Related

WCF: Using Multiple Authentication Schemes on same endpoint

I have a WCF service which i host as a Windows Service. I need to support both Windows and NTLM authentication on the service endpoint.
I came across a MSDN page which explains exactly the same with .NET 4.5, here's the link:
http://msdn.microsoft.com/en-us/library/hh556235(v=vs.110).aspx
Going by this, I configured my service endpoint in code as explained in the self-hosted services section of the above link. But, when I test this doesn't work. I captured the traffic and observed that there's no HTTP 401 challenge sent by the service, instead, it directly fails with HTTP 400 Bad Request error. I believe that should have been a HTTP 401 challenge sent to client.
Did I miss anything here?
Well it is possible and I could make it work after 4 days of struggle, the errors HTTP Bad Request does not indicate the problem. But, As I added service metadata behavior with HttpGetEnabled it worked.
Also, ensure if you define ServiceAuthenticationBehavior you do mark the ClientCredentialType to InheritedFromHost. This would ensure the authentication schemes as indicated by the ServiceAuthenticationBahavior are applied.
Hope, this would save someone else's 4 days! :)
You can have multiple authentication schemes running within the same Windows service, but not at the same end point - that's not possible.
For instance, I can create and IIS or self-host a web service called NeedHelp that uses three kinds of authentication, and here are my endpoints:
http:/ /NeedHelp:8001/NoAuth
http:/ /NeedHelp:8002/WindowsAuth
http:/ /NeedHelp:8003/CertAuth
All of those can run under the same web service, all hosted by IIS or self hosted as a Windows service. But they all need separate port addresses.

How to host wcf Routing Service on IIS?

So this is in relation to my question here.
So I have an existing wcf service running already, hosted on IIS. I created a Router Service that will do some XPath filtering on the header. So if the header is match then go to service1.
Now, I hosted my Router Service on IIS and I can access it like http://iis.com/myrouter/router.svc/ and give me this wsdl stuff. Now when I try to request a service method on service1 like this http://iis.com/myrouter/router.svc/general/getMyMethod?blah=blahblah. It gives me a 404 error. I used fiddler by the way.
On my request through fiddler I added my custom header like "service_version:1". I used a namespace by the way on my <namespaceTable> but I don't know how to append it on my request. Anyway, my main concern is how can I make my Router Service work on IIS?
Update: I am using System.ServiceModel.Routing.RoutingService by the way. So what I am trying to accomplish is Routing Services.
Your help is greatly appreciated.
You are likely facing this. A SOAP service can't be accessed that way because it relies on the SOAP package. Here is another article that should lead you down the right direction. However, the direction it leads you down is that testing a SOAP service by hand is not to be desired and probably a futile effort.
However, one note is that it leads you to use the WCF Test Client - that's the best direction to go my friend and it's very easy to use. Provide the URL and it will do the rest.
Invoke soap wcf service in Fiddler like in Wcf test client
Accessing the RESTful Endpoint
If you're trying to test the RESTful endpoint then the issue is likely surrounding the routing that is configured. Please refer to this link for assistance - make sure you're setting up your service the same because the attributes they use build the routing properly. Remember that you're not going to reference the RESTful endpoint with the same address as the SOAP endpoint.
http://geekswithblogs.net/michelotti/archive/2010/08/21/restful-wcf-services-with-no-svc-file-and-no-config.aspx
You can also check out this link.
Hosting WCF soap and rest endpoints side by side

Hosting 2 WCF services locally for debugging purposes

This problem may be a little broad, but I'm going to go ahead and put it out there and then elaborate as needed on details.
My overall goal is a WCF rest service that when hit calls a WCF soap service, then parses the response of the soap service and extracts desired information and sends it back via http post (to a mobile device eventually).
I am having a problem getting the soap response to the rest service.
This is what is happening:
Console application calls rest service via http post. this is working
Rest service submits message to soap service. this is working
Soap service recognizes message and performs requested operation. this is working
After that, the return value is being generated in the soap service, but it isn't making it back to the rest service. I have tried numerous things. I've got the bindings identical, I've checked and double checked and triple checked the data contracts. I've tried quite a few things and what I'm wondering is if there is a problem using localhost to host 2 services. Both services are hosted locally and both are wcf services.
Would this cause a problem like the one I am seeing?
I will elaborate on the problem as needed as much as I can.
After fixing the problem, I can answer with confidence that running 2 services will not cause a problem. The actual problem in my case was caused by the bindings not being quite identical, once they were, it ran fine.

How do I get the SOAP headers as XML?

How can I get the SOAP header of my web service function as xml?
I need an XML version of my working SOAP header to use as an example for someone with broken SOAP headers. He's using a different programming language, but since the headers are sent in XML, we're hoping we can compare those easily. I'm using C# and ToString() just gives me the name of the object. After googling, I tried Fiddler, but that didn't catch anything, and SOAP Extensions look way too complicated for what seems like a really simple task.
There is no easy way to do this with ASMX web services. If you were using WCF, it would be a trivial matter of turning on message logging.
Fiddler should catch everything, and it's well worth learning how to use. Be sure to look in the online documentation to learn how to capture traffic from localhost to localhost.
The accepted answer to this question mentions that you can capture traffic to a web service using soapUI. You can use it to act as a proxy or HTTP tunnel in order to capture messages sent to your web service. I think using it in HTTP Tunnel mode makes sense, because then you won't have to do anything with your client other than to point the URL to soapUI instead of your actual service.
The soapUI website talks about the SOAP Monitor feature, though I don't think it offers a good explanation for setting up the HTTP tunnel.
Here are the steps involved (based on soapUI 3.0.1):
Open Soap UI
create a New soapUI Project...
2.1 Give your project a name
2.2 Enter the path to your service's WSDL (http://localhost/.../YourService.asmx?WSDL)
Right-click on the project you just created
Select "Launch SOAP Monitor"
Choose "HTTP Tunnel"
Specify an unused port number for "Port". The default will probably work.
Enter the URL to your web service in "Set endpoint for HTTP Tunnel"
If you are using SSL, then you may need to fill in some of the other fields; otherwise, click OK
The HTTP tunnel is running, so now just reconfigure a client to use the HTTP tunnel instead of the actual web service. So if your actual service is "http://localhost:1234/YourService.asmx", then reconfigure your client to use "http://localhost:{Port}/YourService.asmx" where {Port} is the number you entered in step #6.
Now just run your client normally. You'll see the traffic logged in the soapUI interface. Select a message and click on the "Message Content" button at the bottom of the window to view the actual SOAP message.

Is there such a thing as a SOAP proxy server or am I going to have to roll my own?

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...

Categories

Resources