A couple of days ago a friend asked me a question about a problem he had with Windows Authentication and I thought I’d share some of the information about it.

They have an ASP.NET web application that have Windows authentication enabled. That application is accessing another server using an API. So far so good.

When they logged into the web application using Windows authentication, the credentials were automatically transfered and validated through IIS and the thread executing the current request was automatically impersonating using the credentials that were passed from the browser, but the call to the API within the application that accesses the other server failed.

This happens due to the fact that NTLM, the protocol that is used be default in Windows Authentication (and even used by default when installing a new domain server) does not support, due to various reasons, credentials delegation.

This means, that only the hop from the browser to the web server is supported and the credentials are not being transfered again from the web server to the other server through the API.

This will happen in every ASP.NET web application or web service that uses Windows authentication.

There is a nice post in this blog, that describes the problem as well as the possible solutions which includes (in a very short list):

  • Basic Authentication – An IIS feature that uses clear text over the wire to authenticate, which is not secure so consider using HTTPS to perform that.
  • Kerberos – a security protocol that is supported in Active Directory (Windows domains start are based on Windows 2000 and above). Kerberos is a bit annoying to configure, so it might not be the best possible solution (and sometimes your IT guys won’t even support it anyway).
  • Specify explicit credentials – This means that the second hop to the other server from the web server will always use the same predetermined fixed credentials. Sometimes you simply cannot do that, but that solely depends on your implementation.

The blog post also contains some links to knowledge base articles that can help you configure Kerberos as well as how to use explicit credentials.

On my previous post about the dubious “Ambiguous match found” exception, I talked about the fact that the ASP.NET runtime is case sensitive and if you are writing in C# you better be careful about how you name your private, protected and public variables.

Not so long ago, I’ve encountered another problem which is relatively similar. It manifests itself in the runtime but it is actually related to the ASP.NET compiler.

When first accessing an ASPX page in an application after the server was started, the ASP.NET runtime will try to compile that page. One of the first steps in doing so is to parse the ASPX page and figure out what controls were placed on it. It will then create these controls and the Page object behind the page and render the page outputting the result back to the client.

When the ASP.NET runtime tries to create the various controls placed on the ASPX page, it will use the GetType function, but for some reason, it will only pass the name of the control and not its full namespace.

In my case, we had a custom user control named HtmlAnchor which was suppose to overcome a few quirks with HTML anchors in some browsers. ASP.NET already contains a control named HtmlAnchor which its full namespace is System.Web.UI.HtmlControls.HtmlAnchor.
Our control, had no namespace, since we simply created a user control in our application.

Even though we didn’t use even a single System.Web.UI.HtmlControls.HtmlAnchor, but only our custom HtmlAnchor control we got a strange error about not being able to load a certain .NET assembly which was suppose to be generated when the page first renders to produce the page’s code cache.

I fired up WinDbg and when the exception occurs, search for objects of type CompilerError by issuing:

!dumpheap -type CompilerError

This will list all CompilerError objects in the heap. After that I issued:

!do 0xXXXXXX
Where 0xXXXX is the address of the CompilerError object that I’m inspecting (!do = !dumpobject)

And inside there is a private member that contains the error text which I also dumped (using !do).

The error that I saw was that .NET cannot cast HtmlAnchor (my HtmlAnchor) to System.Web.UI.HtmlControls.HtmlAnchor.

I issued “!clrstack -p” to see the call stack and the parameters that were passed to each function and along the way there was call to GetType with the name parameter that was equal to “HtmlAnchor”.

This was the problem. For some reason .NET figured out that my HtmlAnchor is suppose to be the HtmlAnchor the resides in System.UI.HtmlControls.

As it turns out, the namespace System.UI.HtmlControls is ALWAYS included when the ASP.NET compiler compiles an ASPX page and, for some reason, request the type of the object WITHOUT its full namespace and find the wrong HtmlAnchor even though I have a different TagPrefix for my HtmlAnchor in the ASPX page.

