secure web service - c#

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

Related

Do I need an access token for my web api service?

I have an application for managing user data. All the business logic is encapsulated within a separate web api service, which the user management web application (among others) calls into. At the moment all web api calls are exposed (they are anonymous). However the web api sits on a separate domain and is only accessible to the applications that call into it.
Is there any benefit to adding bearer tokens and enforce authentication for each API call?
If the web api service is on a separate domain and adequately protected from the internet, then you dont need to authenticate at the service level for external security (over and above any application logins you have).
However, that is not to say that your application is not internally exposed and could be intentionally or accidentally called by malicious intent or an incorrectly configured application, for example, someone accidentally points a load test at production. For this reason I would secure it, at least with a HMAC if you dont want to implement full blown authentication.
EDITED: To add that with any public facing web real estate you should classify your data and decide the appropriate level of security to apply. In some circumstances you may not want to secure GETs of low sensitivity data. On the flip side, exposing GETs allows someone access to try denial of service attacks (by calling your API in a loop from multiple servers / a botnet). When it comes to POSTs, the risk is higher, since consumers will be inserting in to your datastore.
It's also always good to keep the OWASP Top 10 in mind when dealing with security.

N-Tier Application Authentication (RabbitMQ as Broker and C# as Business Tier) - WIF possible?

I'm currently devoloping a N-Tier Application with C# as Business Tier. It's a kind of ERP and I need authentication (email/password) for this app.
I need also permissions based on the login (create orders, delete articles)
All this informations should be stored in one database.
As UI Clients I planned to make WPF Client, ASP.Net and maybe in future iPhone/Android.
As message broker I use RabbitMQ (Clients talk to Business Layer only over AMQP. Due to the advanteges I have more than one Business Layer for round robin dispatching).
On my research for authentication in N-Tier applications I found one advise for Windows Identity Foundation. WIF is completly new for me. All the examples I found handle only ASP.Net Applications.
My question now is:
Is WIF the right thing for me or should I implement this session handling on my own?
If WIF can fit my needs, what is the best way to handle this?
Do I have to implement a custom STS and place it within a WCF Service?
As you are explicitly mentioning RabbitMq, I am suggesting ServiceStack for your service interface.
One issue with MQs in general is that they are decoupled from any meta information, such as HTTP Headers, to inject authentication. You should in contrast provide a property Session (with pre authentication) or UserName and Password in your message (where the later one is not prefered, as the credentials are passed in plain). A sample solution with the built-in SessionFeature of ServiceStack is available in their documentation.
Another nice feature of ServiceStack is that you can decorate your handlers not only with AuthenticateAttribute but also with RequiredRoleAttribute and RequiredPermissionAttribute.
Also: How do you plan to queue a message with Android? Can you expose the internal MQ to the outside, and is there a client available for eg Android? Therefore I suggest a dual endpoint over HTTP to queue messages in whatever MQ you choose to use. More information on how to integrate MQ in your HTTP service is available in the documentation.
With ServiceStack you can spin as many consumer instances you want, as there is a plain communication without all the serivce stuff available.
Trivia: As I am authoring an upcoming book on Mastering ServiceStack I am a little bit biased. Nevertheless I do cover most of your questions in the book, and provide code examples: Bits and pieces to your scenario are already covered here (do not get frightened by specific MQ, they are interchangeable).

Protect sensitive data with REST Web Api

I am planning to work on an Asp.Net/C# RESTful Web Api 2 project. One of REST actions is receiving "username" and "password" with GET method. The value of "password" passed in query string is needed to be protected from REST client programmers/consumers. The "password" passed in query string (please see a sample REST call below) is sensitive data entered from any non-technical user who is not REST client programmer but who is using REST client programmers' software applications.
REST client programmers are RESTful web service consumers who write software applications in any device platform and any programming language (Java, C++, or Object-C, C, PHP, etc.).
I am supposed to use HTTPS protocol (not HTTP) to host my Asp.Net Rest Web Api services. And one sample GET call to get "password" from client/consuming programmers looks like:
https://www.mycompanyhost.com/account?username=abc&password=some_password
My questions:
1/ Is using https protocol secured enough for my Web Api services side receiving sensitive data and for the consumer/client side sending sensitive data?
2/ if https protocol is not secured enough, then how do I as web service provider and service consumers/programmers to protect sensitive data like "password" as I mentioned?
For me, the follows sound complex:
If Rest web service consumers use some encrypting method/algorithm, then on my Rest service provider side, how can I understand the same encrypting method/algorithm to decrypt "password"?
On my side as provider I am using C#, but web service consumers can use any programming language and device as mentioned above, how do we (both sides) understand each other with encrypting approach?
To achieve secure communication has a long history as you might guess (maybe since the day of digital communication born?). In your question, please consider https is the must-do yet minimum security standard that you can rely on.
Moreover, there are two things that you can consider.
I don't know why you have to GET password from server. Almost all web service treat password as hashed manner (written with several mathematically encryption). So it can compare only, cannot read words back.
It is only your decision which crypto algorithm you choose. There are many encryption/decryption library provider in .NET. I recommend you to buy-and-apply one of them.
Finally, I strongly recommend you a book to read "Pro ASP.NET Web Api Security" (amazon link). It will give you enough knowledge to make decision in your technical domain.

Issuing a single-session certificate for WCF... dangers/ issues?

I'm trying to design a WCF access pattern that will allow me to secure a publicly exposed service containing potentially sensitive information.
I like the idea of using certificates to encrypt and protect traffic from client to server, but I'm not a fan of pre-issuing the certificates, or having them generated by a third party that I would have to pay for... managing a revocation list seems overkill, but I don't want to compromise security.
My current idea is to implement some sort of 2-part authentication method that would return a generated-on-the-fly certificate that was good for a single day, and use that for all other WCF communications. The client would have the service's public certificate installed when the client was installed, and would encrypt the payload with the service's public certificate, and sign it with the generated client certificate (for all messages except the authentication request). It seems like the right way to do this, but I haven't seen any sort of discussion along those lines anywhere.
Is this because the method is inherently insecure, (if so, how), impractical, or slow, or not supported in the WCF framework? Or is my Google-fu weak and there's lots of articles about this?

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