Does that make all of you those freaky vampires?
Well, vampire or no, I'm going to be neighborly and reveal my hard earned knowledge of creating a COM object in .NET that can be called from classic ASP. This is really fun stuff, so hold on tight.
[Ed. Note fun = miserable and mind-numbingly frustrating]
So, my task was to create single sign-on between ASP.NET applications and classic ASP sites. These all reside in a single domain. I just had to create a COM object in .NET that would handle the ticket validation between the two technologies. This took me about two hours to hammer out.
Here we are days later, and I'm just getting to test the COM object.
Why the delay? Days and days of beating my head against the monitor screaming "why me!?! For God's sake, why me!?!"
First, here are the basic steps for creating a COM-callable object in .NET:
1. Create a class library.
2. Add the namespace System.Runtime.InteropServices to your class.
3. Add an interface that defines the properties and methods of your class (aka type).
4. Have your class implement the interface.
5. Decorate your class (type) with a ClassInterface attribute that has a value equal to ClassInterfaceType.None (this tells the Type Library Exporter (tlbexp.exe) to NOT create an interface…because we've already defined one, right?)
6. Decorate both the type and the interface with the attribute ComVisible and set that equal to true. You'll also want to decorate any public property, method, enum, etc. with the same. You can also set this to false if you want a property or method to NOT be visible to COM.
7. Be sure to include a parameter-less default constructor. Sadly, I forgot this and caused myself a little grief for a while
Below is the code in action. But don't stop reading now. We aren't to the fun part (see Ed. Note above).
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Runtime.InteropServices;
namespace ComIsAuthume
{
[ComVisible(true)]
interface iTokenHandler
{
bool IsAuthenticated();
}
[ClassInterface(ClassInterfaceType.None),ComVisible(true)]
public class TokenHandler : iTokenHandler
{
public TokenHandler()
{
//this needs to be here and empty for COM
}
[ComVisible(true)]
public bool IsAuthenticated()
{
return true;
}
}
}
So…after you have done all this, you can compile and then run regasm to register your object (you can't use regsvr32 for managed code), like this
Regasm dllname.dll /codebase
After this, your object should be usable by classic ASP, right? Wrong! Before December 07, we could have stopped here. Unfortunately for me (and probably for you if you are reading this), there is more to do…and I have the secret.
In December 2007, MS was kind enough to release a security patch for IE - MS07 - 45 IE update. This handy update caused our managed COM object to not be usable via IIS 6.0. Why? It keeps the anonymous user from reading the registry settings required to see the object. Nice, eh?
So, until there is yet another update, here's what you need to do. Some people claim that you can just sign your object and shove it in the GAC. This didn't work for me. If that doesn't work for you, you'll need to find the registry settings via regedit, right click on them, select permissions from the context menu, and add the your anonymous account (IUSR blah blah)to have read access to the key. There are a few places to look in the registry, so don't stop with the first one you find. Just search for your dll name (without the extension) and grant read access to that user for each key found.
I hope you found this post helpful…and early so you don't waste a lot of time!
No comments:
Post a Comment