Thursday, December 12, 2013

MVVM vs MVP vs MVC: The differences explained


MVVM vs MVP vs MVC: The differences explained

May 6, 2011 by     18 Comments    Posted under: Linked In, Software Development
For the consicise explanation, see MVVM vs MVP vs MVC: The concise explanation

Those who know me know that I have a passion for software architecture and after developing projects using Model-View-ViewModel (MVVM), Model-View-Presenter (MVP), and Model-View-Controller (MVC),  I finally feel qualified to talk about the differences between these architectures.  The goal of this article is to clearly explain the differences between these 3 architectures.

Common Elements

First, the let’s define common elements.  All 3 of the architectures are designed to separate the view from the model.

Model

  • Domain entities & functionality
  • Knows only about itself and not about views, controllers, etc.
  • For some projects, it is simply a database and a simple DAO
  • For some projects, it could be a database/file system, a set of entities, and a number of classes/libraries that provide additional logic to the entities (such as performing calculations, managing state, etc)
Implementation: Create classes that describe your domain and handle functionality.  You probably should end up with a set of  domain objects and a set of classes that manipulate those objects.

View

  • Code that handles the display
  • Note that view related code in the codebehind is allowed (see final notes at the bottom for details)
Implementation:  HTML, WPF, WindowsForms, views created programmatically – basically code that deals with display only.

Differences between Presenters, ViewModels and Controllers

This is the tricky part.  Some things that Controllers, Presenters, and ViewModels have in common are:
  • Thin layers
  • They communicate with the model and the view
The features of each.

Presenter (Example: WinForms)

  • 2 way communication with the view
  • View Communication: The view communicates with the presenter by directly calling functions on an instance of the presenter.  The presenter communicates with the view by talking to an interface implemented by the view.
  • There is a single presenter for each view
Implementation:
  • Every view’s codebehind implements some sort of IView interface.  This interface has functions like displayErrorMessage(message:String), showCustomers(customers:IList<Customer>), etc.  When a function like showCustomers is called in the view, the appropriate items passed are added to the display.  The presenter corresponding to the view has a reference to this interface which is passed via the constructor.
  • In the view’s codebehind, an instance of the presenter is referenced.  It may be instantiated in the code behind or somewhere else.  Events are forwarded to the presenter  through the codebehind.  The view never passes view related code (such as controls, control event objects, etc) to the presenter.
A code example is shown below.
//the view interface that the presenter interacts with
public interface IUserView
{
    void ShowUser(User user);
    ...
}
 
//the view code behind
public partial class UserForm : Form, IUserView
{
    UserPresenter _presenter;
    public UserForm()
    {
        _presenter = new UserPresenter(this);
        InitializeComponent();
    }
 
    private void SaveUser_Click(object sender, EventArgs e)
    {
        //get user from form elements
        User user = ...;
        _presenter.SaveUser(user);
    }
 
    ...
}
 
public class UserPresenter
{
    IUserView _view;
    public UserPresenter(IUserView view){
        _view = view;
    }
 
    public void SaveUser(User user)
    {
 ...
    }
    ...
}

ViewModel (Example: WPF, Knockoutjs)

  • 2 way communication with the view
  • The ViewModel represents the view.  This means that fields in a view model usually match up more closely with the view than with the model.
  • View Communication:  There is no IView reference in the ViewModel.  Instead, the view binds directly to the ViewModel.  Because of the binding, changes in the view are automatically reflected in the ViewModel and changes in the ViewModel are automatically reflected in the view.
  • There is a single ViewModel for each view
Implementation:
  • The view’s datacontext is set to the ViewModel.  The controls in the view are bound to various members of the ViewModel.
  • Exposed ViewModel proproperties implement some sort of observable interface that can be used to automatically update the view (With WPF this is INotifyPropertyChanged; with knockoutjs this is done with the functions ko.observable() and ko.observrableCollection())

Controller (Example: ASP.NET MVC Website)

  • The controller determines which view is displayed
  • Events in the view trigger actions that the controller can use to modify the model or choose the next view.
  • There could be multiple views for each controller
  • View Communication:
    • The controller has a method that determines which view gets displayed
    • The view sends input events to the controller via a callback or registered handler.  In the case of a website, the view sends events to the controller via a url that gets routed to the appropriate controller and controller method.
    • The view receives updates directly from the model without having to go through the controller.
      • Note: In practice, I don’t think this particular feature of MVC is employed as often today as it was in the past.  Today, I think developers are opting for MVVM (or MVP) over MVC in most situations where this feature of MVC would have been used.  Websites are a situation where I think MVC is still a very practical solution.  However, the view is always disconnected from the server model and can only receive updates with a request that gets routed through the controller.  The view is not able to receive updates directly from the model.
Implementation (for web):
  • A class is required to interpret incoming requests and direct them to the appropriate controller.  This can be done by just parsing the url.  Asp.net MVC does it for you.
  • If required, the controller updates the model based on the request.
  • If required, the controller chooses the next view based on the request.  This means the controller needs to have access to some class that can be used to display the appropriate view.  Asp.net MVC provides a function to do this that is available in all controllers.  You just need to pass the appropriate view name and data model.
MVVM and MVP implementation seem pretty straightforward but MVC can be a little confusing.  The diagram below from Microsoft’s Smart Client Factory documentation does a great job at showing MVC communication.  Note that the controller chooses the view (ASP.NET MVC) which is not shown in this diagram.  MVVM interactions will look identical to MVP (replace Presenter with ViewModel).  The difference is that with MVP, those interactions are handled programmatically while with MVVM, they will be handled automatically by the data bindings.

General rules for when to use which?

MVP
  • Use in situations where binding via a datacontext is not possible.
  • Windows Forms is a perfect example of this.  In order to separate the view from the model, a presenter is needed.  Since the view cannot directly bind to the presenter, information must be passed to it view an interface (IView).
MVVM
  • Use in situations where binding via a datacontext is possible.  Why?  The various IView interfaces for each view are removed which means less code to maintain.
  • Some examples where MVVM is possible include WPF and javascript projects using Knockout.
MVC
  • Use in situations where the connection between the view and the rest of the program is not always available (and you can’t effectively employ MVVM or MVP).
  • This clearly describes the situation where a web API is separated from the data sent to the client browsers.  Microsoft’s ASP.NET MVC is a great tool for managing such situations and provides a very clear MVC framework.

Final notes

  • Don’t get stuck on semantics.  Many times, one of your systems will not be purely MVP or MVVM or MVC.  Don’t worry about it.  Your goal is not to make an MVP, MVVM, or MVC system.  Your goal is to separate the view, the model, and the logic that governs both of them. It doesn’t matter if your view binds to your ‘Presenter’, or if you have a pure Presenter mixed in with a bunch of ViewModels.  The goal of a maintainable project is still achieved.
  • Some evangelists will say that your ViewModels (and Presenters) must not make your model entities directly available for binding to the view.   There are definitely situations where this is a bad thing.  However, don’t avoid this for the sake of avoiding it.  Otherwise, you will have to constantly be copying data between your model and ViewModel.  Usually this is a pointless waste of time that results in much more code to maintain.
  • In line with the last point, if using WPF it makes sense to implement INotifyPropertyChanged in your model entities.  Yes, this does break POCO but when considering that INotifyPropertyChanged adds a lot of functionality with very little maintenance overhead , it is an easy decision to make.
  • Don’t worry about “bending the rules” a bit so long as the main goal of a maintainable program is achieved
  • Views
    • When there is markup available for creating views (Xaml, HTML, etc), some evangelists may try to convince developers that views must be written entirely in markup with no code behind.  However, there are perfectly acceptable reasons to use the code behind in a view if it is dealing with view related logic.  In fact, it is the ideal way to keep view code out of your controllers, view models, and  presenters.  Examples of situations where you might use the code behind include:
      • Formatting a display field
      • Showing only certain details depending on state
      • Managing view animations
    • Examples of code that should not be in the view
      • Sending an entity to the database to be saved
      • Business logic

Understanding Basics of UI Design Pattern MVC, MVP and MVVM

Understanding Basics of UI Design Pattern MVC, MVP and MVVM

By , 20 Jul 2011



Introduction

