views:

45

answers:

3

I have a WCF service which needs to be called from client side(ajax call). I want to use ScriptManager on ASPX page to add a ServiceReference to the WCF service (or) JQuery ajax call to the WCF service. I want to deny anonymous users accessing the WCF service. Is there any way to do user authentication before calling a service method from JavaScript? how to secure my WCF service calls from client side?

A: 

There are a number of things you can do to secure your WCF services. Probably the easiest way is if your services are already part of the existing overall ASP.NET application is to enable ASP.NET Compatibility Mode for your services. If your ASP.NET app uses authentication to validate users (e.g. forms authentication) and you are enabling that via a session cookie, then ASP.NET Compatibility Mode does most of that work for you.

By default, this is disabled, but you can enable it with an addition to your web.config:

<system.serviceModel>
        ...
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
        ...
</system.serviceModel>

This will enable compatibility mode for all your services in your application. You can also enable this on a service by service basis by setting the web.config value and also using the AspNetCompatibilityRequirements attribute on your service class not the interface):

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class FooService: IFooService {
}

When you enable this setting, you have access to HttpContext.Current (like an ASP.NET page) and it will also enforce that a user must be authenticated before accessing the .svc file (just like you have to be authenticated before accessing any .aspx file). If you try to access a .svc file without being authenticated, and you're using forms authentication, the caller will be redirected to the default login page and, after successful authentication, will be redirected to the .svc file.

This suggestion makes a few assumptions:

  • your services are in an ASP.NET application;
  • you're using some type of ASP.NET authentication (like forms authentication) to validate users' credentials and persist a validation ticket in a cookie;

This suggestion, while maybe not the most secure or robust, is probably the simplest to at least get up and running and secure your site to a reasonable degree.

Here's a good MSDN library intro article on ASP.NET compatibility mode.

If this works, perhaps the next step is to look into something like HMAC authentication (which involves a bit more work and the coordination of secret keys - but it's definitely more secure IMHO). Here's a nice walk-through of implementing it - http://blogs.microsoft.co.il/blogs/itai/archive/2009/02/22/how-to-implement-hmac-authentication-on-a-restful-wcf-service.aspx

I hope this helps. Good luck!!

David Hoerster
you mentioned good point about aspNetCompatibility but my wcf service is separte project not in asp.net website application.i am not using the forms authentication. i am validating the user at database level. but having session to pass credentials. role and page level access also in database.
lourdhu
You don't have to have the service in the web site project. I use asp.net compatibility on a few services in a project and my services are in a separate DLL that's referenced by the web project.
David Hoerster
A: 

for WCF web http service The only way to secure a Web endpoint is to expose it through HTTPS, using transport security. When using message-based security, security information is usually placed in SOAP headers and because the messages sent to non-SOAP endpoints contain no SOAP envelope, there is nowhere to place the security information and you must rely on transport security.

lourdhu
+1  A: 

I'm not sure if this will help but I placed a layer between my WCF and webapp. I'd make an AJAX servicereference call to a local asmx. This came under the protection of the forms authentication ticket. The asmx would then do any further security checks (if that specific user making the call was allowed to request that data or shape the data based on the user) and then forward the call on to my WCF service.

This way my service layer did not need to know about the users for each app accessing it and only had a concern for delivery of requested data.

The asmx webservice took the responsibility of security.

Then I made the WCF hosted in IIS using WAS and only allowed Windows Auth access for the identity that the webapp app pool was running as.

So:

ASPX -> ASMX WebService -> WCF

I think that would give you the control/separation and security you are asking for?

MattC