I have a one question about WCF web service security.Currently, we are developing one android mobile project and using wcf web service for data transfer and manipulation.
We use basicHttpBinding and hosted the web service as Window Service.
We don't have any security mode at the moment and I am afraid of every one can consume our web service if they know the service address.
For example, we have one service method and that will return string value. Currently, I can add that service to other visual studio project and mobile project and we can consume any time.
//WCF Service Method
public string DoWork()
{
return "This is return string!";
}
//We can consume it like below from other dot net project by adding service reference.
//Actually, those are not real client.
ServiceReference1.WebServiceClient serv = new TestingPrj.ServiceReference1.WebServiceClient();
string result = serv.DoWork();
My question is how can I secure my web service for real clients? I don't want other projects and people to consume our web services.
The simplest method is to use Basic Authentication over SSL. Basic Authentication requires the client to have a username/password pair, which only your application will know. If the authentication is purely to know if your client is the right one (rather than knowing which user is connecting), then you can use a single, hard-coded username/password.
SSL should be used as well so the credentials don't travel the wire in plain-text and can potentially be sniffed.
Using ssl certificates is the most secure way.
Related
I have a WPF application that uses Client Application Services to allow authentication (username/password logon) against a related web application that uses Forms authentication and the SqlMembershipProvider/SqlProfileProvider/SqlRoleProvider. This all works and I can reliably validate a user/password combination.
The WPF application also calls a number of WCF services that are exposed by the same web application as is used for the CAS authentication. I now want to be able to pass through the authentication details (from Client Application Services) to the WCF services in order that I can identify the user that was authenticated within those services. I also need to be able to prevent the WCF services from being used if no authentication has taken place.
I have found a couple of .NET 3.5 examples where CAS authentication is used against .asmx web services, or authentication is provided against WCF Data Services which does not use ClientBase and has authentication facilities built in, but I cannot find any examples with pure WCF. Can anybody point me toward instruction that will enable this scenario? I am using .NET 4.0 for this project.
I have also found this stackoverflow question but again this is answered for .asmx web services and not for WCF.
The closest I have gotten involves the creation of an OperationContextScope and then copying the cookie header from the ClientFormsIdentity object to an HttpRequestMessageProperty and adding this to the OutgoingMessageProperties of the current OperationContext. I then call one or more methods of the service within the lifespan of the OperationContextScope. Thing is, when I then get to the WCF service, I still cannot see anything that resembles authentication in such a way as I can identify the original user. This methodology has been taken from various examples but I am obviously missing a step at the WCF end.
I think you need to switch to the Web API that Microsoft is now having people use for WCF Services. Check out Using Forms Authentication with Web API and http://aamirposwal.blogspot.com/2012/05/aspnet-web-api-custom-authorize-and.html
Found it.
In my binding, I specified allowCookies="true".
According to Wiktor Zychla, "setting the AllowCookies property on a BasicHttpBinding to true turns on the automatic cookie management" - this means that any attempt to set a cookie in code will be ignored and this is what I was doing.
I need to host a WCF service that will give its clients access to internal business systems on a public facing web server. Obviously I must secure this so that no one from the outside world even knows the service exists, let alone be able to call methods and access the data it exposes.
The overall idea is that the public facing website hosted on the same machine will call the WCF service and then the WCF service will provide it with the required data...
Public Facing Web Site <-> WCF Service <-> Business Systems / Databases
So I need to understand how to secure the service so it can only be accessed via the public facing website.
Ideas I had..
IIS filtering so that the IIS Site hosting the WCF service will only accept requests from a certain IP address.
Obscure port that will not be allowed through the public facing firewall.
Protocol such as NetTCP or NamedPipes
But what about the actual WCF security set up? As both the Public Facing Site and the service are on the same machine is Windows Authentication as option? Questions I have regarding this are...
Should the service client and the service simply use Windows Authentication?
Do I need specific user accounts as opposed to Network Service? If the website runs under network service would this then automatically authenticate to the service?
My objective is that someone in the outside world should not know of the services existance or be able to make access to it.
Thanks in advance.
Technical environment is: IIS7, .Net 4 and WCF 4.
I would suggest you create a http handler '.ashx' and use that as the endpoint for client requests.
If your using asp.net you can secure it by using simple forms authentication and retrieving username and password from the request headers to authenticate the request.
Then execute any requests to your business webservices which is also secured by your forms authentication.
Cheers
I have created and tested a WCF REST service that is protected with SSL and Windows Authentication through IIS 7. I have also created and tested a pure html/javascript web client that is hosted in IIS 7 that is protected with SSL and Windows Authentication -- same server, different "site" within IIS. The REST service is not public, but the web client is.
Without security, everything works beautifully, but now we are ready for field testing and security must be implemented.
My end goal is to have the user visit mywebclient.com and authenticate using their Active Directory accounts. Initially I thought it would be safe to leave the service calls from the client to the REST service unprotected (since the traffic from the web client to the web service would be internal), but this does not protect us from an internal attacker. Also, in the future, the REST services will be available to handhelds through native applications.
I've tried to gain as much information on this subject as possible, but every piece of Microsoft documentation contains client examples written in .NET.
How can I share the security context between these sites without converting the web client to a .NET-based application? Could this be accomplished by combining the web client and service into one IIS "site"?
Edit: If the client and service exist in the same app pool, does that mean they could share authentication information between client and server processes?
I am very new to using WCF services. Right now I have a WCF service that I call using jQuery. I'm concerned about users making unauthorized calls to the service. What would be the best way to secure my service?
If this is a browser app and you're worried about security, presumably you already have some sort of authentication mechanism (cookies, sessions, something). All these are accessible from WCF services (I'm assuming you're using webHttpBinding or basicHttpBinding?) via the WebOperationContext.Current.IncomingRequest property. You can check/validate a cookie (or whatever else) from your service code, or write a cross-cutting MessageInspector to apply the check to all methods on your service behavior. WCF services also can be integrated with traditional ASP.NET authentication (forms, etc) if you host the service with the compatibility flag. The browser app logs in normally, and your service can consume the credential/token/whatever.
you can use a certificate to sign the WCF messages (it's all in the WCF Settings) on both sides (client and server)
Here is some detailed explanation:
Message Security
I have a Windows Service that is self hosting a Wcf service, this Wcf service has a tcpBinding with default settings. The Windows service is running as LocalSystem.
The Wcf Service is referenced (default settings) by a Web application that is running in IIS 7.5 integrated pipeline within it's own application pool with its own identity.
Both are running on the same machine.
All is working fine, except that when in the Wcf Service when I check the identity of the current thread with:
Thread.CurrentPrincipal.Identity.Name
It returns the user of the Application Pool of the Web Application.. this is not what I expect. It looks like some sort of impersonation is going on in the Wcf service.
Is this standard behavior? I can't find any documentation on this.
And does it mean that when I try to access a database in the Wcf service i'm introducing a identity hop?
Edit, the config on service side:
Type serviceType = typeof(WcfService);
host = new ServiceHost(serviceType);
Binding tcpBinding = new NetTcpBinding( );
Uri tcpBaseAddress = new Uri("net.tcp://localhost:8001/Test");
host.AddServiceEndpoint(typeof (WcfService), tcpBinding, tcpBaseAddress);
host.Open();
On the client side:
NetTcpBinding tcpBinding = new NetTcpBinding(SecurityMode.Transport);
windowsService = new WindowsService.WcfServiceClient(tcpBinding, new EndpointAddress("net.tcp://localhost:8001/Test"));
I'm reading from Learning WCF by Michele Bustamante. I have used WCF for an application that I've refactored and we're interested in using WCF in new applications for the flexibility it offers. One of the downsides of WCF is that it can be tricky to use the .net attributes or .config files to get the settings just right. I have spent days tracking down issues with the WCF settings. I've even created automated tests that will check that my service runs the way it's supposed to.
In response to your question, Michele says very specifically in Chapter Seven that NetTcpBinding is secure by default, meaning that callers must provide Windows credentials for authentication. I believe that would explain why the thread appears to be running as the identity of the web service. This is to protect your service from being called by an unauthorized user.
I believe that the following quotation from pp. 419-420 will answer your question concisely. "If you are familiar with traditional .NET role-based security, you know that there is a security principal attached to each executing thread. That security principal holds the caller's identity, which may be tied to a Windows account or a custom database credential, and its roles."
That seems to state plainly that yes, this is standard behavior.
I believe that you can change the behavior through attributes and .config files. I recommend you get a good book on the subject. I spun my wheels in the sand a long time trying to get bits and pieces of information about WCF from the web.
To clearify:
I was checking the wrong property here. Because code would be executed under the WindowsIdentity.GetCurrent() identity.
By default this is NOT the same as the caller (which is in Thread.CurrentPrincipal.Identity). If you want this behaviour you can control this with:
host.Authorization.ImpersonateCallerForAllOperations = true;
and
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
We actually have integrated security set at the website, and then any calls from the website to the WCF service we wrap in:
using (((WindowsIdentity)HttpContext.Current.User.Identity).Impersonate())
{
That makes sure the credentials of the logged in user are passed through, rather than the IIS app pool credentials.
Works like magic!
More information is needed, but I'm guessing that it's somewhere in the configuration for the binding on either the server side or the client side that impersonation is enabled. When adding service references, svcutil.exe is VERY aggressive in setting EVERY possible binding property in configuration.
If you could provide more information for the configuration on the server and client side, it would be appreciated.