This is my first article and I hope you will like it. After reading this article, you will have a good understanding about "Why we need UI design pattern for our application?" and "What are basic differences between different UI patterns (MVC, MVP, MVVP)?”.
In traditional UI development - developer used to create a View using window or usercontrol or page and then write all logical code (Event handling, initialization and data model, etc.) in code behind and hence they were basically making code as a part of view definition class itself. This approach increased the size of my view class and created a very strong dependency between my UI and data binding logic and business operations. In this situation, no two developers can work simultaneously on the same view and also one developer's changes might break the other code. So everything is in one place is always a bad idea for maintainability, extendibility and testability prospective. So if you look at the big picture, you can feel that all these problems exist because there is a very tight coupling between the following items.
  1. View (UI)
  2. Model (Data displayed in UI)
  3. Glue code (Event handling, binding, business logic)
Definition of Glue code is different in each pattern. Although view and model is used with the same definition in all patterns.
In case of MVC it is controller. In case of MVP it is presenter. In case of MVVM it is view model.
If you look at the first two characters in all the above patterns, it remain same i.e. stands for model and view. All these patterns are different but have a common objective that is “Separation of Duties"
In order to understand the entire article, I request readers to first understand the above entity. A fair idea about these will help you to understand this article. If you ever worked on UI module, you can easily relate these entities with your application.
MVC (model view controller), MVP (model view presenter) and MVVM (model view view model) patterns allow us to develop applications with loss coupling and separation of concern which in turn improve testability, maintainability and extendibility with minimum effort.
MVVM pattern is a one of the best solutions to handle such problems for WPF and Silverlight application. During this article, I will compare MVC, MVP and MVVM at the definition level.

MVP & MVC

Before we dig into MVVM, let’s start with some history: There were already many popular design patterns available to make UI development easy and fast. For example, MVP (model view presenter) pattern is one of the very popular patterns among other design patterns available in the market. MVP is a variation of MVC pattern which is being used for so many decades. Simple definition of MVP is that it contains three components: Model, View and presenter. So view is nothing but a UI which displays on the screen for user, the data it displays is the model, and the Presenter hooks the two together (View and model).
View,Model,Presenter,Model The view relies on a Presenter to populate it with model data, react to user input, and provide input validation. For example, if user clicks on save button, corresponding handling is not in code behind, it’s now in presenter. If you wanted to study it in detail, here is the MSDN link.
In the MVC, the Controller is responsible for determining which View is displayed in response to any action including when the application loads. This differs from MVP where actions route through the View to the Presenter. In MVC, every action in the View basically calls to a Controller along with an action. In web application, each action is a call to a URL and for each such call there is a controller available in the application who respond to such call. Once that Controller has completed its processing, it will return the correct View.
In case of MVP, view binds to the Model directly through data binding. In this case, it's the Presenter's job to pass off the Model to the View so that it can bind to it. The Presenter will also contain logic for gestures like pressing a button, navigation. It means while implementing this pattern, we have to write some code in code behind of view in order delegate (register) to the presenter. However, in case of MVC, a view does not directly bind to the Model. The view simply renders, and is completely stateless. In implementations of MVC, the View usually will not have any logic in the code behind. Since controller itself returns view while responding to URL action, there is no need to write any code in view code behind file.

MVC Steps

Step 1: Incoming request directed to Controller.
View,Model,Presenter,Model
Step 2: Controller processes request and forms a data Model.
View,Model,Presenter,Model
Step 3: Model is passed to View.
View,Model,Presenter,Model
Step 4: View transforms Model into appropriate output format.
View,Model,Presenter,Model
Step 5: Response is rendered.
View,Model,Presenter,Model
So now you have basic understanding of MVC and MVP. Let’s move to MVVM.

MVVM (Model View ViewModel)

The MVVM pattern includes three key parts:
  1. Model (Business rule, data access, model classes)
  2. View (User interface (XAML))
  3. ViewModel (Agent or middle man between view and model)
View,Model,ViewModel
Model and View work just like MVC and “ViewModel” is the model of the View.
  • ViewModel acts as an interface between model and View.
  • ViewModel provides data binding between View and model data.
  • ViewModel handles all UI actions by using command.
In MVVM, ViewModel does not need a reference to a view. The view binds its control value to properties on a ViewModel, which, in turn, exposes data contained in model objects. In simple words, TextBox text property is bound with name property in ViewModel.
In View:
<TextBlock Text="{Binding Name}"/> 
In ViewModel:
public string Name
        {
            get
            {
                return this.name;
            }
            set
            {
                this.name = value;
                this.OnPropertyChanged("Name");
            }
        }
ViewModel reference is set to a DataContext of View in order to set view data binding (glue between view and ViewModel model).
Code behind code of View:
public IViewModel Model
        {
            get
            {
                return this.DataContext as IViewModel;
            }
            set
            {
                this.DataContext = value;
            }
        }
If property values in the ViewModel change, those new values automatically propagate to the view via data binding and via notification. When the user performs some action in the view for example clicking on save button, a command on the ViewModel executes to perform the requested action. In this process, it’s the ViewModel which modifies model data, View never modifies it. The view classes have no idea that the model classes exist, while the ViewModel and model are unaware of the view. In fact, the model doesn’t have any idea about ViewModel and view exists.

Where to Use What in the .NET World

  • Model-View-Controller (MVC) pattern
    • ASP.NET MVC 4 Link
    • Disconnected Web Based Applications
  • Model-View-Presenter (MVP) pattern
    • Web Forms/SharePoint, Windows Forms
  • Model-View-ViewModel (MVVM) pattern
    • Silverlight, WPF Link
    • Data binding

Sources and References

Saturday, December 7, 2013

Introducing LINQ to Relational Data

Introducing LINQ to Relational Data

123 out of 162 rated this helpful Rate this topic

Microsoft Data Platform Development Technical Article
Writers: Elisa Flasko, Microsoft Corporation
Published: January 2008
Level: 100/200
Applies To:
LINQ to SQL
LINQ to Entities
ADO.NET Entity Framework
You can also download a Microsoft Word version of this article.
Summary: This article introduces two implementations of LINQ, LINQ to SQL and LINQ to Entities, and the key scenarios for which each was designed. (19 printed pages)

Introducing LINQ to Relational Data

With the combined launch of Visual Studio 2008, SQL Server 2008, and Windows Server 2008, Microsoft is introducing five implementations of .NET Language Integrated Query (LINQ).
Of these five implementations, two specifically target access to relational databases: LINQ to SQL and LINQ to Entities. This white paper introduces these two technologies and the scenarios in which each can best be used.
Microsoft Language Integrated Query (LINQ) offers developers a new way to query data using strongly-typed queries and strongly-typed results, common across a number of disparate data types including relational databases, .NET objects, and XML. By using strongly-typed queries and results, LINQ improves developer productivity with the benefits of IntelliSense and compile-time error checking. 
LINQ to SQL, released with the Visual Studio 2008, is designed to provide strongly-typed LINQ access for rapidly developed applications across the Microsoft SQL Server family of databases.
LINQ to Entities, to be released in an update to Visual Studio 2008 in the first half of 2008, is designed to provide strongly-typed LINQ access for applications requiring a more flexible Object Relational mapping, across Microsoft SQL Server and third-party databases. 

What Is LINQ to SQL?

LINQ to SQL is an object-relational mapping (ORM) framework that allows the direct 1-1 mapping of a Microsoft SQL Server database to .NET classes, and query of the resulting objects using LINQ. More specifically, LINQ to SQL has been developed to target a rapid development scenario against Microsoft SQL Server where the database closely resembles the application object model and the primary concern is increased developer productivity.
Figures 1 & 2 combined with the code snippet below demonstrate a simple LINQ to SQL scenario. Figure 1 shows the LINQ to SQL mapping, and Figure 2 shows the associated database diagram, using the Northwind database.
Figure 1. Database diagram for a subset of the Northwind database.
Figure 2. LINQ to SQL mapping diagram for a simple scenario using a subset of the Northwind database and the associated database diagram. Notice the use of an intermediary table to map the many-to-many relationship between Employees and Territories.
This code snippet shows a simple LINQ query against the Northwind database to retrieve all customers whose address is in London.
NorthwindDataContext db = new NorthwindDataContext();
var customers = from c in db.Customers
                where c.City == "London"
                select c;
Listing 1. Simple LINQ to SQL query
LINQ to SQL has been architected with simplicity and developer productivity in mind. APIs have been designed to “just work” for common application scenarios. Examples of this design include the ability to replace unfriendly database naming conventions with friendly names, to map SQL schema objects directly to classes in the application, to implicitly load data that has been requested but has not previously been loaded into memory, and the use of common naming conventions and partial methods to provide custom business or update logic.
The ability to replace unfriendly database naming conventions with more developer friendly names provides benefit that is pretty self explanatory, making it easier to understand the structure and meaning of data as the application is developed. These changes can be done using the LINQ to SQL designer in Visual Studio 2008, by double clicking on the entity object name, as seen in Figure 3 below.

