Enterprise Software

Easily secure custom Web services with .NET

Tony Patton demonstrate the simple process of securing a custom Web service by utilizing Windows security.

In a recent installment, I walked you through the creation of a basic Web service that provides query access to a SQL Server database using both C# and VB.NET. Another aspect to consider when creating a Web service is security. Publishing a Web service via the Internet makes it available to an infinite number of users. The data might be sensitive, so you must control who may access it.

ASP.NET-based security

The first roadblock for a user accessing an ASP.NET application is authentication. Authenticated users are called principals.

The next step in the security process is authorization. This establishes which resources and operations the principal is allowed to access. ASP.NET supports three authentication schemes: Windows, Passport, and Forms:

  • Windows: authentication performed by Internet Information Services (IIS)
  • Passport: the Passport services that Microsoft offers
  • Forms: unauthenticated users are redirected to HTML form using HTTP redirection

Connection between ASP.NET and Web service security

Web services developed with the .NET Framework utilize the same ASP.NET security paradigm as its starting point. In addition, Web service-focused standards like WS-I and SOAP-based security may be used. For this article, I'll use a simple example of Windows-based security to limit access to our Web service.

Windows-based authentication relies on the Web server (IIS) to authenticate users. It takes advantage of the user accounts on the server, and it provides the following authentication methods:

  • Basic: The user supplies logon credentials (username/password), which are passed to the server as clear text.
  • Digest: This is the same approach as Basic, but the credentials are hashed before they're passed to the server. It requires Internet Explorer.
  • Integrated Windows: An encrypted exchange between the browser and server is used to pass user credentials. It's only supported by Internet Explorer.
  • Certificate: Client certificates are used to identify a user. The certificate is passed by the browser to the server. This requires the installation of the certificate on the client machine.
  • Anonymous: The user is not required to log in. The Web server creates a Windows access token to represent the anonymous user.

The authentication mode is designated in the Web site Properties, accessed by way of the Internet Information Services Administration screen. In addition, the web.config file must be properly set up to utilize Windows authentication in an ASP.NET application. The following sample establishes this with the first line; the second line tells the system to pass the currently logged on user's credentials to the browser (impersonate):

<authentication mode="Windows" />
<identity impersonate="true" />

The identity element enables or disables impersonation with a true value, resulting in the client operating in the security context of the user account used to log onto IIS. If this option is set to false, all code is executed under the security context of the default IIS account. These elements are contained within the web.config file's system.web element.

Securing the Web service

Adding Windows authentication to the Web service begins by accessing the necessary namespace. The System.Web.Security and System.Security.Principal namespaces are available, but you only need the latter. The base Web service class (System.Web.Services.WebService) provides the User property to access the current user. You can convert this User property easily to a WindowsPrincipal object to utilize Windows-based authentication.

The WindowsPrincipal class provides an Identity property, which returns a WindowsIndentity object. The WindowsPrincipal class also includes the IsInRole method to determine if the current user is assigned to a role. Roles, which are the equivalent of Windows server groups, determine if the Windows user is assigned to a group. The following Web services uses this basic security scheme to control access to the service.

<%@ WebService Language="C#"
Class="BuilderWebServices.BuilderWebServiceExample1" %>
using System;
using System.Data;
using System.Data.SqlClient;
using System.Web.Services;
using System.Security.Principal;
namespace BuilderWebServices {
public class BuilderWebServiceExample1: WebService {
private const string sConn = "server=(local);Initial
private SqlConnection conn = null;
private SqlCommand comm = null;
public string GetTotalFreight() {
WindowsPrincipal wp = (WindowsPrincipal)this.User;
if (wp.IsInRole("WebService")) {
try {
conn = new SqlConnection(sConn);
comm = new SqlCommand();
comm.Connection = conn;
comm.CommandText = "SELECT SUM(Freight) FROM Orders";
comm.CommandType = CommandType.Text;
if (comm.ExecuteScalar() == null) {
return "Database error";
} else {
return comm.ExecuteScalar().ToString();
} } catch (SqlException ex) {
return "Database error: " + ex.ToString();
} catch (Exception e) {
return e.ToString();
} finally {
if (conn.State == ConnectionState.Open) {
}} } else { return "Security error"; } } } }

The first line in the GetTotalFreight method determines if the user is in the WebService role before proceeding. A simple text message is returned if the user isn't in the role. If opening a Web service to all users isn't a problem, you may specify a particular user (for the system to impersonate) in the Web.config file, like this:

<identity impersonate="true" name="chester" password="tester"


This tells .NET to access resources using the specific account. This allows you to provide Web service access to all users without opening up your system to anonymous access. On the other hand, the account credentials are stored in clear text, thus introducing a security risk.

VB.NET equivalent

The following listing includes all the code for the VB.NET equivalent of the example code in this article. The main difference is the attribute before the class name declaring it as a Web service.

<%@ WebService Language="VB" Class="BuilderWebServiceExample1" %>
Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports System.Web.Services
Imports System.Security.Principal
1")> _
Public Class BuilderWebServiceExample1
Inherits WebService
Dim sConn As String = "server=(local);Initial Catalog=Northwind;UID=sa;PWD="
Dim conn As SqlConnection
Dim comm As SqlCommand
<WebMethod()> _
Public Function GetTotalFreight() As String
Dim wp As WindowsPrincipal
wp = New WindowsPrincipal(me.User)
If (wp.IsInRole("WebService")) Then
conn = New SqlConnection(sConn)
comm = New SqlCommand
comm.Connection = conn
comm.CommandText = "SELECT SUM(Freight) FROM Orders"
comm.CommandType = CommandType.Text
If (comm.ExecuteScalar() Is Nothing) Then
Return "Database error"
Return comm.ExecuteScalar()
End If
Catch ex As SqlException
Return "Database error: " + ex.ToString()
Catch ex As Exception
Return "Error: " + ex.ToString()
If (conn.State = ConnectionState.Open) Then
End If
End Try
Return "Security Error"
End If
End Function
End Class

Choose carefully

Using Windows-based security provides many administration points—IIS config files (machine.config and web.config), as well as access control list (ACL) and IIS security settings. Additionally, using a database backend (like SQL Server) or an XML file to maintain security is more scalable in the long run, but I utilized Windows security to demonstrate the simple process of securing a custom Web service.

TechRepublic's free .NET newsletter, delivered each Wednesday, contains useful tips and coding examples on topics such as Web services, ASP.NET, ADO.NET, and Visual Studio .NET. Automatically sign up today!

About Tony Patton

Tony Patton has worn many hats over his 15+ years in the IT industry while witnessing many technologies come and go. He currently focuses on .NET and Web Development while trying to grasp the many facets of supporting such technologies in a productio...

Editor's Picks