Showing posts with label .NET Framework. Show all posts
Showing posts with label .NET Framework. Show all posts

Saturday, January 30, 2010

Authentication

Security is one of the most important concerns in application software development. Building a robust security model is one of the most important factors that drive the success of application software. As far as security in ASP.NET is concerned, three terms come into my mind, i.e., Authentication, Authorization and Impersonation. Put simply, authentication authenticates the user’s credentials and authorization relates to the resources that an authenticated user has access to. This article is the first in a series of articles on ASP.NET security and discusses these concepts and their applicability.
Let us start our discussion with a brief outline on the sequence of events are as far as authentication and authorization are concerned when a new request comes in. When a new request arrives at IIS, it first checks the validity of the incoming request. If the authentication mode is anonymous (default) then the request is authenticated automatically. But if the authentication mode is overridden in the web.config file settings, IIS performs the specified authentication check before the request is passed on to ASP.NET.

Authentication
Authentication determines whether a user is valid or not based on the user’s credentials. Note that a user can be authorized to access the resources provided the user is an authenticated user. The application’s web.config file contains all of the configuration settings for an ASP.NET application. An authentication provider is used to prove the identity of the users in a system. There are three ways to authenticate a user in ASP.NET:
Forms authentication
Windows authentication
Passport authentication

  Forms Authentication
This is based on cookies where the user name and the password are stored either in a text file or a database. It supports both session and persistent cookies. After a user is authenticated, the user’s credentials are stored in a cookie for use in that session. When the user has not logged in and requests for a page that is secured, he or she is redirected to the login page of the application. The following code snippet illustrates how this can be implemented in ASP.NET.


 Windows Authentication
Windows Authentication is used to validate a user based on the user’s Windows Account; however, this is only applicable in intranet environments where the administrator has full control over the users in the network. The following code snippet illustrates how we can implement Windows Authentication in ASP.NET.

Passport Authentication
Passport authentication is a centralized authentication service that uses Microsoft’s Passport Service to authenticate the users of an application. It allows the users to create a single sign-in name and password to access any site that has implemented the Passport single sign-in (SSI) service. The following code snippet illustrates how we can implement Passport Authentication in ASP.NET.
  
Authorization
Authorization is the process of determining the accessibility to a resource for a previously authenticated user. Note that authorization can only work on authenticated users, hence ensuring that no un-authenticated user can access the application. The syntax for specifying authorization in ASP.NET is as follows.

< [ allow | deny ] [ users ] [ roles ] [ verbs ] />


In ASP.NET, there are the following types of authorizations.
URL Authorization
File Authorization
Authorization based on ACL (Access Control List)

Impersonation
According to MSDN, “When using impersonation, ASP.NET applications can optionally execute with the identity of the client on whose behalf they are operating. The usual reason for doing this is to avoid dealing with authentication and authorization issues in the ASP.NET application code. Instead, you rely on Microsoft Internet Information Services (IIS) to authenticate the user and either pass an authenticated token to the ASP.NET application or, if unable to authenticate the user, pass an unauthenticated token. In either case, the ASP.NET application impersonates whichever token is received if impersonation is enabled. The ASP.NET application, now impersonating the client, then relies on the settings in the NTFS directories and files to allow it to gain access, or not. Be sure to format the server file space as NTFS, so that access permissions can be set”.
Note that Impersonation is disabled by default and can be specified in the web.config file as shown in the code snippet given below.
or
To impersonate a particular identity, specify the following in your application’s web.config file.


Hungarian Notation