Figure 3. Changing the name of an entity object in LINQ to SQL.
As mentioned above, LINQ to SQL targets scenarios where the database closely resembles the application object model that is desired. Given this target scenario, the mapping between the SQL schema and classes in the application is a direct 1-1 mapping, meaning that a table or view being accessed from the database maps to a single class in the application, and a column being accessed maps to a property on the associated class.
By default, LINQ to SQL enables deferred loading. This means that if, for example, a query retrieves Customer data, it does not automatically pull the associated Order information into memory. When the data is requested however, LINQ to SQL uses its implicit loading capability to retrieve the data that has been requested but has not previously been loaded into memory. In Listing 1 we queried the database for all customers with an address based in London. While iterating through the resulting list of customers we would like to access the list of Orders that each customer has placed. Looking back to the original query in Listing 1, we notice that we did not retrieve any information about Orders; we simply retrieved information included in the Customer object. In Listing 2, we continue from the previous query to iterate through the customers that were returned and print out the total number Orders associated with each customer.
foreach (Customer c in customers)
{
     Console.WriteLine(c.CompanyName + " " + c.Orders.Count);              
}
Listing 2. Implicit loading of Orders data that has been requested but not previously loaded into memory.
In the above example, a separate query is executed to retrieve the Orders for each Customer. If it is known in advance that we need to retrieve the orders for all customers, we can use LoadOptions to request that the associated Orders be retrieved along with the Customers, in a single request.
Beyond the simplicity of the query experience, LINQ to SQL offers additional features to improve the developer experience with regards to application logic. Partial methods, a new language feature of C# and VB in Visual Studio 2008, allow one part of a partial class to define and call methods which are invoked, if implemented in another part of the class. If the method has not been implemented; the entire method call is optimized away during compilation. By using common naming conventions in conjunction with these new partial methods and partial classes, introduced in Visual Studio 2005, LINQ to SQL allows application developers to provide custom business logic when using generated code. Using partial classes allows developers the flexibility to add methods, non-persistent members, etc., to the generated LINQ to SQL object classes. These partial methods can add logic for insert, update, and delete by simply implementing the associated partial method. Similarly, developers can use the same concepts to implement partial methods that hook up eventing in the most common scenarios, for example OnValidate, OnStatusChanging or OnStatusChanged.  Example 3 shows the use of partial methods to implement custom validation on the Customer Phone property as it is changed.
public partial class Customer
{
    partial void OnPhoneChanging(string value)
    {
        Regex phoneNum = new Regex(@"^[2-9]\d{2}-\d{3}-\d{4}$");
        if (phoneNum.IsMatch(value) == false)
            throw new Exception("Please enter a valid Phone Number");
    }
}
Listing 3. Use of partial methods to implement custom validation logic.
Once developers can leverage the query capabilities of LINQ and implement business logic in partial methods, the argument for using persistent objects becomes quite compelling. To round the story out, LINQ to SQL allows people to model inheritance hierarchies in their classes and map them to the database. Inheritance, an important feature of object-oriented programming, does not translate directly into the relational database; therefore, the ability to map inheritance from the application into the database is very important. LINQ to SQL supports one of the most common database inheritance mappings, Table per Hierarchy (TPH), where multiple classes in a hierarchy are mapped to a single table, view, stored procedure, or table valued function using a discriminator column to determine the specific type of each row/instance. In Figure 4, a single Product table in the database, maps the inheritance of DiscontinuedProduct from Product. This two-class hierarchy is mapped directly to the existing Northwind database using the discriminator column “Discontinued”.


Figure 4. Inheritance in LINQ to SQL
Notice that the properties of the inheritance (right-click on the relationship arrow) specify the discriminatory property and the associated discriminator values, while the properties of DiscontinuedProduct specify the base class from which it inherits.
LINQ to SQL has been developed with a minimally intrusive object model, allowing developers to choose whether or not to make use of generated code. Rather, they can create their own classes, which do not need to be derived from any specific base class. This means that you can create classes that inherit from no base class or from a custom base class.
As with any application framework, developers must also have the ability to optimize the solution to best fit their scenario. LINQ to SQL offers a number of opportunities to optimize, including using load options to control database trips and compiled queries to amortize the overhead inherent in SQL generation. By default, LINQ to SQL enables Object Tracking, which controls the automatic change tracking and identity management of objects retrieved from the database. In some scenarios, specifically where you are accessing the data in a read-only manner, you may wish to disable Object Tracking as a performance optimization. The options for specialization of your application behavior is not local to just the API, the LINQ to SQL Designer also allows additional functionality for you to expose stored procedures and/or table valued functions as strongly typed methods on the generated DataContext, and map inserts, updates, and deletes to stored procedures if you choose not to use dynamic SQL.
Developers who are concerned about query performance can leverage the compiled queries capabilities which offer an opportunity to optimize query performance. In many applications you might have code that repeatedly executes the same query, possibly with different argument values. By default, LINQ to SQL parses the language expression each time to build the corresponding SQL statement, regardless of whether that expression has been seen previously. Compiled queries, like that seen in Listing 4, allow LINQ to SQL to avoid reparsing the expression and regenerating the SQL statement for each repeated query.   
var customers = CompiledQuery.Compile(
                    (NorthwindDataContext context,
                     string filterCountry) =>
                        from c in context.Customers
                        where c.Orders.Count > 5
                        select c);

NorthwindDataContext db = new NorthwindDataContext();
           Console.WriteLine("Customers in the USA: ");
foreach (var row in customers(db, "USA"))
{
       Console.WriteLine(row.CompanyName);
}
Console.WriteLine();
Console.WriteLine("Customers in Spain: ");
foreach (var row in customers(db, "Spain"))
{
       Console.WriteLine(row.CompanyName);
}
Listing 4. An example of a simple compiled query, executed twice with varying parameters.

When Do I Use LINQ to SQL?

The primary scenario for using LINQ to SQL is when building applications with a rapid development cycle and a simple one-to-one object to relational mapping against the Microsoft SQL Server family of databases. In other words, when building an application whose object model is structured very similarly to the existing database structure, or when a database for the application does not yet exist and there is no predisposition against creating a database schema that mirrors the object model; you can use LINQ to SQL to map a subset of tables directly to classes, with the required columns from each table represented as properties on the corresponding class. Usually in these scenarios, the database has not and/or will not be heavily normalized.

I want to
LINQ to SQL is applicable
Use an ORM solution and my database is 1:1 with my object model

Use an ORM solution with inheritance hierarchies that are stored in a single table

Use my own plain CLR classes instead of using generated classes or deriving from a base class or implementing an interface

Leverage LINQ as the way I write queries

Use an ORM but I want something that is very performant and where I can optimize performance through stored procedures and compiled queries

Table 1. LINQ to SQL Scenarios

What Is LINQ to Entities?

