IIS 7 and ASP.NET Providers (Membership, Roles, and Profile)
I talked at length about the ASP.NET Provider Model pattern and the ease of implementing several built-in services you can have for free with ASP.NET 2.0 in my previous series of posts. In this post, I will be discussing the advantages of using the ASP.NET Provider system under IIS 7 found in Windows Vista and Server 2008. I will also talk about an issue with using this Provider system to try and add authentication to an ASP.NET website that contains non-ASP.NET content, like static HTML pages. I think I’ll start with the discussion about non-ASP.NET content first.
IIS 7.0 Integrated Pipeline
Since I don’t really understand much about ISAPI filters and such, I’m just going to quote stuff from random pages on the official Microsoft IIS site:
"IIS 6.0 and previous versions allowed the development of .NET application components via the ASP.NET platform. ASP.NET integrated with IIS via an ISAPI extension, and exposed its own application and request processing model. This effectively exposed two separate server pipelines, one for native ISAPI filters and extension components, and another for managed application components. ASP.NET components would execute entirely inside the ASP.NET ISAPI extension bubble and only for requests mapped to ASP.NET in the IIS script map configuration.
"IIS 7.0 integrates the ASP.NET runtime with the core web server, providing a unified request processing pipeline that is exposed to both native and managed components known as modules."
and…
"This allows developers to fully extend the IIS 7.0 server with the richness of ASP.NET 2.0 and the .NET Framework, instead of using the lower level IIS C++ APIs. Existing ASP.NET applications also immediately benefit from tighter integration using existing ASP.NET features like Forms Authentication, Roles, and Output Caching for all content."
Note the last three words there: "for all content." When I started this endeavor to implement the ASP.NET Provider system, I didn’t realize that it would really only apply to ASP.NET content and pages. I didn’t realize on IIS 6 I would have to fiddle with ISAPI filters and content filters to make my implementation work. And when I tried to doing a mapping (like *.html to the ASP.NET ISAPI DLL), I either didn’t do it right or it just isn’t very reliable and stable; here is a link to the thread I followed in trying to make the appropriate changes in IIS 6. I will note however that UltiDev’s Cassini Web Server can host such a site with absolutely no extra modification, where even IIS 7 required a little configuration.
By default in IIS 7, an application pool runs using the Integrated mode for the Managed Pipeline configuration. But there is also the option of Classic mode, which is helpful if you are needing strict compatibility with how you ran a website under IIS 6. In many cases, however, an existing ASP.NET website runs under Integrated mode without any problems.
Configuring an ASP.NET Website to Run on IIS 7
First, I think I will point you to a great video and document on Microsoft’s official IIS site that explains everything you really need to know. Then I will emphasize a few of the important points and also a gotcha or two. Here are the links you should reference:
The video above is also a terrific introduction to IIS 7. Below is a screenshot of IIS’s UI for configuring a website:
Notice the ASP.NET section and how it’s able to use your Providers to bring back Users, Roles, and Profile data back from the database. This UI reads from and writes to your Web.config and is really slick in my opinion.
The only real "breaking change" for running your website under IIS 7 is the fact that your Web.config might need a little migration to be compatible with Integrated mode. Apparently IIS gives you helpful error messages if it detects you haven’t run through the migration yet. The two most common things that ASP.NET websites have that require this migration are if you have declared httpModules or httpHandlers in your Web.config. The fix is to either copy or move these sections under system.web to their corresponding system.webServer sections. If you duplicate the sections, then you should be able run under both Integrated and Classic modes without any problems. You can even still run on IIS 6 I believe, as IIS 6 will ignore this new section called system.webServer which is IIS 7 specific. IIS 7 even provides a utility that can perform this migration for you; here is the what you would type in a Command Prompt:
%windir%\system32\inetsrv\APPCMD.EXE migrate config <Application Path>
…where <Application Path> would be something like "Default Web Site/" or "Default Web Site/someApp". If you manually migrate your Web.config and are still getting migration error messages, here is a snippet you can add right under the system.webServer node to disable the error message:
<validation validateIntegratedModeConfiguration="false" />
Also, I want to make note of something I couldn’t get to work that they showed in the tutorial video. At about the 13:50 mark in the video, they go into the Modules section of the UI. These are the modules of the IIS pipeline for both managed .NET code and unmanaged code. In order to make their video file hidden behind ASP.NET Forms Authentication, they change a property on two authentication modules to allow these modules to execute on non-managed content as well. However, this did not work for me for some reason when I was trying to secure HTML pages behind Forms Authentication. What did work for me (and may have been a drastic solution) was to put the following attribute on the modules node under system.webServer:
<modules runAllManagedModulesForAllRequests="true" />
I believe the issue in my case was their was another few managed modules that I needed to clear that checkbox for in the UI. But I didn’t take the time to find out which ones I was missing and opted for the drastic solution. I will also say there is a way to configure these managed modules through your Web.config so you don’t have to have your IT Admin configure properties manually in the UI. In fact, it seems that much of IIS 7 configuration for your website can be done this way.
A Few Error Messages (and Their Solutions)
If you get error messages while using the IIS Manager user interface like this…
"This feature cannot be used because the default provider type could not be determined to check whether it is a trusted provider.
"You can use this feature only when the default provider is a trusted provider. If you are a server administrator, you can make a provider a trusted provider by adding the provider type to the trusted providers list in the Administration.config file. The provider has to be strongly typed and added to the GAC (Global Assembly Cache)."
…then you should visit the following article for detailed information about resolving the error message:
Getting rid of this error message is really only for convenience in letting the IIS Manager UI be able to query your database using your providers and give you a basic view of your Membership, Roles, and Profile fields. Also, if you are trying to find your Administration.config file, it is likely located under the C:\Windows\System32\inetsrv\config\ folder.
The other error message I received was not in the IIS Manager UI, but rather when you attempt to view your website in a browser (after you think you got all the configuration bugs out!). A BadImageFormatException is thrown and the error details say something like this:
Could not load file or assembly ‘AssemlyNameHere’ or one of its dependencies. An attempt was made to load a program with an incorrect format.
The likely cause of this error is that the assembly referenced in the error message was compiled only for 32-bit machines and you are running a 64-bit operating system. With Windows Server 2008 x64, the application pools in IIS have an Advanced Setting called Enable 32-Bit Applications, that is disabled by default. Enable this setting and you’re probably good to go. See the following link for more detailed information and some nice screenshots:
Additional Reading
I just barely noticed that 4GuysFromRolla.com recently posted an article about the exact same stuff I was attempting to explain. To read additional details about IIS 7’s Integrated Pipeline and ASP.NET Forms Authentication with static content, check out the following link:
Conclusion
I hope you’ve enjoyed this series on the ASP.NET Provider System. My desire is that you’ve found these posts helpful in getting you started with implementing such a versatile and customizable model for adding common membership and authorization functionality to your new and existing websites. There are quite a few advantages in hosting your site on IIS 7 in Windows Server 2008, as I’ve outlined in this specific post. Hopefully these discussions about errors and gotchas will also help you get going in no time!