Here is my best guess based upon what you've told us.

ASP.NET threads run inside of the MTA (multi-threaded aparment).

VB6 COM components must run inside on a thread that belongs to an STA
(single-threaded apartment).  So when your webmethod is called - it is
being called on an ASP.NET thread, which means COM with have to create
your COM instance on a different thread - which also means any
impersonating you are getting ASP.NET to do on your thread is not being
passed to the other thread.

With .aspx files, you can make the request run on an STA thread by
setting the AspCompat="true" - but AFAIK there is no property that will
make the asmx handler do the same.  This is one instance when you might
want to create a thread to pass this work off to - that way you can set
the apartmentstate before you start the thread:

                [WebMethod]
                public string GetApt(bool sta)
                {
                        if(!sta)
                        {
                                Thread t  = new Thread(new
ThreadStart(this.DiffThread));
                                t.ApartmentState  = ApartmentState.STA;
                                t.Start();
                                t.Join();
                        }
                        else
                                DiffThread();
                        return AptState;
                }
                string AptState;
                public void DiffThread()
                {
                        AptState =
System.Threading.Thread.CurrentThread.ApartmentState.ToString();

                }
If you can pass true to this method - the result should be that the new
thread has the same security context as the thread you just create.
Also make sure to accually deny (with the authorization element) access
to your .asmx file- or else ASP.NET will not even try to use the Token
that IIS is giving it (either the anonymous user or a specific
authenticated user).


It isn't changing to unmanaged code - it is the fact that your unmanaged
code is running on different thread.

Jon Flanders
[EMAIL PROTECTED]
"Display some adaptability."
Douglas MacArthur Shaftoe - Cryptonomicon


-----Original Message-----
From: Moderated discussion of advanced .NET topics.
[mailto:[EMAIL PROTECTED] On Behalf Of Ben Callister
Sent: Sunday, June 29, 2003 8:37 AM
To: [EMAIL PROTECTED]
Subject: [ADVANCED-DOTNET] security passes question: IIS -> ASP.NET ->
COM Interop ...


hello!

i have an ASP.NET web service with a web method that passes a path to a
network drive ('\\tron\Versioning'), on *another* box, to a classic
in-proc VB COM component that, internally, using the 'MS Scripting'
component to create a FileSystemObject and calls GetFolder() on that
object to retrieve a reference to that Folder object. when doing so, i
get a 'Path not found' exception returned.

------------------------------------------
couple notes (and code below):
------------------------------------------

- im running .NET framework 1.1 (v1.1.4322)
- the VB COM component is *not* a configured COM+ component - its just
classic COM (and in-proc DLL)
- i have verified that the path exists and the box that the web service
is running on can access it via 'Start...Run,' IE, and windows explorer
- i configured IIS security for *anonymous*, but specified a different
account that all incoming request will use (and for debugging purposes,
even included a domain admin to see if that would work - nope!)
- my web.config authentication mode = 'Windows' (<authentication
mode="Windows" />)
- i have tried turning impersonation on in my web.cofig file (<identity
impersonate="true"/>)
- when i pass a *local* path to the VB COM component, rather than
another network resource, it can fetch the folder just fine
- the ACL of the target folder, on the target box, *does* provide the
correct permissions for the account configured as the anonymous account
in IIS (and is verifiably being passed to ASP.NET - see below)

------------------------------------------
code snippets: (ASP.NET - shortened for clarity)
------------------------------------------

[WebMethod]
public string BuildVersionManifest(...)
{
        //just to verify that the appropriate credentials are getting
passed from IIS
        WindowsIdentity wi = WindowsIdentity.GetCurrent();
        string sUsername = wi.Name;
        //wi.Impersonate(); //ive tried this, but i assume it does the
same thing as having
        //impersonate turned on in my web.config - neither of them do
the trick

        //note: doing this works great?!? although, these 2 lines are
not part of the real code
        Scripting.FileSystemObject pFSO = new
Scripting.FileSystemObjectClass();
        Scripting.Folder pFolder = pFSO.GetFolder(@"\\tron\Versioning");

        //this is the real code that fails... see below for the code in
the 'VersionBasePath' property of the broker
        //that is the code that is unable to locate the passed folder
        nGENVerServer.VersionBroker pBroker = new
nGENVerServer.VersionBrokerClass();
        pBroker.VersionBasePath = @"\\tron\Versioning";        //THIS
LINE FAILS!!!
        ...
}

------------------------------------------
code snippet: (VB COM object)
------------------------------------------

Public Property Let VersionBasePath(ByVal sValue As String)
    On Error GoTo errHandler

    Dim theFSO As Scripting.FileSystemObject
    Set theFSO = New Scripting.FileSystemObject

    Set g_VersionBaseFolder = Nothing  'module member
    Set g_VersionBaseFolder = theFSO.GetFolder(sValue)  'REAL LINE THAT
FAILS with 'Path not found'!!!

    Exit Property

errHandler:
    Call Err.Raise(Err.Number, Err.source, Err.Description)
    Exit Property
End Property

------------------------------------------

notice that when i create a Scripting.FileSystemObject *directly* from
ASP.NET, and then call GetFolder() with my path, it is able to retrieve
the folder just fine. so... i was wondering if, how, and why a security
identity switch is occuring from my ASP.NET page to the VB COM interop
AND how can i get around this issue? (and please note, that as of right
now im not willing to accept the ASP.NET page passing in a reference to
the folder that it has already acquired. even if that worked, i have too
many other places internal to this VB COM component that will go out to
other network resources to perform its job).

also, in my research, i have found several good explanations of how
security is configured and handled in ISS, ASP.NET, and the transition
between the two, but i have not been able to find anything good on what
happens when you drop from managed code (in this case ASP.NET) to COM
interop code. in addition to knowing the answer to this particuliar
problem, i would really appreciate any advice on some good
articles/books on what happens here specifically (note: i am familiar
with Keith Brown's excellent book!).

thanks for any help you can provide,

Benjamin Callister
Vice President of Engineering, Tutor.com
Real Tutors, Real Results.

e: [EMAIL PROTECTED]
p: 212.528.3101; x.227
w: http://www.tutor.com

Reply via email to