LINQ to Entities, like LINQ to SQL is a LINQ implementation providing access to relational data, but with some key differences.
LINQ to Entities is, specifically, a part of the ADO.NET Entity Framework which allows LINQ query capabilities. The Entity Framework is the evolution of ADO.NET that allows developers to program in terms of the standard ADO.NET abstraction or in terms of persistent objects (ORM) and is built upon the standard ADO.NET Provider model which allows access to third party databases. The Entity Framework introduces a new set of services around the Entity Data Model (EDM) (a medium for defining domain models for an application). This set of services includes the following:
·         Domain Modeling  Capabilities and the ability to define conceptual, data store agnostic models
·         Object Relational Mapping Capabilities (full CRUD and state management scenarios)
·         Database independent Query Capabilities using LINQ or Entity SQL
More than a simple Object Relational Mapping (ORM) tool, the ADO.NET Entity Framework and LINQ to Entities allow developers to work against a conceptual model with a very flexible mapping and the ability to accommodate a high degree of divergence from the underlying data store. For further discussion of the Entity Framework and EDM, please see the Data Platform Development Center (http://msdn.microsoft.com/data).
Figure 5 below shows a simple LINQ to Entities EDM diagram, using the same subset of the Northwind database seen in Figure 1.

Figure 5. LINQ to Entities mapping diagram corresponding to the Northwind database subset in Figure 1. Notice the directly mapped many-to-many relationship between Employees and Territories without an intermediary table.
In this figure you can see that the object model is not mapped directly, one-to-one, to the database, rather we have bypassed the intermediary table used to represent the many-to-many relationship between Employees and Territories.  Although you can map many-to-many relationships in both LINQ to SQL and LINQ to Entities, LINQ to Entities allows a direct mapping of many-to-many relationships with no intermediary class, while LINQ to SQL requires that an intermediary class map one-to-many to each of the classes that are party to the many-to-many relationship.
Listing 5 below shows the same simple LINQ query used in Listing 1 for LINQ to SQL, used against the Entity Data Model shown in Figure 5. 
using (NorthwindEntities nw = new NorthwindEntities())
{
       var cusotmers = from c in nw.Customers
                       where c.City == "London"
                       select c;
}
Listing 5. Simple LINQ to Entities query
The similarities between the two LINQ implementations for this simple query highlight the benefit of LINQ creating a query language that remains consistent across data stores.
Microsoft designed the ADO.NET Entity Framework, and in turn LINQ to Entities, to enable flexible and more complex mappings, ideal in the scenario where it is not possible or ideal for the object model to match the database schema. The mapping flexibility available with the ADO.NET Entity Framework allows the database and application(s) to evolve separately and makes development against highly normalized databases simpler and easier to understand. When a change is made in the database schema, the application is insulated from the change by the Entity Framework, and there is no requirement to rewrite portions of the application, but rather the mapping files can simply be updated to accommodate the database change. In Figures 6 & 7, a change is made to the database splitting the Employees table to separate personal information that is only accessible to HR and information that is available in the Employee Address Book. If existing applications are not going to make use of these changes we simply need to update the mapping to account for this change.

Figure 6. Database Model for the new modified Northwind database subset. In this modified database, we have split the Employees table into two tables one containing Employee information that is only available to HR and another containing information that is available to all employees in the Employee Address Book. We have also used a different inheritance mapping, Table per Subclass, which we will discuss later.


Figure 7. Entity Data Model Diagram for the modified Northwind database subset shown in Figure 6.
Listing 6 shows a query against a single entity, mapped to multiple tables in the database. The same query directly against the database would require the knowledge that Employee information is split between two tables and a join of those two tables in the query.
using (NorthwindModEntities nw = new NorthwindModEntities())            {
       var q = from e in nw.Employees
               select e;
       foreach (Employees emp in q)
       {
               Console.WriteLine(emp.FirstName + ", " + emp.LastName + ", Hire Date: " + emp.HireDate.ToString());
       }
}
Listing 6. Querying a single Entity mapped to two tables in the database.
As discussed earlier in this article, LINQ to SQL allows one of the most common inheritance scenarios to be mapped, Table per Hierarchy. LINQ to Entities and the ADO.NET Entity Framework also allow the mapping of two other types of inheritance. In addition to Table per Hierarchy (as supported by LINQ to SQL), the Entity Framework supports:
·         The mapping of Table per Concrete Type, a separate table for each class or type in the hierarchy.
·         The mapping of Table per Subclass, a hybrid approach using a shared table for information about the base type and separate tables for information about the derived types seen in Figure 8.  

Figure 8. Mapping Table per Subclass inheritance with the Entity Data Model.
Similar to LINQ to SQL, LINQ to Entities uses partial classes and partial methods to allow update and business logic to be easily added to generated code. Using partial classes and partial methods allows developers the flexibility to add methods, non-persistent members, etc., to the generated Entity Framework object classes, and for the addition of custom logic for insert, update, and delete by simply implementing the associated partial method. Similarly, developers can use the same concepts to implement partial methods that hook up eventing in the most common scenarios, for example OnStatusChanging or OnStatusChanged. Listing 7 shows the use of partial methods to implement custom validation on the Customer Phone property as it is changed.
public partial class Customers
{
       partial void OnPhoneChanging(string value)
       {
            Regex phoneNum = new Regex(@"^[2-9]\d{2}-\d{3}-\d{4}$");
            if (phoneNum.IsMatch(value) == false)
                throw new Exception("Please enter a valid Phone Number");
       }
}
Listing 7. Use of partial methods to implement custom validation logic.
Due to the explicit nature of LINQ to Entities, developers also have the ability to optimize the solution to best fit their scenario. In Listing 2 for LINQ to SQL, when we queried for Customer data, Order information was not automatically pulled into memory, but rather was only pulled into memory only when the Order information was accessed. In LINQ to Entities, the developer has full control over the number of database round trips by explicitly specifying when to load such information from the database. Navigating to associated information that has not yet been retrieved from the database will not cause an additional database trip, but rather will only return the information if it was explicitly requested with the first query or with a new query, as seen in Listing 8.
using (NorthwindModEntities nw = new NorthwindModEntities())
{
   var q = from cus in nw.Customers
           where cus.City == "London"
           select cus;
// Loop through customers and print out orders since January 1, 1998
   foreach (Customers customer in q)
   {
       Console.WriteLine(customer.CompanyName + ": " );
// Note line below to explicitly load all orders for each customer
       customer.Orders.Load();
       foreach (Orders order in customer.Orders.Where(o => o.OrderDate > new DateTime(1998, 1, 1)))
       {
           Console.WriteLine("\t{0},{1}", order.OrderID, order.OrderDate);
       }
   }
   Console.ReadLine();
}
Listing 8. Explicit loading of information to control number of database roundtrips.
Like LINQ to SQL, LINQ to Entities enables Object Tracking by default. In some scenarios, specifically where you are accessing the data in a read-only manner, you may wish to disable Object Tracking as a performance optimization.
LINQ to Entities also provides the ability to expose stored procedures as strongly typed methods on the generated ObjectContext, and map inserts, updates, and deletes to stored procedures if you choose not to use dynamic SQL.

When do I use LINQ to Entities?

The primary scenario targeted by LINQ to Entities is a flexible and more complex mapping scenario, often seen in the enterprise, where the application is accessing data stored in Microsoft SQL Server or other-third party databases.
In other words, the database in these scenarios contains a physical data structure that could be significantly different from what you expect your object model to look like. Often in these scenarios, the database is not owned or controlled by the application developer(s), but rather owned by a DBA or other third party, possibly preventing application developers from making any changes to the database and requiring them to adapt quickly to database changes that they may not have been aware of.

I want to
LINQ to Entities is applicable
Write applications that can target different database engines in addition to Microsoft SQL Server

Define domain models for my application and use these as the basis for my persistence layer.

Use an ORM solution where my classes may be 1:1 with the database or may have a very different structure from the database schema

Use an ORM solution with inheritance hierarchies that may have alternative storage schemes (single table for the hierarchy, single table for each class, single table for all data related to specific type)

Leverage LINQ as the way I write queries and have the query work in a database vendor agnostic manner.

Use an ORM but I want something that is very performant and where I can optimize performance through stored procedures and compiled queries

Table 2. LINQ to Entities Scenarios

Friday, November 22, 2013

ASP.NET Security


ASP.NET Security: An Introductory Guide to Building and Deploying More Secure Sites with ASP.NET and IIS

ASP.NET Security

An Introductory Guide to Building and Deploying More Secure Sites with ASP.NET and IIS

Jeff Prosise
This article assumes you're familiar with the .NET Framework
Level of Difficulty     1   2   3 
SUMMARY ASP.NET and Microsoft Internet Information Services (IIS) work together to make building secure Web sites a breeze. But to do it right, you have to know how the two interrelate and what options they provide for securing access to a Web site's resources. This article, the first in a two-part series, explains the ABCs of Web security as seen through the eyes of ASP.NET and includes a hands-on tutorial demonstrating Windows authentication and ACL authorizations. A range of security measures and authentication methods are discussed, including basic authentication, digest authentication, and role-based security.
There's an old adage among developers that says building security into software is like paying taxes. You know it's important and you know you must do it sooner or later, but you put it off as long as you can and when you finally do it, you do so only because you have to. You might not go to jail for building insecure applications, but security is no less important because of it. In many applications—Web applications in particular—security isn't a luxury; it's a necessity.
      Security is a big deal in network applications because by nature those applications are available to (and vulnerable to misuse by and attacks from) a larger population of users. When the network to which an application is deployed is the Internet, security becomes even more important because the list of potential users grows to about four billion. Web security is a broad and complicated subject. Much of the ongoing research in the field has to do with hardening Web servers against attacks. Microsoft® Internet Information Services (IIS) administrators are all too aware of the past security holes in IIS and of several patches and security updates from Redmond. But this article isn't about protecting servers from buffer overruns and other hack attacks; rather, this article is about using ASP.NET to build secure sites that serve up pages only to authorized users.
      Most sites built with ASP.NET fall into one of three categories:
  • Sites whose content is freely available to everyone.
  • Internet sites that serve the general population but require a login before displaying certain pages. eBay is a great example of such a site. Anyone can browse eBay and view the ongoing auctions, but when you place a bid, eBay requires a user name and password. eBay also has a feature named "My eBay" that lets you review the auctions you've bid on. Because My eBay pages are personalized for individual users and because they contain private information such as maximum bid prices, you must log in before viewing them.
  • Intranet sites that expose content to a controlled population of users—for example, a company's employees—who have accounts in a Windows® domain (or set of domains). Sometimes these sites support a limited degree of Internet access, too, so authorized users can access them from anywhere an Internet connection is available.
      Sites that fall into the first category require no special protection beyond what the Web server provides. Sites in the second and third categories require some form of application-level security to identify authorized users and prevent illicit accesses. ASP.NET provides that application-level security. It works in conjunction with IIS and the Windows security subsystem to provide a solid foundation for building secure sites. And it builds on what IIS has to offer to make deploying secure sites as easy as possible.
      This is the first in a two-part series on building secure Web sites with ASP.NET. In this installment, you'll learn how ASP.NET integrates with IIS and Windows and how the three can be combined to protect resources using Windows authentication and access control list (ACL) file authorizations. Part two of this article will cover ASP.NET forms authentication—a cool new feature of ASP.NET that lets you secure sites using a combination of form-based logins and URL resource authorizations.

Understanding Web Security

      At the application level, Web security is first and foremost about securing pages so that they can't be retrieved by unauthorized users—for example, preventing non-managers from viewing pages containing salary data and performance evaluations on the company intranet or preventing other people from viewing your My eBay pages. At a slightly deeper level, you might want to know who requested the page so you can personalize it for that individual. Either form of protection requires two overt actions on the part of the application: identify the originator of each request and define rules that govern who can access which pages
      A Web server identifies callers using a mechanism called authentication. Once a caller is identified, authorization determines which pages that particular caller is allowed to view. ASP.NET supports a variety of authentication and authorization models. Understanding the options that are available to you and how they interrelate is an important first step in designing a site that restricts access to some or all of its resources or that personalizes content for individual users.

Authentication

      Authentication enables the recipient of a request to ascertain the caller's identity. The caller might claim to be Bob, but you don't know he really is Bob unless you authenticate him. ASP.NET supports three types of authentication: Windows authentication, Passport authentication, and forms authentication.
      When Windows authentication is selected, ASP.NET looks to IIS for help. IIS does the hard part by authenticating the caller. Then it makes the caller's identity available to ASP.NET. Let's say Windows authentication is enabled and Bob requests an ASPX file. IIS authenticates Bob and forwards the request to ASP.NET along with an access token identifying Bob. ASP.NET uses the token to make sure Bob has permission to retrieve the page he requested. ASP.NET also makes the token available to the application that handles the request so that at its discretion, the application can impersonate Bob—that is, temporarily assume Bob's identity—to prevent code executed within the request from accessing resources that Bob lacks permission to access.
      For Web applications, Windows authentication is typically used in the following scenarios:
  • Your application is deployed on the company's intranet and everyone who uses it has an account that they can use to log in and access network resources.
  • Your application is primarily intended for use on the company intranet, but you'd also like it to be possible for employees to be able to log in and use the application remotely—that is, from outside the firewall.
      The overarching goal of Windows authentication is to map incoming requests to user accounts on your Web server (or in the Web server's domain). In addition to preventing users who lack the proper logon credentials from accessing parts of your Internet site that require authenticated access, Windows authentication lets you use the operating system's built-in security mechanisms in order to protect files and any other resources from unauthorized access by authenticated users.
      Passport authentication relies on Microsoft Passport to authenticate users. Passport is a Web service that front-ends a massive database of user names and passwords maintained by Microsoft. Users who register with Passport can be authenticated anywhere on the Internet by applications that present login credentials to Passport. If Passport determines that the credentials are valid, it returns an authentication ticket that the application can encode in a cookie to prevent the user from having to log in time and time again. If you would like to see further information about Passport, check out the Passport SDK, which you can download from the Microsoft Web site.



Figure 1 Forms Authentication

      Forms authentication relies on login forms in Web pages to authenticate users. Figure 1 shows an example of forms authentication in action on eBay. You can surf most of eBay's site without logging in. But to bid on an item or go to My eBay, you have to enter a user name and password to let eBay know who you are. Windows authentication isn't very practical in this scenario because eBay doesn't want to assign each of its millions of users a Windows account on its servers. Forms authentication fits the bill nicely because it doesn't require users to have Windows accounts. It's perfect for Internet sites designed to serve the general population but that also have to know who a user is before allowing access to certain pages. Forms authentication is as old as the Web, but ASP.NET makes it incredibly easy as you'll see later in this article.
      You tell ASP.NET what type of authentication, if any, to use through Web.config files. The following Web.config file enables forms authentication for the corresponding application:
<configuration>
  <system.web>
    <authentication mode="Forms" />
  </system.web>
</configuration>
      Other valid mode values include None, Windows, and Passport. The default, defined in Machine.config, is Windows. The authentication mode is an application-wide setting that can only be set in the application root and can't be overridden in subordinate Web.config files. You can't use Windows authentication in one part of an application and forms authentication in another.

Authorization

      Authentication is an important element of Web security—indeed, of network security in general—because it establishes trust. You can't trust a user if you don't know who he or she is.
      Authorization is the other half of the security equation. Once you know who a user is, authorization determines what resources that person can access. On a company intranet, for example, you might want to prevent rank-and-file employees from accessing files and directories containing payroll data. That's what authorization is for. ASP.NET supports two forms of authorization: ACL authorization (also known as file authorization) and URL authorization.
      ACL authorization is based on file system permissions. Most Web servers that run IIS and ASP.NET use the NTFS file system. NTFS uses ACLs to protect file system resources—that is, files and directories. It's trivial, for example, to tag a file with an ACL that permits only system administrators to read it. You simply pop up the file's property sheet, go to the Security page, remove the security principals (users and groups) that are currently listed, and add administrators. If you don't want Bob to view a particular ASPX file, you can deny Bob read access to the file in an ACL and Bob will be greeted with an access denied error when he tries to view the page. Because ACL checks are performed against access tokens representing Windows security principals, ACL authorization is typically used in scenarios where Windows authentication is used, too.
      URL authorization works differently. Rather than rely on NTFS permissions to protect resources, it relies on configuration directives in Web.config files. URL authorization is wholly a function of ASP.NET and does not require the complicity of IIS. It's most often used with forms authentication, but can be used with other authentication types as well.

IIS Security

      Since IIS is a Web server, its primary job is to accept connections from remote clients and respond to HTTP requests arriving through those connections. Most of the requests are HTTP GET and POST commands requesting HTML files, JPEG files, ASPX files, and other file system resources. Obviously, you don't want someone who connects to your Web server to be able to retrieve just any file. IIS protects a server's content in four ways:
  • Web applications are deployed in virtual directories that are URL-addressable on the server. Remote clients can't arbitrarily grab files outside virtual directories and their subdirectories.
  • IIS assigns every request an access token that enables the operating system to perform ACL checks on the resources used in the request. If the request runs as Bob and Bob isn't allowed to read Hello.html, then the request will fail when it attempts to read Hello.html. In addition, IIS makes Bob's access token available to ASP.NET so that ASP.NET can perform access checks of its own.
  • IIS supports IP address and domain name restrictions, enabling requests to be granted and denied based on the IP address or domain of the requesting entity.
  • IIS supports encrypted HTTP connections using the Secure Sockets Layer (SSL) family of protocols. SSL doesn't protect resources on the server per se, but it does prevent eavesdropping on conversations between Web servers and remote clients.
      All of these protection mechanisms are important to ASP.NET programmers, but the second item listed merits special consideration because ACL checks are wholly dependent upon the identity assigned to a request, and when Windows authentication is the chosen form of authentication, ASP.NET works closely with IIS to resolve issues involving identity.
      IIS runs in a process named Inetinfo.exe. Inetinfo.exe typically runs using the identity of the built-in SYSTEM account, which is highly privileged on the host machine. Requests forwarded to ASP.NET by IIS don't run as SYSTEM, however. They're assigned the identity of a specific user. Which user depends on the configuration of the requested resource.
      Through the IIS configuration manager found under Administrative Tools, IIS permits authentication control to be applied to individual files and directories. A given file or directory can be configured to allow anonymous access (access by unauthenticated users), authenticated access, or both. Let's say a request comes in for a file that supports anonymous access. By default, the request executes as IUSR_machinename, where machinename is the Web server's machine name. IUSR_machinename is a special account that's created when IIS is installed. You can use the IIS configuration manager to map anonymous requests to other accounts, but assuming you don't change the defaults, requests from anonymous users are tagged with IUSR_machinename's access token. It follows that Web pages intended for anonymous users should not be tagged with ACLs that deny access to IUSR_machinename.
      If, on the other hand, the requested file requires authenticated access, IIS assigns the request the identity of the account whose credentials the requestor supplies. If the user is Bob and can prove as much to IIS, then the request is tagged with Bob's access token.
      How does IIS ascertain a requestor's identity for authenticated accesses? How, for example, does it know that Bob is Bob? It depends on the type of authentication used. IIS supports four different forms of authentication: basic authentication, digest authentication, integrated Windows authentication, and SSL client certificates. As far as ASP.NET is concerned, all fall under the category of Windows authentication.
      Basic and digest authentication rely on user names and passwords to authenticate users. When the client is a browser, the browser prompts the user for a user name and password and transmits them to the Web server. Basic and digest authentication work well over the Internet because they piggyback on HTTP. Integrated Windows authentication uses Windows logon credentials to authenticate users. It's ill-suited to general Internet use, in part because both client and server must support Windows security protocols, and also because the client must validate against a domain controller that it can't get to through a firewall. SSL client certificates are also limited primarily to intranet use because they require clients to be outfitted with digital certificates.

ASP.NET Security

      Figure 2 shows the relationship between IIS and ASP.NET. When IIS receives a request for a file registered to ASP.NET (for example, an ASPX file), it hands the request off to an ISAPI DLL named Aspnet_isapi.dll. Aspnet_isapi.dll runs in the same process as IIS—that is, inside Inetinfo.exe. ASP.NET applications run in a separate process named Aspnet_wp.exe. Aspnet_isapi.dll forwards requests to Aspnet_wp.exe using a named pipe. When the request reaches the worker process, it is assigned to a specific application executing in a specific AppDomain. Once inside an AppDomain, the request travels through the ASP.NET HTTP pipeline, where it is examined by various HTTP modules and ultimately processed by the HTTP handler that corresponds to the resource type requested. Machine.config contains the master list that maps file types to HTTP handlers.








Figure 2 Relationship between IIS and ASP

      The architecture in Figure 2 changes somewhat when ASP.NET is paired with IIS 6.0. Slated for release in 2002 with Windows Server 2003, IIS 6.0 will feature a more robust security model that gives IIS administrators the ability to segregate applications into surrogate processes very much like Aspnet_wp.exe. In IIS 6.0, there is no Aspnet_wp.exe; instead, IIS provides the worker process. At the time of this writing, Microsoft plans to connect Inetinfo.exe to worker processes using Local Procedures Calls (LPCs) rather than named pipes.
      What does all of this have to do with security? When Aspnet_isapi.dll forwards an HTTP request to Aspnet_wp.exe, it also forwards the access token that it obtained from IIS. That access token is typically one of the following: an IUSR_machinename token representing an unauthenticated user, or a token representing an authenticated security principal (for example, Bob).
      Before processing the request by sending it through the targeted application's HTTP pipeline, Aspnet_wp.exe does the following:
  • It performs an ACL check on the requested resource using the access token presented to it. If, for example, the request is a GET command asking for Foo.aspx, the access token represents Bob, and Foo.aspx has an ACL that denies read permission to Bob, then ASP.NET fails the request with an access denied error. ASP.NET performs this ACL check regardless of whether impersonation is enabled in ASP.NET.
  • It makes the access token available to the application that handles the request so that, if desired, the application can impersonate the caller and protect resources guarded by ACLs from code executed during the request.
      The importance of these actions cannot be overstated. The ACL check that ASP.NET performs before processing the request means you can deny Bob access to an ASPX file simply by tagging that file with an ACL that denies Bob read access. The fact that ASP.NET makes the caller's access token available for impersonation purposes means you, the developer, have some latitude in deciding what identity to use when processing the request. The right choice depends on what the application is designed to do and how it's designed to do it. I'll provide some background to enrich your understanding.
      By default, Aspnet_wp.exe runs as ASPNET, a special account that's set up when ASP.NET is installed. ASPNET is a member of the Users group, which means it's privileged enough to perform most of the actions a legitimate application might want to perform, but restricted enough to prevent certain kinds of attacks. Unless you specify otherwise, requests executed by ASP.NET use Aspnet_wp.exe's identity. Therefore, by default, requests run as ASPNET. Among other things, this means that barring configuration changes, there are certain actions an ASP.NET application can't perform, such as modifying entries in the HKEY_LOCAL_MACHINE section of the registry.
      The other option is to execute the request using the access token provided by IIS, a technique known as impersonation. Impersonation is enabled by including the following statement in the <system.web> section of a top-level Web.config file or modifying the <identity> element already present in Machine.config:
<identity impersonate="true" />
      If IIS assigns a request the identity of IUSR_machinename, impersonation won't buy you much because IUSR_machinename is a weak account that enjoys few privileges on the host machine. But if Windows authentication is enabled and IIS presents ASP.NET with a token representing the actual requestor, impersonation ensures that the application can't do anything on the Web server that the requestor isn't allowed to do.
      To further complicate matters, Aspnet_wp.exe can be configured to run as a principal other than ASPNET. Suppose you write an ASP.NET application that must have wider-ranging permissions than those afforded ASPNET—for example, the freedom to write to any part of the registry. You can configure Aspnet_wp.exe to run as SYSTEM by changing the statement
<processModel userName="machine" ... />
in Machine.config to read:
<processModel userName="SYSTEM" ... />
This enables your application to do almost anything it wants on the host machine, but it also makes ASP.NET less resistant to attacks. SYSTEM was the default when ASP.NET was in beta, but that was changed shortly before the product shipped.
      Another possible complication arises from the fact that in IIS 6.0, ASP.NET requests will default to Network Service rather than ASPNET. If you use ACLs to allow access to the ASPNET account while denying access to other security principals and find that requests mysteriously fail with access denied errors after you install IIS 6.0, modify your ACLs to allow access to Network Service rather than ASPNET.
      Clearly, the identities assigned to the ASP.NET worker process and to the requests that it executes play crucial roles in determining how successful an application is in carrying out its appointed mission. If your head is spinning right now trying to make sense of it all, don't fret; ASP.NET security will be far easier to grasp once you've experienced it firsthand. In the meantime, here are some guidelines to help you sort through the options and figure out which of them really matter for a given deployment scenario:
  • If your application requires no special protection—if all of its pages can be freely browsed by anyone and none are personalized for individual users—you needn't bother with application-level security. Just grant Everyone access to the application's files and be done with it.
  • If you're building an intranet application or any application whose permissions are based on mapping incoming requests to Windows accounts on your server, you'll probably use Windows authentication and ACL authorization. In that case, you'll use operating system ACLs to restrict access to pages that aren't intended for everyone. You may or may not enable impersonation, depending on the needs of the application.
  • If you're building an Internet application that serves the general public but want to secure access to certain pages, you'll most likely use forms authentication and URL authorization. In that case, you'll leave impersonation disabled and rely on credentials entered in login forms as the basis for authorizations. Many of the aformentioned issues regarding IIS and access tokens fall by the wayside in this scenario because you grant Everyone access to the application's files and rely on URL authorizations in Web.config to protect them.
      A final thought to keep in mind is that if you use ACLs to limit access to files and directories in an ASP.NET application, always grant the ASPNET account—or whatever account Aspnet_wp.exe runs as—read access to them. Otherwise, ASP.NET itself will be unable to read them and you'll experience all kinds of access denied errors that you probably didn't expect.

Windows Authentication

      Windows authentication is one of the options that ASP.NET gives you for identifying callers. Because Windows authentication maps incoming requests to accounts on the Web server or in the Web server's domain, you don't use it to generically expose content to all comers over the Internet. Instead, you use it to serve content to a well-defined populace—a populace that you control through Windows user accounts. Windows authentication on the front end is typically paired with ACL authorization on the back end to control access to the resources that your application exposes. But it works with URL authorization, too.
      Recall that Windows authentication comes in four forms: basic, digest, integrated, and client certificate. All map incoming requests to accounts on your network, but each does so in a different way. The next several sections describe the inner workings of basic, digest, and integrated Windows authentication and the user experiences that they convey. After that, I'll put Windows authentication to work in a real ASP.NET application.

Basic Authentication

      Basic authentication is an HTTP standard. It's documented in RFC 2617, which you can read online at ftp://ftp.isi.edu/in-notes/rfc2617.txt. Basic authentication transmits a user name and password in each request. IIS maps the user name and password to an account on the Web server, producing an access token that can be used to perform ACL-based security checks.
      It sounds simple, and it is. To demonstrate how basic authentication works, suppose your company deploys a series of Web pages containing information that only employees should be able to see. The IT staff places the files in a virtual directory on your Web server and configures IIS to disallow anonymous access to that directory and to require basic authentication. The first time you attempt to retrieve a page from that directory, the Web server returns a 401 status code indicating that authentication is required. It also includes in the response a WWW-Authenticate header identifying the type (or types) of authentication that it accepts. (The details differ slightly when a proxy server is involved, but the principle is valid nonetheless.) Here's a portion of a response returned by IIS 5.0 indicating that access to the requested resource requires basic authentication:
HTTP/1.1 401 Access Denied
Server: Microsoft IIS-5.0
  •••
WWW-Authenticate: Basic realm="jupiter"
      Your browser responds by popping up a dialog box asking for a user name and password (seeFigure 3).













Figure 3 Basic Authentication

It then concatenates the user name and password to a string that identifies the authentication type, base-64-encodes the result, and transmits it to the browser in the Authorization header of an HTTP request. Here's the Authorization header transmitted by Internet Explorer 6.0 following a login with the user name "Jeff" and the password "imbatman":
Authorization: Basic SmVmZjppbWJhdG1hbg==
And here are the contents of the base-64-encoded portion of the header after decoding:
Jeff:imbatman
      To prevent you from having to log in again and again, the browser includes the same Authorization header in future requests to the same realm. A realm is simply a logical security space that encompasses all or part of a Web site.
      All authentication mechanisms have pros and cons. What's good about basic authentication is that it works with virtually all browsers, it provides an easily used and understood means to solicit user names and passwords, and it works well with firewalls. The downside of basic authentication is that it transmits user names and passwords in clear text. If used over an unencrypted channel, there's nothing to prevent requests from being intercepted and used to gain access to your server (or other servers where the caller's credentials are valid). In addition, some users consider pop-up user name and password dialogs intrusive.
      If you use basic authentication and the lines to your Web server aren't physically secured, be sure you use it over HTTPS, not HTTP. Otherwise, you'll secure access to honest (or technically unsophisticated) users, but leave yourself vulnerable to attacks by others.

Digest Authentication

      Digest authentication is similar to basic authentication. When you attempt to access a resource guarded by digest authentication, the browser solicits a user name and password by popping up a dialog box. The Web server uses the credentials that you enter to assign an identity to the request. The big difference between basic and digest authentication is that digest doesn't transmit clear-text passwords. Instead, it passes an authentication token that is cryptographically secure. As a result, you can use it over unencrypted channels without fear of compromising your Web server.
      The inner workings of digest authentication are also documented in RFC 2617. When the client first requests a resource guarded by digest authentication, the server returns a 401 error and includes a "nonce"—a string of 1s and 0s—in a WWW-Authenticate header. The browser responds by prompting for a user name and password. It then transmits the user name back to the server, along with a hash or "digest" computed from the combined user name, password, and nonce. The server authenticates the request by performing its own hash on the user name, password, and nonce. The password the server uses doesn't come from the client; it comes from the server itself (or from a connected server). If the hashes match, then the user is authenticated. Significantly, digest authentication never requires a plain-text password to be transmitted over an HTTP connection. It's also compatible with proxy servers.
      Digest authentication offers the following advantages. Like basic authentication, it provides an easily understood means for identifying callers, and it works with firewalls. In addition it's far more secure over ordinary HTTP than basic authentication.
      But there are three primary disadvantages. First, digest authentication requires a modern browser that supports digest authentication. For Microsoft Internet Explorer users, version 5.0 or higher is required. Second , it requires passwords to be stored in plain text (or in a reversible encrypted form that can be converted to plain text). This is contrary to the normal security model in Windows, which stores one-way password hashes in lieu of plain-text or encrypted passwords to protect the passwords if the server is compromised. Finally, like basic authentication, digest authentication uses pop-up dialog boxes to prompt for user names and passwords. Due to these restrictions, and because digest authentication doesn't support delegation (the ability to make a call from one machine to another and have the call execute as the caller on the remote machine) on Windows 2000 servers, digest authentication is not widely used.

Integrated Windows Authentication

      Integrated Windows authentication uses Windows logon credentials to authenticate users. Rather than prompt a user for a user name and password and transmit them over HTTP, a browser asked to identify the user through integrated Windows authentication carries on a conversation with the Web server and identifies the user using that person's login identity on the client. In other words, if Bob logs in to his Windows PC, starts Internet Explorer, and requests a resource protected by integrated Windows authentication, a handshake ensues between Internet Explorer and the Web server, and Bob's request executes as Bob on the server. Obviously, Bob has to be a valid account on the server (or in a domain that the server can authenticate against), or else access will be denied. Unless configured to do otherwise, the browser only asks for a user name and password if Bob is not a valid account on the Web server.
      Integrated Windows authentication isn't an Internet standard; rather, it is a proprietary authentication protocol that permits Windows logon credentials to travel over HTTP. Its inner workings haven't been fully documented by Microsoft, although some details have been published by third parties. The details vary somewhat depending on the security provider being used, which can be either NTLM or Kerberos. In essence, however, the client and server negotiate a trust in a series of exchanges that involve user names, domain names, nonces, and hashes.
      Here are the benefits regarding integrated Windows authentication. It provides a better user experience because it doesn't force users who have already logged into Windows to provide a user name and password again. Integrated Windows authentication is secure, even over unencrypted channels, because plain-text passwords are never transmitted.
      There are two negatives to integrated Windows authentication. First, it works in Internet Explorer 2.0 and higher, but is unsupported by other browsers. Second, it's stopped dead in its tracks by most firewalls, primarily because the Windows security protocols that it negotiates—NTLM and Kerberos—rely on ports that are normally sealed off.
      Integrated Windows authentication is a great solution for in-house networks that sit behind firewalls and whose browser clients can be carefully controlled—that is, restricted to Internet Explorer. It is poorly suited for general Internet use.

Getting Information about Authenticated Users

      ASP.NET exposes information about callers via an HttpContext property named User. HttpContext objects accompany each and every request and are exposed to application code through the Context properties of various ASP.NET objects such as Page, WebService, and HttpApplication. Pages (ASPX files) access User through Page.Context.User or simply Page.User.
      User's type is IPrincipal. IPrincipal is an interface defined in the System.Security.Principal namespace that's implemented by the WindowsPrincipal and GenericPrincipal classes. When a user is authenticated using Windows authentication, Page.User refers to a WindowsPrincipal object. When a user is authenticated using another type of authentication, Page.User refers to a GenericPrincipal object. IPrincipal has a method named IsInRole that you can use to test role memberships. (For users authenticated using Windows authentication, roles correspond to groups. For users authenticated using forms authentication, roles do not exist unless they're programmatically assigned.) It also has a property named Identity that exposes information regarding an authenticated user's identity. Identity is actually a reference to an IIdentity interface, which has the members shown in Figure 4.
      It sounds confusing, but in practice, User makes it trivial to get information about callers. If you want to find out whether a caller is authenticated from code in an ASPX file, do this:
if (User.Identity.IsAuthenticated) {
    // The caller is authenticated
}
      You can also find out whether a caller is authenticated by checking the Request object's IsAuthenticated property, which consults User.Identity.IsAuthenticated under the hood. If you want to know the caller's name (assuming they're authenticated), do this:
string name = User.Identity.Name;


      For a user authenticated using Windows authentication, the name is of the formdomainname\username, where domainname is the name of the domain in which the user is registered (or machine name if it's a local account instead of a domain account), and username is the user's name. For forms authentication, the name is normally the one that the user typed into a login form. One use for the user name is to personalize pages for individual users. The application in the next section demonstrates how.

Windows Authentication in Action

      The application in Figure 5, which I'll refer to as CorpNet since it models a simple intranet-type application, uses Windows authentication and ACL authorization to restrict access to some of its pages and to personalize content for individual users. It contains three pages:
  • General.aspx, which provides users with general information about the company
  • Salaries.aspx, which lists the salary of the employee who is viewing the page
  • Bonuses.aspx, which lists this year's employee bonuses
      You'll deploy CorpNet such that anyone in the company can view General.aspx, but only selected individuals can view Salaries.aspx and Bonuses.aspx.
      Before testing can begin, you need to deploy the application on your Web server and configure it to provide the desired level of security. Here are the steps:
Figure 6 Choosing an Authentication Method
  1. Create a directory named Basic, somewhere—anywhere—on your Web server.
  2. Use IIS configuration manager to transform Basic into a virtual directory named "Basic."
  3. While in IIS configuration manager, configure Basic to require basic authentication and to disallow anonymous access. How? Right-click Basic in the IIS configuration manager and select Properties from the ensuing context menu. Go to the Directory Security page of the property sheet that pops up and click the Edit button under "Anonymous access and authentication control." In the ensuing dialog box, uncheck "Anonymous access" and check "Basic authentication," as shown in Figure 6. OK the changes and close the configuration utility.
  4. Create two user accounts on your Web server for testing purposes. Name the accounts "Bob" and "Alice." It doesn't matter what passwords you assign, only that Bob and Alice are valid accounts on the server.
  5. Copy General.aspx, Salaries.aspx, Bonuses.aspx, Bonuses.xml, and Web.config to the Basic directory.
  6. Change the permissions on Salaries.aspx so that only Bob and the ASPNET account are allowed access. At the very least, grant them read permission. Other permissions are optional.
  7. Change the permissions on Bonuses.xml (not Bonuses.aspx) to grant access to everyone, but specifically deny access to Alice.
Figure 7 Testing the Application

      Now give the application a test run by performing the following six exercises:
  1. Type http://localhost/basic/general.aspx into your browser's address bar to call up General.aspx. Because the Basic directory requires callers to be authenticated using basic authentication, a dialog box will pop up. Enter Bob's user name and password. When General.aspx appears, observe that it knows your login name (see Figure 7).
  2. Restart your browser and repeat the previous exercise, but this time enter Alice's user name and password rather than Bob's. General.aspx still displays just fine because both Bob and Alice have permission to access it.
  3. Without restarting your browser, call up Salaries.aspx. Because you're logged in as Alice and Alice isn't allowed to read Salaries.aspx, the server reports that access is denied. (If you're using Internet Explorer, you may have to type Alice's user name and password a few times before being told access is denied.)
  4. Restart your browser and try again to call up Salaries.aspx. This time, log in as Bob when prompted for a user name and password. Because Bob is permitted to read Salaries.aspx, the page comes up and Bob's salary appears. Salaries.aspx is capable of displaying salaries for other employees, too, but it uses the caller's login name to personalize the information that it displays.
  5. Without restarting your browser, call up Bonuses.aspx. A list of employee bonuses appears.
  6. Restart your browser and call up Bonuses.aspx again. This time, log in as Alice. What do you think will happen? Anyone can access Bonuses.aspx, but Bonuses.aspx calls DataSet.ReadXml to read Bonuses.xml, and Alice isn't permitted to read Bonuses.xml. You're logged in as Alice. Will Bonuses.aspx report an error?
      As you can see, Bonuses.aspx comes up just fine and even shows a list of bonuses. Clearly, Bonuses.aspx succeeded in reading Bonuses.xml. How can that happen if Alice lacks permission to read Bonuses.xml? The answer is simple, but also subtle.
      IIS tagged the request with Alice's access token. And it passed that access token to ASP.NET. ASP.NET knows that the caller is Alice and won't allow Alice to retrieve an ASPX file (or any other ASP.NET file type) for which Alice lacks access permission. But because Web.config lacks a statement enabling impersonation, any code executed inside the request executes as ASPNET, not as Alice. ASPNET has permission to read Bonuses.xml, so Alice wasn't prevented from viewing employee bonuses.
      I purposely laid this trap for you to drive home an important point. ASP.NET performs ACL checks on ASPX files and other ASP.NET file types using the caller's identity, regardless of whether impersonation is enabled. That means you can prevent any caller from retrieving an ASPX file simply by denying that caller permission to read the file. However, if a caller pulls up an ASPX file and the ASPX file programmatically reads another file, you must tell ASP.NET to impersonate the caller if you want the reader to be subject to an ACL check using the caller's identity.
      You can prevent Alice from seeing the data in Bonuses.xml by modifying Web.config to read as follows.
<configuration>
  <system.web>
    <authentication mode="Windows" />
    <identity impersonate="true" />
  </system.web>
</configuration>
The new line turns on impersonating.
      After making the change to Web.config, restart your browser, log in as Alice, and try to view Bonuses.aspx again. This time, you're greeted with an error message reporting that an error occurred while processing the page. That message is displayed by the exception handler in Bonuses.aspx's Page_Load method, which catches the XmlException thrown when ReadXml can't read Bonuses.xml. Restart your browser and log in as Bob, however, and you can once more view Bonuses.aspx.
      CorpNet demonstrates several important principles that you should keep in mind when writing ASP.NET applications that use Windows authentication:
  • Windows authentication is enabled in ASP.NET by including this statement in Web.config.
       <authentication mode="Windows" />
    
  • ASP.NET applications that use Windows authentication can prevent users from viewing files by using ACLs to deny access to selected security principals.
  • ASP.NET applications that use Windows authentication must enable impersonation if they want resources protected by ACLs to be protected from programmatic accesses by code executed within a request.
  • ASP.NET applications that use Windows authentication can personalize content for individual users by reading user names from Page.User.Identity.Name.
      Remember, too, that ASPX files and other ASP.NET files guarded by ACLs should grant read permission to the account that Aspnet_wp.exe runs as (by default, ASPNET), or else ASP.NET itself can't read the file. In order to prove it, temporarily remove ASPNET from Salaries.aspx's permissions list. Now even Bob can't view Salaries.aspx.

Windows Authentication and URL Authorizations

      CorpNet currently uses ACL authorizations to restrict access to its pages. But ASP.NET also supports URL authorizations. To demonstrate, create a subdirectory named Secret in the Basic directory and move Salaries.aspx, Bonuses.aspx, and Bonuses.xml into it. Then place the following Web.config file in the Secret directory (and be sure to replace domainname with the appropriate machine name or domain name for the Bob account):
<configuration>
  <system.web>
    <authorization>
      <allow users="domainname\Bob" />
      <deny users="*" />
    </authorization>
  </system.web>
</configuration>
Log in as Bob and you'll be able to access Salaries.aspx and Bonuses.aspx just fine. But log in as anyone else and it'll be as if the files don't exist.
      The chief drawback to URL authorizations is that they only protect files registered to ASP.NET. You can't use them to protect ordinary HTML files, for example. Another limitation is that URL authorizations are based on stringified names rather than Windows security IDs (SIDs). For these reasons, ACL authorizations are typically used in lieu of URL authorizations when Windows authentication is used, too.

Windows Authentication and Role-based Security

      Role-based security is a powerful concept in Web applications. Rather than restrict access to callers based on user names, role-based security restricts access based on "roles"—CEO, manager, developer, clerk, or whatever—that those users belong to. If you modify the permissions on the Secret directory to only allow access to members of a group named Managers, for example, you're exercising role-based security. Only users that belong to that group can call up Salaries.aspx and Bonuses.aspx.
      Role-based security can also be applied using URL authorizations. The following Web.config file restricts access to the host directory to members of the Managers group. Behind the scenes, ASP.NET handles the chore of mapping the groups to which the caller belongs to roles named in <allow> and <deny> attributes:
<configuration>
  <system.web>
    <authorization>
      <allow roles="domainname\Managers" />
      <deny users="*" />
    </authorization>
  </system.web>
</configuration>
      Role-based security applied through URL authorizations suffers from the same limitations as user-based security applied through URL authorizations, and is therefore rarely used outside of forms authentication.

Conclusion

      The marriage between Windows authentication and ASP.NET is a perfect one for intranet sites and also for sites that support Internet access to a controlled population of users. It doesn't, however, map very well to Internet sites that want to serve everybody. Next month, I'll conclude my look at ASP.NET security by taking a close look at forms authentication and seeing how it can be used to secure Web sites without requiring visitors to have logon accounts in your server's domain.
For related articles see:
Security Briefs: ASP .NET Security Issues
Security Briefs Archive
Web Security: Putting a Secure Front End on Your COM+ Distributed Applications
Web Security: Part 2: Introducing the Web Application Manager, Client Authentication Options, and Process Isolation 

For background information see:
Security Briefs: Managed Security Context in ASP.NET 
Jeff Prosise makes his living programming Windows and teaching others to do the same. He is also a cofounder of Wintellect, a developer training and consulting firm that specializes in .NET developer training. Contact Jeff at wicked@microsoft.com. This article was adapted from Jeff's upcoming book,Programming Microsoft .NET, which will be published in May 2002 by Microsoft Press.
From the April 2002 issue of MSDN Magazine