The is a combination of a number of problems.
First, when adding a user control to an ASP.NET web application, there is no specific namespace in the file. It will eventually get the namespace of ASP.XXXX when compiled using the ASP.NET compiler like the rest of the ASCX and ASPX pages.

I haven’t checked it for user controls that are not ASCX, meaning, someone wrote a control in some DLL and does get a namespace. The difference is that when including that control on an ASPX page we do provide the exact namespace and assembly, so it might works without a problem.

Second, if the user control has the same name as any of the control that are in the System.Web.UI.HtmlControls and System.Web.UI.WebControls namespaces, they will, for some reason, get loaded in GetType instead of your controls.

Third, in the @Register tag at the top of the page, where we declare and include our user control (we include the ASCX file), there is no additional information such as namespace to help the ASP.NET compiler resolve this issue.

Conclusion:

Be careful when you name your User Controls (ASCX controls) and make sure they do not have the same name as other controls in System.Web.UI.*.

Disclaimer: I usually like to keep this blog clean of link posts (posts that only have links to other posts in other blogs), but this time the information was too valuable so I had to make an exception.
Although this information is not exactly pure .NET debugging, it does have some information that can actually save you debugging time 🙂

Tess has some interesting tips that she expanded from a post her colleague Doug wrote about:

Read, learn and implement where needed.

A friend of mine, Eyal Post, whom I worked with in a previous company opened up a blog about two weeks ago (an DIDN’T let me know about it). I found out about it by looking at some stats of my blog and seeing that he linked to one of my posts about STA COM objects in .NET.

Eyal added some more important information and a solution to handling STA COM objects in ASP.NET Web Services and you can read all about it (and get the code) here.

Enjoy!

Oh, and Eyal, when you do something like that drop me a line in the Email 🙂

Everyone else probably wrote about it, so I thought I should write about it too 🙂

Dimitri from Microsoft released an RSS Toolkit for .NET that can be used to consume as well as generate RSS feeds.
You can read more about it in this post on his blog.

Dimitri is the development manager for ASP.NET and a great guy in general.

He actually made this hotfix for a company I used to work for (it was later integrated to one of the service packs of .NET framework v1.1, and I think its also included in .NET 2.0).

The whole ASP.NET threading model and how it works with Single Threaded Apartment (STA) COM objects is a good material for another post, so stay tuned 😉

Say you have an ASP.NET application with some code written in the ASPX pages themselves (I know its so ASP, but it happens sometimes 😉 ).
Say you need to update some of this code and change it, or you just want to extend an existing web application with some ASPX pages and you don’t want to get into a code-behind adventure.
Say that some of the code is giving you problems and you really want to debug it in a debugger and its not even a production environment and you even have Visual Studio installed.

What do you do?

System.Diagnostics.Debugger.Break();

That’s all.

This little line will pop up the dialog that you usually see when an error occured that is not handled and if you have a debugger installed, Windows will offer you to debug the problem.

Then you can simply select to open the debugger and debug your code.

Do mind that you’ll need to have the debug=”true” flag in your web.config (otherwise debug symbols will not be generated).

Easy, isnt’ it?! 🙂

Scott has a great post in his blog about how to share authentication between ASP.NET 1.1 and ASP.NET 2.0.

It’s useful for those of you who actually needs to be able to share the same authentication between an older ASP.NET 1.1 application and a new ASP.NET 2.0 application.

This article exposes some information I didn’t know (or didn’t want to know 😉 ).

First, ASP.NET 1.1 encrypted cookie uses the 3DES (a.k.a Triple DES) encryption. This key is per ASP.NET application (unless configured otherwise in the configuration).

According to the Scott’s post, ASP.NET 2.0 uses a stronger encryption (I assume AES since 3DES is AES predecessor).
Therefore, if you do use this feature mind that it will weaken your ecnrypted cookine in your ASP.NET 2.0 application.

While I usually don’t speak too much about performance, I’ve decided to write about this subject since I’ve stumbled upon it one time too many.

