Resetting a website's AppDomain

by Thomas 27. August 2008 12:44
There are times when you want to forcefully reset a given website application's AppDomain. One specific scenario where this might happen is if you are storing application settings in a database as opposed to the web.config file. It turns out this is easy to accomplish by calling: System.Web.HttpRuntime.UnloadAppDomain();

SQL Voodoo

by Thomas 26. August 2008 11:49

I've often told my developers that throwing errors is a good thing. You want to know about errors when they occur or they will never get fixed. Obviously, that does not mean you should not handle errors, but a far worse situation is when something looks right. As someone once said, "It is not what you know that gets you in trouble; it is what you think you know".

Today I ran into something that is close to voodoo. I was reviewing some Classic ASP code (bleh, don't ask) that was making a SQL call. In this case, the user was populating a list of checkboxes with a guid ID value and a name and then taking the result list and passing it directly to SQL hoping that it would work like an IN clause. However, their code came out as something like:
"...Where ID = '{958BE980-9CA8-42C1-A4FA-998200CE2BAB}, {DD0A61EF-A5A0-45CA-B36F-998200CE2BAB}'"

Now, clearly this should not work as the string cannot be cast into a uniqueidentifier. Yet it does. It runs and returns values where the ID is equal to the first guid. That IMO is a bug in SQL Server. It should throw an error telling me that the string cannot be cast into a uniqueidentifier. The worst part is that developers will generally miss this error because something does come back and they do not get an error. If they don't get all the results they expect, they would likely chalk it up to missing data.

Visual Studio 2008 SP1- Make sure nothing Microsoft is running

by Thomas 25. August 2008 09:49

I tried running VS 2008 SP1 today. I also happened to be running Office and SQL Server. Clearly, that was a mistake as the installer took its requisite hour to install only to tell me it errored. So, I rebooted and tried it again with nothing Microsoft running and it worked fine. I know I'm shocked. One of my biggest annoyances with Microsoft is that many installers require seemingly unrelated applications to be closed. It is one of the reasons I switched to Firefox.

By the way, what is with having to run "SPInstaller.exe"? What happened to good ole' Setup.exe?

Multiple Applications with built-in MembershipProvider and RoleProvider Part II

by Thomas 23. August 2008 20:40

As I mentioned in an earlier post, the SqlRoleProvider is not really designed to work when the SqlMembershipProvider points to a different application. You would want to do such a thing if you were creating a suite of application sites for which you wanted a single user list but wanted each application to control its roles and role membership. The SqlRoleProvider and SqlMembershipProvider, worse that not providing this functionality, make you think it is provided by having an applicationName attribute on each one's configuration section. Alas, regardless of what you enter for the SqlMembershipProvider's applicationName, the RoleProvider's applicationName will always trump.

The solution I devised was to create a custom membership provider that derives from SqlMembershipProvider. I then overwrote the following methods:AddUsersToRoles, FinUsersInRole, GetRolesForuser, GetUsersInRole, IsUserInRole and RemoveUsersFromRoles. In addition, I copied the application stored procedures into renamed ones called aspnet_Custom_UsersInRoles_X where I allowed for both the UserApplicationName and the RoleApplicationName to be passed. 

The big advantage of going this route is that it makes it easier to combine the ActiveDirectoryMembershipProvider with the SqlRoleProvider in that you are inheritantly allowing for the two to come from different sources.

Passing RoleProvider roles to Classic ASP

by Thomas 23. August 2008 20:32

I struggled for a couple of days trying to work this one out. In short, we have a system which places a .NET veneer on top of ASP Classic to provide security. The trick in this scheme is to add a Wildcard mapping that points the the 2.0 aspnet_isapi.dll so that all requests are routed through .NET. Now, if you are using XP/2003 only, then one solution for then passing the roles to ASP Classic is to add a custom header in a .NET HttpModule. Unfotunately, in IIS7 (and thus Vista), it does not appear that you can add custom headers once you have the User principal instantiated. Ideally, you'd be able to do this in the PostAuthorize event but alas, it is not to be.

I tried numerous approaches and nothing seemed to work. In the end the solution was to create an HttpModule that wrote the username in plain text in a new cookie in the Response and to read that cookie from ASP Classic and use it to query for the Roles. Theoretically, the (more) ideal solution would be for ASP Classic to decrypt the FormsAuthentication cookie. However, to do that, you must read the site's Web.config file or the Machine.config file for the decryption key (and encryption algorithm). I had toyed with the idea of writing a .NET COM component that would do this, but it would still be a bear and I ran into issues getting the COM component to instantiate in ASP Classic (i.e. Server.CreateObject would sporatically throw an error). 

SQL Server 2005 Linked Server Error - "data that does not match expected data length"

by Thomas 23. August 2008 20:30
Ran into this error today while trying to do an import. The scenario is that I had a linked server to an MS Access database. After a bit of search and using the force, I discovered that the problem was due to fields set to an empty string as opposed to Null. Running a quick update query that set the given column value to Null where its length was less than one did the trick.

Multiple Applications with built-in MembershipProvider and RoleProvider

by Thomas 19. August 2008 23:10

The built-in RoleProvider has, IMO, a major flaw in its design.  Both the RoleProvider and the MembershipProvide allow for an "applicationName" attribute to be set. However, you quickly find out that when you have a RoleProvider configured, that the Membership static methods simply ignore the applicationName on the Membership provider and instead uses the applicationName from the RoleProvider. The assumption being that the source of the Roles is the same as the source for the Users. That's fine and dany when this assumption is true. However, what happens when you are say building a suite of applications that should each have their own roles, but you want to use a centralized list of users? An example, might be a suite of applications installed at a customer where the customer desires to use the ActiveDirectoryMembershipProvider.

As it stands now, the only way to accomplish this feat is to use AzMan for all of your applications. Unfortunately, AzMan is a bear to use and does not provide the ability to create a web interface whereby you can call AddUserInRoles. What the user really wants in this situation is the user search functionality so that they can search for users on their Active Directory domain. Of course you can do this via the AzMan mmc, but if you ever have to hand off your application for someone else to install, you quickly realize that you have to write a bazillion instructions for configuring AzMan which is a problematic pain in the neck (see Commerce Server 2007).

What would be peachy would be a way of using the SqlRoleProvider with ActiveDirectory. That is what I have worked together and I'll post the code in an ensuing post. However, in general the idea is to have a SqlRoleProvider that you use for all authorizations but allow for a different MembershipProvider for authentication and then store a flag which determines whether authenticated users should automatically be added to a given role in the SqlRoleProvider store.  In effect, you are always using the SqlRoleProvider but ensuring that authentication is always done via the cutomer's preferred MembershipProvider.

Forcefully kill a process

by Thomas 19. August 2008 19:39
One of the many useful tools that comes with the XP Support Tools is a utility called TaskKill. TaskKill lets you dump a process that refuses to let you kill it from the Task Manager. On occasion, I have run into processes that would throw an "Access is denied" error when I try to kill it from the Task Manager. Once you have installed the XP Support Tools and have it as part of your path, simply type taskkill /? to get more information.

Powered by BlogEngine.NET 1.5.0.7
Theme by Extensive SEO