Sunday, November 27, 2005

What Are the Benefits of Generics?

Generics offer significant benefits, including productivity, type safety and performance.

What is special about generic types is that you code them once, yet you can use them with different parameters. Doing so has significant benefits—you reuse your development and testing efforts, without compromising type safety and performance, and without bloating your code.

With the object-based solutions, mismatch in type will still get complied, but yield an error at runtime. With generics, such code would never get compiled.

Various benchmarks have shown that in intense calling patterns, generics yield on average 200 percent performance improvement when using value types, and some 100 percent performance improvement when using reference types. However, performance is not the main benefit of generics. In most real-life applications, bottle necks such as I/O will mask out any performance benefit from generics. The most significant benefit of generics is type-safety.

Adopted from Generics FAQ: Fundamentals by Juval Lowy.

How Are Generics Implemented?

Generics have native support in IL and the CLR itself. When you compile generic server-side code, the compiler compiles it into IL, just like any other type. However, the IL only contains parameters or place holders for the actual specific types. In addition, the metadata of the generic server contains generic information such as constraints.

The client-side compiler uses that generic metadata to support type safety. When the client provides a type arguments, the client's compiler substitutes the generic type parameter in the server metadata with the specified type. This provides the client's compiler with type-specific definition of the server, as if generics were never involved. At run time, the actual machine code produced depends on whether the specified types are value or reference type.

If the client specifies a value type, the JIT compiler replaces the generic type parameters in the IL with the specific value type, and compiles it to native code. However, the JIT compiler keeps track of type-specific server code it already generated. If the JIT compiler is asked to compile the generic server with a value type it has already compiled to machine code, it simply returns a reference to that server code. Because the JIT compiler uses the same value-type-specific server code in all further encounters, there is no code bloating.

If the client specifies a reference type, then the JIT compiler replaces the generic parameters in the server IL with object, and compiles it into native code. That code will be used in any further requests for a reference type instead of a generic type parameter. Note that this way the JIT compiler only reuses actual code. Instances are still allocated according to their size off the managed heap, and there is no casting.

Adopted from Generics FAQ: Fundamentals by Juval Lowy.

Saturday, November 26, 2005

Protected Directories in ASP.NET

By default, ASP.NET 2.0 will block access to all URLs that contain directory segments named App_Data, App_Code, App_Browsers, App_WebReferences, App_GlobalResources, and App_LocalResources anywhere in the URL. ASP.NET 1.1 and 2.0 will both also block access to the /Bin directory. This support is conditional on having the aspnet_filter.dll ISAPI filter registered with IIS, which is done by default during ASP.NET installation. By placing your content in these directories, you can prevent HTTP access to it regardless of the file extensions being requested.

Adopted from Are You Protected? Design and Deploy Secure Web Apps with ASP.NET 2.0 and IIS 6.0 by Michael Volodarsky.

Protecting Resources in IIS