Hungarian notation is the system used by most C and C++ developers (including those at Microsoft). It's a complete naming system created by Microsoft Distinguished Engineer Charles Simonyi. Back in the early 1980s, Microsoft adopted this famous-or infamous, depending on your point of view-naming system based on ideas from Simonyi's doctoral thesis, "Meta-Programming: A Software Production Method." -
Hungarian notation specifies that a prefix be added to each variable to indicate its type. However, not every type was given a standard prefix. In addition, as other languages were introduced and new types created, new prefixes had to be created. This is why even if you go into a shop that employs Hungarian notation, you might see some prefixes you're not accustomed to seeing. (By the way, the term "Hungarian notation" comes from the fact that the prefixes make the variables look as if they are written in a language other than English; plus, Mr. Simonyi is from Hungary.) -
Perhaps the most important publication that encouraged the use of Hungarian notation was the first book read by almost every Windows and OS/2 developer: Charles Petzold's Programming Windows (Microsoft Press), which used a dialect of Hungarian notation throughout its demo applications. In addition, Microsoft employed the notation in its own development. When MFC was released, a bunch of new prefixes specific to C++ development were released with its source code, thereby guaranteeing the continued use of Hungarian notation.
So why not simply continue using Hungarian notation? Because Hungarian notation is useful in situations where it's beneficial to know the type, or scope, of a variable being used. However, as you'll see in more detail in the next chapter, all types in C# are objects and based on the .NET System.Object class. Therefore, all variables have a basic set of functionality and behavioral characteristics. For this reason, the need for Hungarian notation is lessened in the .NET environment.
NOTE
For the curious, or for those suffering from insomnia, the original paper that presented Hungarian notation can be found at http://msdn.microsoft.com/library/techart/hunganotat.htm.

Interoperability with Unmanaged Code

As you might suspect, unmanaged code is code that isn't controlled by the .NET runtime. Let's be clear about something: this code is still run by the .NET runtime. However, unmanaged code doesn't have the advantages that managed code has, such as garbage collection, a unified type system, and metadata. You might wonder why anyone would want to run unmanaged code in the .NET environment. Well, you wouldn't do it out of choice. Rather, you would do it when faced with circumstances that offer few alternatives. Here are some situations that will make you thankful Microsoft put this feature into .NET: -
  • Managed code calling unmanaged DLL functions Let's say your application needs to interface to a C-like DLL and the company that wrote the DLL isn't adopting .NET as quickly as your company is. In this case, you still need to call into that DLL from a .NET application. I'll cover this very example in Chapter 16, "Querying Metadata with Reflection."
  • Managed code using COM components For the same reason that you might need to continue supporting the ability to call a C-like DLL's functions from your .NET application, you might also need to continue supporting COM components. You do this by creating a .NET wrapper for the COM component so that the managed client thinks it's working with a .NET class. This is also covered in Chapter 16.
  • Unmanaged code using .NET services This is exactly the reverse problem-you want to access .NET from unmanaged code. It's solved using a reciprocal approach: a COM client is fooled into thinking it's using a COM server, which is actually a .NET service of some sort.

Deployment

Deployment is, by far, the most gruesome task associated with developing extremely large distributed systems. In fact, as any Windows developer can tell you, dealing with the different binary files, Registry issues, COM components, and support library installation of products such as open database connectivity (ODBC) and Data Access Objects (DAO) is enough to make you rethink your career choice. Thankfully, deployment is an area where the .NET design team obviously spent a lot of time.
The key to .NET application deployment is the concept of assemblies. Assemblies are simply packages of semantically related behavior that are built as either single-file or multiple-file entities. The specifics of how you deploy yourapplication will vary based on whether you're developing a Web server application or a traditional desktop application for Windows. However, with the introduction of the assembly as a fully encapsulated set of functionality, deployment can be as simple as copying the necessary assemblies to a target location.
Many of the problems that caused so much trouble for programmers prior to the .NET Framework have now been eliminated. For example, there's no need to register components-as you do with COM components and Microsoft ActiveX controls-because with metadata and reflection, all components are self-describing. The .NET run time also keeps track of the files, and the versions of the files, associated with an application. Therefore, any application that is installed is automatically associated with the files that are part of its assembly. If a setup application attempts to overwrite a file needed by another application, the .NET runtime is smart enough to allow the setup application to install the needed file, but the CLR doesn't delete the previous version of the file because it's still required by the first application.

Security