This issue was at the bottom of my post ideas list, but after seeing this article in ZDNet, I’ve decide to pay a bit more attention to this issue.

What’s Hyper-Threading?
Hyper-threading is Intel’s implementation for simultaneous multithreading, a technology that enables the processor to utilize empty cycles that are wasted when the currently running thread is waiting for a long operation such as RAM access or disk access.

While on paper this technology should speed up certain opeartions, in certain workload and certain scenarios of intensive server applications performance actually decreases.

A Sample Scenario
Let’s imagine the following scenario (which is very common to a lot of server applications).
Let’s say we have a few worker threads that are handling requests from clients. If too many requests are coming they are being queued.

Since this queue is shared among all threads and is accessed frequently, it will also be in the L1 or L2 cache of the CPU.

Now consider another different thread that is also running the background. It belongs to the application but it is not a worker thread that handles requests. It’s a thread that is being awakened periodically or by a trigger.
This thread runs and scans large chunk of the memory / objects / cache / (put your memory intensive task here) for changes. While it is running, sometimes getting some of those free cycles while one or more of the other worker threads are waiting for that operation, it will trash the L1 and L2 cache on the CPU due to the various tasks that its performing.

In that case, when the worker threads returns to work they try to access the memory that was previously in the L1 and L2 cache, but since the other non-worker thread trashed the cache we will get a cache miss that will cause us to fetch things from the RAM, or even worse, from the page file.
These operations will take instead of 2-4 cycles some where between 10-100 or even more cycles.

What actually happens is that in the L2 and L3 caches in the processor are being trashed whenever they switch to a different thread while the current one is waiting for some I/O operation.
This is specifically bad for applications such as ASP.NET and SQL Server.

ASP.NET and SQL Server
ASP.NET and SQL Server are two common server applications that use .NET (SQL Server 2005 hosts the CLR for stored procedures).

These two server applications are heavy on thread usage and since they both use the CLR (probably with the server GC) it means that they will have a GC thread per heap (and we have heap per Logical CPU) that the GC is being performed on them.
GC threads are memory intensive since they scan through all the memory of the generations being collected and traverse the various pointer to determine which objects are garbage or not.

In addition to the GC threads, SQL server has additional system threads running in the background that can also lead, in certain situations, to a decrease in performance.

While I’m not aware of system threads in ASP.NET, I know that some applications have additional threads running inside an ASP.NET which may cause them, in certain situations (of course), to suffer a decrease in performance.

You can read more about the effect Hyper-Threading has on SQL Server in this blog post by an MS developer.

So what should you do?
As I’ve said numerous times during this post, this behavior only happens in certain situations.
This means, that the best way of handling these issues is to stress test your application under high load with both Hyper-Threading enable and disabled.

Only then you will be able to determine if under the tested load Hyper-Threading is working with you or against you.

Server GC pre-allocation in Hyper-Threaded enabled environments
There is another benefit for disabling Hyper-Threading regarding the whole cache misses issues that we talked about above.

The Server version of the GC allocates a separate heap and a GC thread per Logical CPU. Hyper-Threading causes Windows to see a single physical Hyper-Threaded enabled CPU and 2 Logical CPUs (that’s one of the tricks that it uses to reschedule other threads for executions while others are waiting for their costly operations).
This means that, if you have a 2-CPU machine with Hyper-Threading enabled, upon starting your ASP.NET application (or any application that uses the Server GC) the GC will pre-reserve 64Mb x 4 CPUs = 256Mb of your virtual address space (which is 2Gb per process or 3Gb if you set the /3Gb flag in boot.ini).

If you have a memory intensive application that might be more than you need. By disabling Hyper-Threading you will be able to reduce that to 128Mb.

This is another factor one should consider when enabling or disabling Hyper-Threading.

Summary
The funny thing about Hyper-Threading and .NET is that I’ve found this post in MSDN saying that it can boost .NET and everything will be great and fine. The problem is that they neglected to mention some of the issues we’ve talked about here.