Published: 30 Apr 2010
By: Andrew Freemantle
Download Sample Code

In this article we show how Forms Authentication can be used to secure ASP.Net Web Services, using the built-in ASP.Net Membership Provider classes which utilize SQL Server to store usernames and passwords.

Contents [hide]

Why?

Adding a Web Service, (also called an Application Programming Interface, or API for short) to an existing web site or desktop application (of the client-server variety) is a great way to enable additional and innovative uses of the data it holds, and also extend its reach to different development platforms such as native Apple and Linux applications, or to native mobile device applications such as those on Apple's iPhone.

Figure 1: Web Services or APIs can be used to easily extend existing applications onto new platforms

Web Services or APIs can be used to easily extend existing applications onto new platforms

There are really only 2 reasons for the need to secure a Web Service or API;

  • the data it serves is sensitive in some way – it all needs to be locked away from any un-authorized access, or only certain users can view certain sets of data (such as financial data)
  • it allows users to upload data or otherwise modify something, and there's a need to know who did what, or to restrict who can do what.

The code in this article targets .Net frameworks: 2.0 – 4.0

What do we mean by Authentication?

"Authentication is a process that determines the identity of a user. After a user has been authenticated, a developer can determine if the identified user has authorisation to proceed."[1 p734]

To keep this article straightforward, we'll assume that once a user has been authenticated, they're then free to call any Web Service method. Preventing the use of specific Web Service methods, or filtering the data that Web Service methods return depending on a specific user or the users permissions (which is called Authorization) is outside of the scope of this article, and is left as an exercise for the reader (I've always wanted to say that).

Getting started

Let's start with the default Web Service project code (File > New Project > ASP.Net Web Service Application). We'll be securing the HelloWorld() method:

Listing 1: Default ASP.Net Web Service Application code

The first thing we need to do is provide a way to accept authentication credentials, and we'll do this by requiring a SOAP Header for all of our calls. We could just as easily use parameters to the Web Service methods, but the SOAP Header is the common place to put such authentication information [1 p1317].

Here we're adding the SecuredSoapHeader object (9-19), creating a public instance of it in the Web Service (32), and adding the [SoapHeader] directive to the HelloWorld() method (35):

Listing 2: Adding a SoapHeader and making it required for calls to HelloWorld()

We don't want to require a username and password for every method call, so let's create a simple AuthenticateUser() method (36-59) that returns an AuthenticatedToken that can be used by clients in subsequent requests if the username and password are valid:

Requiring Usernames and Passwords every time, or issuing Tokens?

This really depends on the typical use cases of your Web Service.

Usernames and Passwords are great for Web Services or Web Service methods that aren't used so frequently, an example is the status updates on Twitter.com, as the average update is once every 74 days[2], but reading status updates (tweets) or searching is much more common and doesn't require authentication.

Tokens are great for Web Services that are more session-based where users make lots of queries or updates over a short period of time, or for Web Services that have extended user authentication (like asking for more than just a Username and Password) that you don't want the user to have to fill out every time. An example would be an e-commerce Web Service that holds some form of payment details.

Finally, there's the question of session state. If you require the username and password every time then the Web Service remains state-less and the client becomes almost state-less (the client application will probably ask the user once for their credentials and use them repeatedly), but the Web Service has to authenticate every call. However, If the Web Service issues a Token then it simplifies the Web Service authentication logic, makes the Web Service a little more secure (as we're not passing Usernames Passwords around as often), but means the Web Service and the client have to remember the Token.

Note

Regardless of your decision to require usernames and passwords or issue tokens, if your Web Service is going to be available on a public network such as the internet, you should take the additional step of using Secure Socket Layer (SSL / HTTPS).

Listing 3: Adding the AuthenticateUser() method, which returns a token

We've also added some basic checking to make sure the Soap Header is valid (38-41), and added the private IsUserValid() method (62), where the actual authentication will happen.

But before we start looking at authentication and the IsUserValid() implementation, there's one thing left to do - secure the HelloWorld() method:

Listing 4: Securing the HelloWorld() method

We've done that by adding an overloaded IsUserValid() method (69-79) that accepts the SecuredSoapHeader object, it's then a single line to call this IsUserValid() at the beginning of HelloWorld() (86) to secure its contents.

Here are the results of some simple tests of the Secured Web Service so far:

Figure 2: Testing the Secured Web Service – anyone can get a AuthenticatedToken

Testing the Secured Web Service – anyone can get a AuthenticatedToken

As we can see, any old username and password receives an AuthenticatedToken, which is obviously wrong, so let's look at the different authentication methods to prevent "foo" from getting access to HelloWorld()..

SQL Membership Provider Authentication

By default, ASP.Net 3.5 uses the built-in SQLMembershipProvider for storing details about registered users.

If you're adding or securing a Web Service as part of an existing ASP.Net website that uses the built-in SQL Membership login and user management web controls, you can skip the 'Setting it up' part as you will already have the necessary bits set up and working.

