Securing Silverlight Applications
- About software security principles
- Security principles that apply to Silverlight
- To authenticate a user in a Silverlight application
This lesson will introduce software security principles and illustrate a practical example of authenticating a user in a Silverlight application.
Software Security Basics
Data is pretty much at the heart of all business software. Data pertaining to identification is a foundation of ecommerce. In ecommerce and business today, a business must be able to trust data related to a user and the user's identity. As such, identity theft is growing to be one of the top crimes perpetrated. With that said, the need to protect data managed by software is of prime importance and should be considered in the conceptual and logical software design phases. In fact, a formal security plan should be compiled that includes a plan for determining a user's identity, what tasks a user is allowed to perform in an application, and how data is to be secured while being transported and stored.
When discussing software security, all applications typically perform the two "A" words, authentication and authorization. Authentication is the process of determining a user's identity. A user's identity is generally determined by using user credentials such as a username and a password. Once a user's identity is determined, an application must determine what a user has permission to perform. Authorization is the process of determining a user's permissions within an application.
The method used to secure data that is being transported and stored varies based on the type of application being created. For instance, a Windows application that is not exposed to the Web can rely on internal network security to protect data whereas a Web application must take many precautions to guard against malicious attacks.
In a Web application environment, data is transported from a client's computer, over the Web, to a Web server. A client computer that accesses a Web application may be comprised of any operating system and any Web browser, thus it is nearly impossible to impose strict security mechanisms on the client's computer in a traditional Web application. Data entered on a client's computer is generally already known to the user that is entering it, hence, securing data while it is on the client's computer really isn't a significant concern. However, once data leaves a client's computer and is transported over the Web to the Web server, it can be intercepted by anyone using an HTTP packet sniffer or other similar mechanism.
In order to secure data while it is transported over the Web, the data is encrypted before it leaves the client machine and unencrypted when it reaches the Web server and visa versa. There are many methods used in the software industry to encrypt data, however, the standard used on the Web for ecommerce is called Secure Sockets Layer (SSL) and utilizes 128-bit encryption. SSL is implemented through certificates that can be obtained from a third party certificate authority (CA) such as Verisign.
Developers generally take additional steps to secure user credentials. If valid user credentials fall into the wrong hands, a malicious user can gain access to all of the data in an application that is granted to the acquired credentials and do so undetected. A primary additional step taken to protect user credentials is to not store the user's password with the authentication information.
Once a user is authenticated, minimal information is normally stored in memory about the user for the duration of the user's session. Silverlight includes interfaces that can be implemented by a class to ensure that the class complies with the security functionality included in other aspects of the .NET Framework, such as ASP.NET. The IIdentity and IPrincipal interfaces are located in the System.Security.Principal namespace. The IIdentity interface is implemented by a class that describes information about the user such as the user's name. The IPrincipal interface is implemented by a class that describes a user's identity as well as a list of roles that the user is a member of. The code listing below shows a class that implements the IIdentity interface.
using System;
using System.Security.Principal;
namespace AthleteManager
{
public class AuthenticationTicket : IIdentity
{
// data members.
public string AuthenticationType { get; set; }
public bool IsAuthenticated { get; set; }
public string Name { get; set; }
}
}
Transporting Sensitive Data
All data transported back and forth between a Web server and a client must reside inside some type of data packet. Ultimately, all communications reside within HTTP packets. An HTTP packet includes a payload, or secondary container construct (such as an HTML document). The most common methods used to transport data consumed by a Silverlight application are SOAP, REST, POX, and JSON. Regardless of the data transportation method used, bear in mind that all communication between a Silverlight application and a Web server occur using a Web service on the server.
Service Oriented Architecture (SOA) Security
A Web service is a class that is available over the Web. A Web service contains methods that are exposed over the Web to be called by any type of client application. In many scenarios, a Web method will provide access to a server database so that a client application can retrieve data. With that in mind, standards had to be put into place so that calls made to Web methods could be authenticated prior to execution; in essence, securing the Web service.
Web service standards, just as all other Web standards, are constantly evolving to keep up with technological advances. Maintaining a secure environment over the Web is not an easy task. To add to the complexity, bear in mind that the Web is a stateless environment. Communications between Web clients and Web methods are handled in the same manner as communications between Web clients and Web sites. Each request is isolated from all other requests. A method of maintaining state between requests to a Web method is necessary so that a client does not have to be authenticated with each request.
In the simplest example, user credentials can be passed to a Web method with each request so that the request can be authenticated. However, formal standards have been created for authenticating user requests to Web methods. In a nutshell, the default mechanism used to transport data to and from a Web method, SOAP, is constructed very similar to an HTML document. The SOAP document is referred to an envelope and it includes a head section and a body section. The head section is optional but can be used to transport additional information and parameters that are intended to be utilized by the processing engine. When information is transported in the SOAP header, the SOAP message is said to contain a "custom SOAP header". User credentials are one example of information that can be passed in a custom SOAP header. (see footnote)
Representational State Transfer (REST) Security
RESTful messages are transported by using HTTP just as SOAP messages and other Web data. However, RESTful messages are more succinct and carry data directly in the HTTP header. Hence RESTful messages also carry authentication credentials directly in the message and are validated at the server.
Silverlight Security
Silverlight applications execute entirely on the client machine with occasional calls being made to a service that resides on a Web server. With that in mind, you may want to authenticate a user to use a Silverlight application simply as a feature of the application and to protect data displayed. For instance, you may create a Silverlight application that allows a user to manage their finances. An application of this type would, obviously, benefit from user authentication.
Additionally, a Silverlight application may make calls to a service residing on a Web server in order to retrieve data on the server. At this point, the service that resides on the server should be secured as to authenticate users making calls to the service.
Aside from making remote calls to a Web method, all Silverlight code executes within a secure environment that is isolated from the host operating system somewhat. This environment is referred to as the "sandbox". The Silverlight version of the .NET Framework is powerful but due to the security constraints placed on code executing in the Silverlight sandbox, tasks that can be performed by using the Silverlight version of the .NET Framework are limited in comparison to the full .NET Framework.
Silverlight Enterprise Security Features
Silverlight executes in an isolated environment on the client machine, hence Silverlight does not include code access security (CAS) features or enterprise-level security features.
Cryptography
Silverlight includes a System.Security.Cryptography namespace that includes cryptography classes for encryption and hashing.
Encryption is a bidirectional process. When data is encrypted, it is intended to be decrypted. Data is encrypted by using an encryption key. There are many encryption standards available and varying strengths of encryption keys. Some of the encryption standards that have been used throughout history are known to be cracked but the .NET Framework and Silverlight utilize modern encryption standards that have been proven as secure when used to encrypt data for transport over the Web.
Hashing is a unidirectional process. When data is hashed, it cannot be "un-hashed". In fact, there is no such thing as "un-hashing" or "de-hashing". Hashing is useful for obscuring data values when the original value is not as important as is the ability to ensure that a consistent seed value is supplied. When hashing, if the same hashing algorithm is used, a consistent seed value will always generate a consistent resulting hashed value. Hashing is a perfect fit for obscuring passwords supplied by a user for authentication. When a user supplies a password, it can be hashed prior to transporting it over the Web. If the password hash falls into malicious hands, the original seed password value can never be arrived at, hence the password hash is not of value to a malicious user.
Silverlight 2 beta 2 includes the SHA1 hashing algorithm which is the accepted and most commonly used hashing standard on the Web.
To further prevent a malicious user from using a password hash to perform injection attacks and spoofing an application, the entire data communication between a Silverlight application and a server should be encrypted using SSL if the data communication contains user credentials or sensitive data.
ASP.NET Membership Providers
A common way of securing a Silverlight application is to use the same authentication mechanisms available under ASP.NET. The accepted way to perform authentication in ASP.NET is to use Forms Authentication and set an Authorization Cookie in the browser. Cookies are sent from the browser with each request, so the web server can check for the authorization cookie and grant privileges based on its value. Since a Silverlight client executes within the context of a browser, we can use this existing browser-based authentication under the ASP.NET Membership Provider. The Membership Provider gives developers a pre-built library of classes that allow for creating and managing user accounts, passwords and groups, among other security-related information. There are many different provider types available, which allow you to use different databases to store your security information. Perhaps the most common (and also the default) Membership Provider is the SQL Membership Provider, which allows you to use a SQL Server database to store security information.
The SQL Membership Provider stores Membership information such as usernames, passwords, and profile information in a group of tables inside a SQL Server database. By default, this database is created inside the "App_Data" directory of your ASP.NET project, but you can also specify a different SQL Server database using a special utility called aspnet_regsql. Complete details of the SQL Membership Provider are beyond the scope of this course, but we will look at how to do basic setup and authentication using Silverlight against this provider.
Here are the basic steps to configure and authenticate against a SQL Membership Provider using Silverlight: (NOTE that the lab at the end of this section will explore these steps in detail)
- Create a Silverlight application, being sure to add a new ASP.NET Web Project to the solution by accepting the default project options.
- Create the SQL Membership Provider tables inside a SQL Server database, using the ASP.NET Web Site Administration Tool (accessible via the Project/ASP.NET Configuration menu option inside Visual Studio), or using the aspnet_regiis utility (available in the c:\windows\microsoft.net\framework folder).
- Create user accounts (username and password) in your Membership tables. You can do this using the ASP.NET Web Site Administration Tool, or the Membership API classes.
- Create a Web Service (asmx or wcf) containing an Authenticate method which uses the Membership.ValidateUser call to check for valid credentials, and uses the FormsAuthentication.SetAuthCookie method to enable the authorization cookie for the browser session. You can also set Session values to create a security context, such as Username, etc.
- For each secured Web Service method, use the Membership API to determine if the authenticated user has appropriate privileges to execute the method.
Exercise: Using the SQL Membership Provider for Authentication
In this exercise, you will use the SQL Membership Provider to add authentication to the Login dialog we created in a previous module.
- Open the "AthleteManager" solution you created in the "Silverlight Controls" Lab. Alternatively, you can open the completed solution located at \ClassFiles\SilverlightControls\Solutions\AthleteManagerControls.
- Select Project/ASP.NET Configuration from the Visual Studio menu (If this option is not present, be sure to highlight any file in the ASP.NET Web project in the solution.
- After a slight pause, you will see a web page appear with the ASP.NET Web Site Administration Tool.
- Select the "Security" hyperlink.
- On the Security tab, select the "Select Authentication Type" then select "From the internet" on the next page. This enables Forms Authentication for your website so you can create your own user accounts.
- In the Users section, select "Create User." Enter "admin" for User Name, and "admin!!!" for password, then enter other details and click Create User.
- Note that we will be using an ASMX web service instead of a WCF Web Service for this lab. This is because using Session state from WCF under Silverlight 2 is more complex than ASMX, due to the fact that Silverlight does not yet support wsHttpBinding.
- In the AthleteManager_Web project, delete the AthleteService.svc and AthleteService.cs files.
- Select Website/Add New Item from the main menu. Select Web Service and name the file AthleteService.asmx
- At the top of the AthleteService.cs file, add the following using clause to import the ASP.NET security namespace:
using System.Web.Security;
- Remove the HelloWorld() default method from the web service, and in its place add the following methods:
[WebMethod(EnableSession=true)] public bool AuthenticateUser(string username, string password) { bool valid = Membership.ValidateUser(username, password); if (valid) { FormsAuthentication.SetAuthCookie(username, false); Session["username"] = username; } else Session["username"] = null; return valid; } [WebMethod(EnableSession = true)] public string HelloWorld() { if (!IsLoggedIn()) throw new Exception("User is not logged in!!!"); else return "Hello World!"; } private bool IsLoggedIn() { if (Session["username"] != null) return true; else return false; } - In the Silverlight project, expand the Service References node in Solution Explorer and delete the AthleteService service reference.
- Right-click the Service References folder and select "Add Service Reference." In the Add Service Reference dialog, click the Discover button and select the AthleteManager_Web/AthleteService.asmx file. Enter AthleteService in the Namespace field and select OK.
- Inside Page.xaml.cs, at the top of the file where the svc variable is declared, replace the line with the following declaration:
AthleteManager.AthleteService.AthleteServiceSoapClient svc = new AthleteManager.AthleteService.AthleteServiceSoapClient(); - Run the project by hitting F5 and test that the login works (with the username/password you created above).
- We can now test authentication on individual methods. Note that the HelloWorld method checks to see if the user has previously been authenticated. We can test this method by adding a call to HelloWorld just after logging in. Add the following code to the end of the svc_AuthenticateUserCompleted event:
svc.HelloWorldCompleted += new EventHandler<AthleteManager.AthleteService.HelloWorldCompletedEventArgs>(svc_HelloWorldCompleted); svc.HelloWorldAsync(); - Add a callback handler for the HelloWorld call
void svc_HelloWorldCompleted(object sender, AthleteManager.AthleteService.HelloWorldCompletedEventArgs e) { MessageBox.Show("HelloWorld call successful!"); } - Test the application with both a valid username and password. Note that an exception is raised when trying to call HelloWorld with an invalid user account and password.
Securing Silverlight Applications Conclusion
In this lesson of the Silverlight tutorial, you
- Reviewed software security principles
- Authenticated a user in a Silverlight application
Footnotes
-
To learn more about using Web Services with the .NET Framework, visit the MSDN reference located at http://msdn2.microsoft.com/en-us/library/bb931714.aspx.