The most important facet of any distributed application development environment is how it handles security. Thankfully for those of us who have long complained that Microsoft would never be taken seriously in the server-side enterprise solutions space without a completely new approach to security, .NET brings many concepts to the table. In fact, security begins as soon as a class is loaded by the CLR because the class loader is a part of the .NET security scheme. For example, when a class is loaded in the .NET runtime, security-related factors such as accessibility rules and self-consistency requirements are verified. In addition, security checks ensure that a piece of code has the proper credentials to access certain resources. Security code ensures role determination and identity information. These security checks even span process and machine boundaries to ensure that sensitive data is not compromised in distributed computing environments.

Metadata and Reflection

As I mentioned in the earlier section "Microsoft Intermediate Language and the JITters," the CLS-compliant compilers take your source code as input and produce MSIL code for the runtime to compile (via the JITters) and execute. In addition to mapping source code to MSIL instruction sequences, CLS-compliant compilers have another equally important task: embedding metadata into the resulting EXE.
Metadata is data that describes data. In this context, metadata is the collection of programmatic items that constitute the EXE, such as the types declared and the methods implemented. If this sounds vaguely familiar, it should. This metadata is similar to the type libraries (typelibs) generated with Component Object Model (COM) components. Not only is the metadata output from a .NET compiler substantially more expressive and complete than the COM typelibs we're accustomed to, but the metadata is also always embedded in the EXE. This way, there's no chance of losing the application's metadata or having a mismatched pair of files.
The reason for using metadata is simple. It allows the .NET runtime to know at run time what types will be allocated and what methods will be called. This enables the runtime to properly set up its environment to more efficiently run the application. The means by which this metadata is queried is called reflection. In fact, the .NET Framework class libraries provide an entire set of reflection methods that enable any application-not just the CLR-to query another application's metadata.
Tools such as Visual Studio.NET use these reflection methods to implement features such as IntelliSense. With IntelliSense, as you type in a method name, that method's arguments pop up in a list box on the screen. Visual Studio.NET takes that functionality even further, showing all the members of a type. I'll discuss the reflection APIs in Chapter 15, "Multithreaded Programming."-
Another incredibly useful .NET tool that takes advantage of reflection is the Microsoft .NET Framework IL Disassembler (ILDASM). This powerful utility parses the target application's metadata and then displays information about the application in a treelike hierarchy.

Unified Type System

One of the key features of any development environment is its type system. After all, a development environment with a limited amount of types or a system that limits the programmer's ability to extend the system-supplied types isn't an environment with a long life expectancy. The .NET runtime does more than just give the developer a single, unified type system that is used across all CLS-compliant languages. It also lets language writers extend the type system by adding new types that look and act just like the system built-in types. This means that you, as a developer, can use all typesin a uniform manner, regardless of whether they are .NET predefined types or user-created types. I'll discuss the details of the type system and how the C# compiler supports it in Chapter 4, "The Type System." -

Microsoft Intermediate Language and the JITters

To make it easy for language writers to port their languages to .NET, Microsoft developed a language akin to assembly language called Microsoft intermediate language (MSIL). To compile applications for .NET, compilers take source code as input and produce MSIL as output. MSIL itself is a complete language that you can write applications in. However, as with assembly language, you would probably never do so except in unusual circumstances. Because MSIL is its own language, each compiler team makes its own decision about how much of the MSIL it will support. However, if you're a compiler writer and you want to create a language that does interoperate with other languages, you should restrict yourself to features specified by the CLS.
When you compile a C# application or any application written in a CLS-compliant language, the application is compiled into MSIL. This MSIL is then further compiled into native CPU instructions when the application is executed for the first time by the CLR. (Actually, only the called functions are compiled the first time they are invoked.) However, since we're all geeks here and this book is called Inside C#, let's look at what's really happening under the hood: -
  1. You write source code in C#.
  2. You then compile it using the C# compiler (csc.exe) into an EXE.
  3. The C# compiler outputs the MSIL code and a manifest into a read-only part of the EXE that has a standard PE (Win32-portable executable) header.
  4. So far, so good. However, here's the important part: when the compiler creates the output, it also imports a function named _ CorExeMain from the .NET runtime.
  5. When the application is executed, the operating system loads the PE, as well as any dependent dynamic-link libraries (DLLs), such as the one that exports the _ CorExeMain function (mscoree.dll), just as it does with any valid PE.
  6. The operating system loader then jumps to the entry point inside the PE, which is put there by the C# compiler. Once again, this is exactly how any other PE is executed in Windows.
  7. However, since the operating system obviously can't execute the MSIL code, the entry point is just a small stub that jumps to the _ CorExeMain function in mscoree.dll.
  8. The _ CorExeMain function starts the execution of the MSIL code that was placed in the PE.
  9. Since MSIL code cannot be executed directly-because it's not in a machine-executable format-the CLR compiles the MSIL by using a just-in-time (JIT) compiler (or JITter) into native CPU instructions as it processes the MSIL. JIT compiling occurs only as methods in the program are called. The compiled executable code is cached on the machine and is recompiled only if there's some change to the source code.