The only caveat if you are adding a Web Service to an existing ASP.Net website that already uses Forms Authentication, is that you will need to allow un-authenticated users to access the Web Service (otherwise they'll be redirected to your login form). The Web Service Methods will handle the authentication - just add the following to the web.config, then skip to the 'Using the SQL Membership Provider' section:

Setting it up

The first thing we need to do is enable Forms Authentication in the web.config:

Next, we need a database that has the necessary ASP.Net Membership tables, views and stored procedures. If you already have one, you just need to add the connection string to it in the web.config and you're set.

If you don't have one, you're not sure, or you want to play about with it a bit first, here's a quick way to get one created for you (and create a user account to work with):

  1. Add a new WebForm to the SecuredWebService project, and open it (we'll delete it in a second..)
  2. From the Toolbox, drag the CreateUserWizard control onto the new WebForm, between the <form> tags
  3. Build and run the project – it should launch at the new WebForm page
  4. Complete the form and hit 'Create User' – you should get a success message
  5. Delete the WebForm from the project

Figure 3: Using the Create User Wizard to create a user and the SQL Server Membership Database file (ASPNETDB.MDF)

Using the Create User Wizard to create a user and the SQL Server Membership Database file (ASPNETDB.MDF)

If you now expand the App_Data folder, you will find ASPNETDB.MDF (you may need to hit the 'show all files' button to see it):

Figure 4: ASPNETDB.MDF created for us

ASPNETDB.MDF created for us

Using the SQL Membership Provider

Back to the SecuredWebService code, and there's just one line to change in the IsUserValid() method (65):

Note

Note that we're only using the Membership.ValidateUser() method, which does the Username and Password verification for us – it doesn't remember these credentials, it just tells us if they're valid or not.

And a re-run of our tests show that we're now secured:

Figure 5: Secured Web Service using the SQL Membership Provider

Secured Web Service using the SQL Membership Provider

Taking it further

Returning simple strings is great for illustration purposes, but it doesn't make the Web Service very easy to use from a client point of view. A more structured and consistent response across all of the Web Service methods would be to return XML. Here are a couple of examples that with very little work could be returned from our sample code:

An error message might look like this:

And a successful response might look like this:

Summary

We've discussed how adding a Web Service or API to an existing web site or desktop application is a great way to extend the usefulness of application data, and how they can provide a way to extend it to native applications on different platforms.

We've then seen how easy it is to secure application data using ASP.Net Web Services and Forms Authentication with the default, built-in SQL Membership Provider, and discussed the merits of requiring usernames and passwords versus issuing authenticated tokens.

References

<<  Previous Article Continue reading and see our next or previous articles Next Article >>

About Andrew Freemantle

Andrew Freemantle has been working with Microsoft .Net since 2003, and is a Microsoft Certified Applications Developer.

View complete profile here.

Other articles in this category


Code First Approach using Entity Framework 4.1, Inversion of Control, Unity Framework, Repository and Unit of Work Patterns, and MVC3 Razor View
A detailed introduction about the code first approach using Entity Framework 4.1, Inversion of Contr...
jQuery Mobile ListView
In this article, we're going to look at what JQuery Mobile uses to represent lists, and how capable ...
Exception Handling and .Net (A practical approach)
Error Handling has always been crucial for an application in a number of ways. It may affect the exe...
JQuery Mobile Widgets Overview
An overview of widgets in jQuery Mobile.
Book Review: SignalR: Real-time Application Development
A book review of SignalR by Simone.

You might also be interested in the following related blog posts


Idle Timeouts in RIA Services Authentication read more
Health Monitoring and ASP.NET MVC read more
Exporting SWF & FLV format reports in SSRS 2005 and 2008 read more
Announcing the WebsiteSpark Program read more
Announcing the Microsoft AJAX CDN read more
Intersoft Solutions Announces WebUI Studio 2009 Service Pack 1 read more
Using SSL in your application read more
Telerik Introduces Free Web Testing Framework for ASP.NET AJAX and Silverlight read more
Silverlight 2.0 Authentication Services. read more
Patterns: What is .net RIA Services? read more
Top
 
 
 

Discussion


Subject Author Date
placeholder Intergration with Client Application Services Jacob Lindehoff 5/9/2010 5:59 AM
RE: Intergration with Client Application Services Andrew Freemantle 5/17/2010 12:16 PM
placeholder U can pass the credentials to the web Service Lawrence Zhang 5/16/2010 10:51 PM
RE: U can pass the credentials to the web Service Andrew Freemantle 5/17/2010 12:29 PM
placeholder RE: Intergration with Client Application Services Andrew Freemantle 5/17/2010 12:29 PM
RE: RE: Intergration with Client Application Services Andrew Freemantle 5/17/2010 12:31 PM
placeholder here is what i'm cooking Shane Atkin 5/18/2010 8:50 AM
RE: here is what i'm cooking Andrew Freemantle 5/22/2010 11:04 AM
placeholder RE: RE: here is what i'm cooking Shane Atkin 5/26/2010 11:59 AM
RE: here is what i'm cooking Shane Atkin 5/19/2010 4:08 AM
placeholder RE: RE: here is what i'm cooking Andrew Freemantle 5/22/2010 10:56 AM
RE: RE: RE: here is what i'm cooking Shane Atkin 5/26/2010 12:02 PM
placeholder client code Evgeny Petrov 3/24/2011 10:46 PM
RE: client code Andrew Freemantle 3/27/2011 7:52 AM
placeholder RE: RE: client code Doul 1010 8/22/2011 11:15 AM
RE: RE: RE: client code Andrew Freemantle 8/23/2011 2:18 AM
placeholder RE: RE: RE: RE: client code Doul 1010 8/23/2011 9:03 AM
RE: RE: client code Evgeny Petrov 4/28/2011 5:58 PM
placeholder returning proper erro message!! Francisco Dias 5/8/2013 8:45 AM
Securing ASP.Net Web Services with Forms Authentication Steve Stacel 5/17/2013 5:25 PM
placeholder RE: Securing ASP.Net Web Services with Forms Authentication Solly M 11/14/2013 3:44 AM
how to get this to work with jQuery AJAX Ashwin Kotwaliwale 7/17/2013 6:27 PM
placeholder Client side Rahim Rahmanpour 12/3/2013 4:51 AM

Please login to rate or to leave a comment.