I have a WCF Service setup using BasicHttpBinding, now I need to make a section where I will allow users to upload a file. This needs to be secure, so we are thinking of using SSL for transfer from website to WCF. Does anyone know if I need to create another WCF Service just for the SSL piece or can it all be in one WCF Service, part of it being BasicHTTPBinding and the other part being the SSL piece, as we don't want to use SSL for all calls, just a few related to the file upload.
Otherwise is there anothe way to approach this? Like possibly encrypt the file via some encryption method on the website side and then send it over we could try that if that's recommended, so no SSL just sending the encrypted file to WCF to store on the server.
Thank you.
Yes you need 2 WCF services with seperate contracts, but they can be hosted onn the same site.
Configure the one that you want to use SSL with a binding that has "Transport Security".
Related
First a little background:
I have already managed to connect to a Microsoft SOAP web service using C#. To use this web service, I have to supply a username and a password in the C# code. I also have to install a security certificate (in .cer format) into the "Root Certificate Authorities" section of the system's certificates. The service's address is a secure “https://” address.
(By the way, the C# class I use to connect to the service was automatically generated for me with the command line tool "svcutil.exe https://address.of.service")
Here is my question:
How can I connect to this web service using Ruby? I don't know where to even begin. I don't know where my .cer file, username and password should go exactly. Any ideas?
Further information:
Using these instructions for C#, I have been able to find out exactly what XML message is sent, and what XML message is received back. These XMLs are fairly straightforward, but “https://” never appears in them, even though the address of the web service is HTTPS. I’m not sure why that is. I suppose sending and receiving messages from a service is just a separate matter from actually connecting to the service.
I can warmly recommend using Savon for dealing with SOAP in Ruby!
I assume it is HTTP Basic authentication you are dealing with, in that case it should be pretty simple. Just:
client = Savon::Client.new do
http.auth.basic "user_name", "password"
# Use a local wsdl
wsdl.document = File.expand_path("../wsdl/ebay.xml", __FILE__)
# or from internet
wsdl.document = "http://service.example.com?wsdl"
# to list SOAP actions
client.wsdl.soap_actions
end
(this is just from my head so it might be a bit off)
Read the link i posted and msg me if you can't figure it out. :)
The certificate file is used for your computer to accept the identity of the server you want to connect to. If you have installed it to your computer, I don't think you have to do anything more on that part.
EDIT
If you can't use the WSDL file you will have to build the xml by hand, this is pretty ugly, but possible if the is no other way. Nokogiri can be used to construct a xml document, then you can simply POST the xml document to the correct url. I have good experiences using httpi-ntlm to deal with authentication.
What you're talking about here is transport security, rather than message security. The certificate you installed on the Windows server is what is being used to encrypt the SSL connection. What you would need to do with Ruby is ensure that when the connection is made that the client certificate corresponding to the certificate you installed is used to encrypt the SSL connection you use.
This is half server management (SSL cert installation) and half code (making sure you use the proper certificate).
I'm no Ruby expert, but I think you'd need something like this to utilize the x509 certificate in your connection. WCF makes use of a configuration file to do the same thing, while traditional ASMX services use code to do it.
I've got an WP7 application who does authentication with Azure Access Control Service and stores it's SimpleWebToken in an the IsolatedStorage. I want to use this SWT-token to secure my (locally deployed not in AZURE)WCF Service. (The WCF service is finished, except the ACS token validation part) So I've added an Service Reference in my WP7 application and now I want to send the SWT-token to WCF Service via the generated WCF proxy client, but how? Or is this not the way to do it?
Because custom binding & wsHttpBinding isn't supported on WP7(Not sure if mango fixes this) and I don't want to use a WCFDataService. I've come with an nasty solution, I will add a string(the simplewebtoken) to my operationcontract and send it with every client call. I validate this token in the serviceimplentation with the configured securityTokenHandler. This currently works for me!
I'm building a complex, public web service in WCF that send email to a specific address, similar to a contact form but with some features.
With jQuery I get the data from the textbox and with Ajax and json I send to the web service the strings to proceed at the send.
Now, is there a good way to make it secure?
I mean.. the service is public so someone can have access to it and starting to spam on this address. Can I restrict the users to use the web service only from the correct web site?
Thanks.
IF the WCF service is hosted in the IIS you can allow calls only from a specific IP address, look at the directory security settings under IIS.
By far the simplest way is to have your web service require some type of access key in order to run the operation.
Something simple like a base64 encoded GUID would work. It doesn't even have to change. Just add a parameter called "AccessKey" or something similar. Have your app pass that and let the service validate that it is good.
Another idea is to have the web service check the http headers to see if it came from the page you authorized to use it.
Neither of those are perfect. The first one means that your "key" will be inside the html you send to the client. The second one can be spoofed.
Personally, I'd probably not bother at this level and just log what the service is doing. If the traffic counts to the service start to exceed what you think it ought to be, then I'd investigate ways to mitigate it. Most likely, given that it's a service you won't see any issues.
I am going to be creating a web service that will be passing confidential information across the network.
What would be the best way to secure the web service?
how do I know if the application requesting the information is who it says it is, and it's not another application that is using another's user name and password?
Use WCF for your web service! It has tons of security capabilities:
You can
secure your clients via Certificates - only those that have the appropriate certificate will be allowed to get their calls processed
secure your clients by looking them up in your internal Active Directory domain - only those with AD accounts will be allowed to get their requests processed
secure your clients with custom username/passwords which you can look up against anything you want (this is the most flexible, but also the most complicated option, and offer the most potential for failure if you get something wrong)
Plus, with WCF, you also have loads of options to secure the transport between client and service, or encrypt and sign the messages going back and forth.
See the WCF Developer Center as a great starting point for all things WCF.
If you're serious about safely and securely programming WCF services, grab a copy of the Programming WCF Services book by Juval Lowy - it's the bible for WCF.
I've done this once or twice in the past:
Use SSL
Write the webservice to require a token which is retrieved from a method on the webservice.
Have the token returned from a method which requires a login and password.
After a certain number of webservice requests, or at random intervals, change the token required, thus forcing a re-authentication.
If you want to, encrypt the data in the ssl stream, by using an encryption method which both parties understand. (if you're paranoid.)
You don't write which implementation technology you intent to use, so let me start by recommending that you use Windows Communication Foundation (WCF) instead of asmx web services.
With WCF you can select between many different bindings, many of which offer data protection. Overall, there are two different styles of data protection for web services:
Transport protection, where the transport mechanism itself offers protection in form of encryption. The best known version of this is HTTPS/SSL. However, note that unless you employ client certificates, the service has no guarantee that the client is what it says it is.
Message protection, where the message itself is encrypted and signed. Such messages can travel over otherwise unprotected networks and still be protected.
The WsHttpBinding offers message protection according to open standards. That's where I would start.
Have a look at WIF (aka Geneva framework). Its purpose is to solve the exact problem you describe.
http://msdn.microsoft.com/en-us/security/aa570351.aspx
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...