Three different JITters can be used to convert the MSIL into native code, depending on the circumstances: -
  • Install-time code generation Install-time code generation will compile an entire assembly into CPU-specific binary code, just as a C++ compiler does. An assembly is the code package that's sent to the compiler. (I'll talk about assemblies in more detail later in this chapter in "Deployment.") This compilation is done at install time, when the end user is least likely to notice that the assembly is being JIT-compiled. The advantage of install-time code generation is that it allows you to compile the entire assembly just once before you run it. Because the entire assembly is compiled, you don't have to worry about intermittent performance issues every time a method in your code is executed the first time. It's like a time-share vacation plan in which you pay for everything up front. While paying for the vacation plan is painful, the advantage is that you never have to worry about paying for accommodations again. When and if you use this utility depends on the size of your specific system and your deployment environment. Typically, if you're going to create an installation application for your system, you should go ahead and use this JITter so that the user has a fully optimized version of the system "out of the box."
  • JIT The default JITter is called at run time-in the manner I described in the preceding numbered list-each time a method is invoked for the first time. This is akin to a "pay-as-you-go" plan and is the default if you don't explicitly run the PreJIT compiler.
  • EconoJIT Another run-time JITter, the EconoJIT is specifically designed for systems that have limited resources-for example, handheld devices with small amounts of memory. The major difference between this JITter and the regular JITter is the incorporation of something called code pitching. Code pitching allows the EconoJIT to discard the generated, or compiled, code if the system begins to run out of memory. The benefit is that the memory is reclaimed. However, the disadvantage is that if the code being pitched is invoked again, it must be compiled again as though it had never been called.

The .NET Framework Class Libraries

The .NET Framework class libraries are monumentally important to providing language interoperability because they allow developers to use a single programming interface to all the functionality exposed by the CLR. If you've ever used more than one dissimilar language in development for Windows, you'll love this feature. In fact, the .NET Framework class libraries are forging a revolutionary trend in compiler development. Before .NET, most compiler writers developed a language with the ability to do most of its own work. Even a language such as C++, which was designed as a scaled-down grouping of functionality to be used in conjunction with a class library, has at least some functionality on its own. However, in the world of .NET, languages are becoming little more than syntactical interfaces to the .NET Framework class libraries.
As an example, let's first take a look at the standard "Hello, World" application in C++ and then compare it to an application that does the same thing in C#: -
#include 

int main(int argc, char* argv[])
{
    cout << "Hello, World!" << endl;
    return 0;
}
Notice that the application first includes a header file with the declaration of the cout function. The application's main function-every C/C++ application's entry point-uses the cout function to write the string "Hello, World" to the standard output device. However, what's important to note here is that you can't write this application in any .NET language without the .NET Framework class libraries. That's right: .NET languages don't even have the most basic compiler features, such as the ability to output a string to the console. Now I know that technically the cout function is implemented in the C/C++ runtime, which is itself a library. However, basic C++ tasks such as string formatting, file I/O, and screen I/O are at least logically considered part of the base language. With C#-or any .NET language for that matter-the language itself has almost no ability to do even the most menial task without the .NET Framework class library.
Let's look at the "Hello, World" example in C# to see what I mean: -
using System;

class Hello
{
    public static void Main()
    {
        Console.WriteLine("Hello, World");
    }
}
So, what does this common set of class libraries mean to you, and is it a good thing? Well, it depends on your vantage point. A common set of class libraries means that all languages, theoretically, have the same capabilities because they all have to use these class libraries to accomplish anything except declaring variables.
One gripe I've seen on discussion boards is, "Why have multiple languages if they all have the same capabilities?" For the life of me, I don't understand this complaint. As someone that has worked in many multilanguage environments, I can attest that there's a great benefit to not having to remember what language can do what with the system and how it does it. After all, our job as developers is to produce code, not to worry about whether a favorite language has this advantage or that advantage.
Another question I've seen frequently is, "If all these .NET languages can do the same thing, why do we need more than one?" The answer relates to the fact that programmers are creatures of habit. Microsoft certainly didn't want to pick one language out of the many available and force millions of programmers to toss out their years of experience in other languages. Not only might a programmer have to become familiar with a new API, he or she might have to master a completely different syntax. Instead, a developer can continue using the language that's best suited for the job. After all, the name of the game is productivity. Changing what doesn't need to be changed is not part of that equation.
NOTE
While in theory the .NET Framework class libraries enable compilers to make all the CLR's functionality available to a language's users, this is not always the case. One point of contention at Microsoft between the .NET Framework class libraries team and the different compiler teams is that although the .NET Framework class libraries team has attempted to expose all its functionality to the different languages, there's nothing-besides meeting minimal CLS standards-that requires the different compiler teams to implement every single feature. When I asked several Microsoft developers about this discrepancy, I was told that instead of each language having access to every exposed bit of .NET Framework functionality, each compiler team has decided to implement only the features that they feel are most applicable to their users. Luckily for us, however, C# happens to be the language that seems to have provided an interface to almost all of the .NET Framework functionality.

The Common Language Runtime

The CLR is the very core of .NET. As the name suggests, it is a run-time environment in which applications written in different languages can all play and get along nicely-otherwise known as cross-language interoperability. How does the CLR provide this cozy environment for cross-language interoperability? The Common Language Specification (CLS) is a set of rules that a language compiler must adhere to in order to create .NET applications that run in the CLR. Anyone, even you or me, who wants to write a .NET-compliant compiler needs simply to adhere to these rules and, voila!, the applications generated from our compilers will run right alongside any other .NET application and have the same interoperability.
An important concept related to the CLR is managed code. Managed code is just code that is running under the auspices of the CLR and is therefore being managed by the CLR. Think of it like this: In today's Microsoft Windows environments, we have disparate processes running. The only rule that applications are required to follow is that they behave well in the Windows environment. These applications are created by using one of a multitude of completely dissimilar compilers. In other words, the applications have to obey only the most general of rules to run under Windows.
The Windows environment has few global rules regarding how the applications must behave in terms of communicating with one another, allocating memory, or even enlisting the Windows operating system to do work on their behalf. However, in a managed code environment, a number of rules are in place to ensure that all applications behave in a globally uniform manner, regardless of the language they were written in. The uniform behavior of .NET applications is the essence of .NET and can't be overstated. Luckily for you and me, these global rules primarily affect the compiler writers.

The Microsoft .NET Platform

The idea behind Microsoft .NET is that .NET shifts the focus in computing from a world in which individual devices and Web sites are simply connected through the Internet to one in which devices, services, and computers work together to provide richer solutions for users. The Microsoft .NET solution comprises four core components: -
  • .NET Building Block Services, or programmatic access to certain services, such as file storage, calendar, and Passport.NET (an identity verification service).
  • .NET device software, which will run on new Internet devices.
  • The .NET user experience, which includes such features as the natural interface, information agents, and smart tags, a technology that automates hyperlinks to information related to words and phrases in user-created documents.
  • The .NET infrastructure, which comprises the .NET Framework, Microsoft Visual Studio.NET, the .NET Enterprise Servers, and Microsoft Windows.NET.
The .NET infrastructure is the part of .NET that most developers are referring to when they refer to .NET. You can assume that any time I refer to .NET (without a preceding adjective) I'm talking about the .NET infrastructure. The .NET infrastructure refers to all the technologies that make up the new environment for creating and running robust, scalable, distributed applications. The part of .NET that lets us develop these applications is the .NET Framework.
The .NET Framework consists of the Common Language Runtime (CLR) and the .NET Framework class libraries, sometimes called the Base Class Library (BCL). Think of the CLR as the virtual machine in which .NET applications function. All .NET languages have the .NET Framework class libraries at their disposal. If you're familiar with either the Microsoft Foundation Classes (MFC) or Borland's Object Windows Library (OWL), you're already familiar with class libraries. The .NET Framework class libraries include support for everything from file I/O and database I/O to XML and SOAP. In fact, the .NET Framework class libraries are so vast that it would easily take a book just to give a superficial overview of all the supported classes.
As a side note (as well as an admission of my age), when I use the term "virtual machine," I don't mean the Java Virtual Machine (JVM). I'm actually using the traditional definition of the term. Several decades ago, before Java was anything more than another word for a dark, hot beverage, IBM first coined "virtual machine." A virtual machine was a high-level operating system abstraction within which other operating systems could function in a completely encapsulated environment. When I refer to the CLR as a kind of virtual machine, I'm referring to the fact that the code that runs within the CLR runs in an encapsulated and managed environment, separate from other processes on the machine.

Thursday, May 7, 2009

ASP.NET 1.1 vs 2.0

he latest version of ASP.NET, 2.0, is more than an upgrade—it is a major update of the technology, as it changes the way ASP.NET applications are designed, compiled, and deployed. Microsoft does recognize the existence of a large number of ASP.NET 1.1 installations, so 2.0 was designed to allow older applications to work without problems. On the other hand, the need to convert existing applications to the 2.0 platform may arise. With that said, let's examine the major differences between the versions, as well as areas that may be problems during the conversion process.Version changesWhile there are many changes between ASP.NET 1.1 and 2.0, there are certain ones that have a greater impact of
  • Code-behind model: ASP.NET 2.0 introduces the concept of partial classes, whereas a class can span multiple class files. It is a key feature used in Visual Studio 2005 to separate system-generated code from user code. This negates the scenario where you find yourself scrolling through source code and encountering the code generated by the system. The partial class approach reduces the risk of inadvertently editing system code and results in smaller code-behind files.
  • Directories: ASP.NET 2.0 has added a number of special directories where 1.1 had only the one required bin directory. Most of these new directories have the App_ prefix with names like App_Code, App_Data, App_GlobalResources, and App_LocalResources, while the bin directory still exists along with a themes directory. The new directories are a key aspect of 2.0's elimination of project files.
  • No more project files: Gone are the days of project files with ASP.NET and Visual Studio 2005. The project is now the complete Web project directory, which is a drastic shift from 1.1 and can cause migration issues as described later.
  • Compilation model: With 1.1, all code was compiled into one assembly placed in the bin directory. With 2.0, the assembly is separated into multiple assemblies. These multiple assemblies may be created on-the-fly or precompiled. Examples of multiple assemblies are one assembly for each ASP.NET directory like App_Code and App_Data as well as individual assemblies for Web Forms, User Controls, and so forth. This is a major shift in the application structure; it offers more deployment options in how the application is delivered to the users.
  • Application deployment: The deployment of 1.1 applications was fairly straightforward as you moved the content files along with the necessary assembly files—it could easily be accomplished with a simple copy and paste with limited options. The 2.0 model provides various options for deploying an application. For instance, you may choose to precompile all code and deploy it or go the other way with no precompilation. Also, you can lock down deployed content files so no changes may be made after deployment (this is a major difference from 1.1).

The list provides a high-level view of the main differences between ASP.NET 1.1 and 2.0 and what can affect the conversion of an existing application to 2.0. Now let's take a closer look at possible problem areas.