Here are some rules/methods regarding how to protect resources in IIS 6.0 (adopted from Michael Volodarsky's article Are You Protected? Design and Deploy Secure Web Apps with ASP.NET 2.0 and IIS 6.0:
  • If your application is programmatically accessing data or supporting files during its execution, you should place them outside the Web namespace.
  • If you cannot remove all such files, make sure that IIS is configured not to serve these files to Web clients. This should be accomplished by mapping the extensions for the protected files to ASP.NET in the IIS script processor map configuration, and subsequently mapping those extensions to the HttpForbiddenHandler or HttpNotFoundHandler in the ASP.NET configuration for the application or directory. By default, ASP.NET already blocks access to a number of extensions common to Web applications, including .cs, .java, .mdb, .mdf, .vb, and others.
  • If you use the IIS static file handler, you should also make the files hidden for additional protection because the IIS static file handler will not serve files that have been given the hidden attribute.

It is frequently thought that removing a corresponding extension entry from the IIS MIME mapping configuration will prevent the static file handler from serving files with that extension. In actuality this is not always true because the static file handler will also honor the registry MIME mapping configuration and therefore will still serve the extension if the registry entry is present. Because of this, you would have to make sure that both the metabase MIME mapping configuration and the registry key in HKEY_CLASSES_ROOT do not contain an extension entry for the forbidden extension. Due to the management complexity, this practice is not recommended as a way of securing content.

Of course, this guidance regarding the IIS static file handler only applies to extensions that are not mapped to an ISAPI extension in the IIS script mapping configuration.

Friday, November 25, 2005

Accessing Files in IIS 6.0

What are the operations in order performed by IIS 6.0 if you launch IE to send a request via the URL http://myServer/myApp/test.xyz?

Here is what I found by performing some testing. I might be wrong at some points. So be cautious.
  • IIS performs authentication/authorization. If it fails at this step, a HTTP Error 401.1 is returned.
  • IIS does MINE maps.
  • IIS 6.0 will not deliver content for which there is no MIMEMap entry at the Computer level and in the registry MIME mapping configuration. In this case, a HTTP Error 404 is returned and a HTTP Error 404.3 is logged.
  • If there is no MIMEMap entry at myApp (site) level and there is a MIMEMap entry at the Computer level or in the registry MIME mapping configuration, then the request will be processed by the IIS static file handler.
  • If there is a MIMEMap entry at myApp (site) level, then the ISAPI extension in the corresponding IIS script mapping will be responsible for processing the request. Assume that this is the case by now.
  • IIS starts to check "Execution Permission" on the Virtual Directory tab of the Properties dialog box. If "Execution Permission" is not allowed to process the request, a HTTP Error 403.1 is returned.
  • Next IIS starts to check "Web Service Extensions". If there is a corresponding Web Service Extension and the Web Service Extension is prohibited, then a HTTP Error 404 is returned and a HTTP Error 404.2 is logged.
  • Now IIS starts to load the ISAPI extension in the corresponding IIS script mapping to process the request.
Recently I read the following two articles regarding to IIS security:

Neither articles are made clear on MIMEMaps. Michael's article is excellent except the tiny thing on MIMEMaps. Every developer working on ASP.NET and IIS should read this article.

Sunday, November 20, 2005

WinForms 2.0 resources

The WinForms team has put up all kinds of WinForms 2.0 resources, including a bunch of FAQs and samples.

Adopted from Chris Sells's post.

Monday, November 14, 2005

NegotiateStream

As SDK states, using NegotiateStream, you can do the following.
  • Send the client's credentials to the server for Impersonation or Delegation.
  • Request server authentication.
  • Encrypt and/or sign data before transmitting it.

If you want CIA protection, the client must first call AuthenticateAsClient and the server must call AuthenticateAsServer. Both calls block. If you miss one on one side, then you are not able to use NegotiateStream on this side and the other side is blocked. As Keith Brown points out, these functions map down to SSPI's InitializeSecurityContext and AcceptSecurityContext, and basically implement an authenticated key exchange using a protocol called SPNEGO, which stands for "secure, protected negotiation."

The client should also specify a service princpal name (SPN) if its wants to use Kerberos.

Sunday, November 13, 2005

WindowsIdentity.Groups

WindowsIdentity.Groups can be used to display the list of groups that an account belongs to. The following code enumerates the group list and displays both the group name and SID.

WindowsIdentity wi = WindowsIdentity.GetCurrent();
foreach (IdentityReference id in wi.Groups)
{
Console.WriteLine(@" {0}, {1}",
((NTAccount)((SecurityIdentifier)id).Translate(typeof(NTAccount))).Value,
id.Value);
}

However, this property is buggy. So be cautious to use it. I found strange (wrong) behaves.

  1. If you list the groups that Network Service or Local Service belongs to, you get two Users groups with the same SID.
  2. If you create a local normal user named tmpUser and then remove it from the Users group, then you log out and relog in your system, and then launch your app under the tmpUser account to display the list of groups that it belongs to. You'll find that the Users group still shows up in the list!

Saturday, November 12, 2005

Thread.CurrentPrincipal in .NET Framework 2.0

Thread.CurrentPrincipal is simply a helpful property for keeping track of a principal, and is primarily used in server applications to track client identity. As Keith Brown pointed out that
Thread.CurrentPrincipal propagates during asynchronous activities such as asynchronous delegates and creating new threads, but doesn't propagate during ThreadPool.QueueUserWorkItem and System.Threading.Timer, in .NET Framework 1.1.

I found that
Thread.CurrentPrincipal propagates during
ThreadPool.QueueUserWorkItem in .NET Framework 2.0.

Upgrade to .NET Framework 2.0

Our company has an application built and running against .NET Framework 1.1. The client side is a Windows Forms control embedded in IE. So the client requires .NET Framework. The control makes Web service calls to a Web server and Web services make ADO.NET calls to a SQL Server database.

Recently I tested the app under .NET Framework 2.0 with all the combinations: client 1.1 + server 2.0, client 2.0 + server 1.1, client 2.0 + server 2.0. It worked very well and no change was made. Amazing!

I found that MSDN documentation in this area is very poor. So I record a couple of things that I feel useful. Assume that .NET Framework 2.0 is installed on top of an existing .NET Framework 1.1.
  • IE always loads .NET Framework 2.0 no matter which version of .NET Framework your Windows Forms control is built against if both 2.0 and 1.1 are present. This is against .NET rule. The rule says that, if the version of the .NET Framework that the application was built against is present on the computer, the application runs on that version. Our control was built against .NET 1.1, but .NET 2.0 was loaded by IE instead of .NET 1.1.
  • If .NET 2.0 is installed on top of .NET 1.1, the combo box on the ASP.NET tab in IIS will contain two entries: .NET 2.0 and .NET 1.1. But .NET 1.1 remains the default. This is very good because it causes the least pain when upgrading of servers. If you want to run your Web app against .NET 2.0, then you need to change the framework version to 2.0 on the ASP.NET tab.

Tuesday, November 08, 2005

Watching the First XAML Presentation

I read a couple of Chris Sells's articles on Longhorn two years ago, but I never had chance to watch presentations on Avalon and try Avalon myself. Gary Fuhr gave a presentation on XAML yesterday at .NET Developers Association. WPF is cool! It seems to me that it's not hard for an experienced WinForm developer to work with WPF.

Many Windows developers like me are not good at graphic design. We spent most of our time on how to wire things up using frameworks provided by Microsoft. WPF provides much more ways to create much cooler graphics and graphic design is tougher than before. We (Windows developers) really need an easy-to-use graphic design tool to help us. After done with graphic design using the tool, the tool should be able to export XAML for us to use in VS .NET.