Thursday, December 18, 2008

Secure Web services Through .NET

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):

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 Code uses this basic security 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);InitialCatalog=Northwind;UID=sa;PWD=";private SqlConnection conn = null;private SqlCommand comm = null;[WebMethod]public string GetTotalFreight()

{

WindowsPrincipal wp = (WindowsPrincipal)this.User;if (wp.IsInRole("WebService"))

{

try {

conn = new SqlConnection(sConn);conn.Open();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) {conn.Close();

}

}

} else { return "Security error"; }

}

}

}


No comments: