Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Distributed Applications / December 2005

Tip: Looking for answers? Try searching our database.

Exception with Child AppDomain

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
xenophon - 15 Dec 2005 21:27 GMT
IIS6 with all WindowsUpdate patches
ASP.NET 1.1-SP1
using identity impersonate="true" and authentication mode="Windows" in
web.config
Application is not in the local intranet, it is externally hosted for
an internal company

Web app with a reference to an external Assembly (it has no strong
name). The external Assembly contains a class with a method for
creating a new AppDomain and then placing a new Singleton instance of
another class (defined in the same Assembly) in the new AppDomain.

In the Session_Start event in Global.Asax, I check if the user has
authenticated, and if so the external Assembly is loaded and an
instance of the class is unwrapped and placed in the Remoted domain.
Web pages can make Remoted calls as needed and do their work.

However, that only works from a local XP desktop (where the developer
is an Administrator or Power User). The below Exception is thrown when
run from a Windows 2003 server. I think there is a problem is related
to Evidence for loading the Assembly. What could be wrong?

The code looks like this:

Evidence appEvidence = null;
AppDomainSetup aaD = new AppDomainSetup();
aaD.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory +"bin";
aaD.PrivateBinPath = aaD.ApplicationBase;
aaD.ApplicationName = "AppStorage";
aaD.ShadowCopyDirectories = aaD.ApplicationBase;
aaD.ShadowCopyFiles = "true";
AppDomain appdoma = AppDomain.CreateDomain("Dummy");
AppStorage appStorage = new AppStorage();
try
{
appdoma = AppDomain.CreateDomain( "AppStorage" , appEvidence , aaD );
this._hostHandle = appdoma.CreateInstance( "TestDev.AppServices" ,
"TestDev.AppServices.AppStorage"  );
appStorage = (AppStorage)this._hostHandle.Unwrap();
ObjectHandle _hostHandle = appdoma.CreateInstance(
"TestDev.AppServices" , "TestDev.AppServices.AppStorage"  );
// Above line is where Exception is thrown

Problem:


System.IO.FileLoadException: Access is denied: 'TestDev.AppServices'.
File name: "TestDev.AppServices"

Server stack trace:
  at System.Reflection.Assembly.nLoad(AssemblyName fileName, String
codeBase, Boolean isStringized,
              Evidence assemblySecurity, Boolean
throwOnFileNotFound, Assembly locationHint, StackCrawlMark& stackMark)
  at System.Reflection.Assembly.InternalLoad(AssemblyName
assemblyRef, Boolean stringized,
              Evidence assemblySecurity, StackCrawlMark&
stackMark)
  at System.Reflection.Assembly.InternalLoad(String assemblyString,
Evidence
              assemblySecurity, StackCrawlMark& stackMark)
  at System.Activator.CreateInstance(String assemblyName, String
typeName,
              Boolean ignoreCase, BindingFlags bindingAttr,
Binder binder, Object[] args,
              CultureInfo culture, Object[]
activationAttributes, Evidence securityInfo,
              StackCrawlMark& stackMark)
  at System.Activator.CreateInstance(String assemblyName, String
typeName)
  at System.AppDomain.CreateInstance(String assemblyName, String
typeName)
  at
System.Runtime.Remoting.Messaging.StackBuilderSink.PrivateProcessMessage(
              MethodBase mb, Object[] args, Object server,
Int32 methodPtr, Boolean
              fExecuteInContext, Object[]& outArgs)
  at
System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage
msg,
              Int32 methodPtr, Boolean fExecuteInContext)

Exception rethrown at [0]:
  at
System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage
reqMsg, IMessage retMsg)
  at
System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&
msgData, Int32 type)
  at System.AppDomain.CreateInstance(String assemblyName, String
typeName)
  at TestDev.AppServices.EnterpriseServices.StoragePrep.Prepare(
              String remoteServerLocation, Int32
localClientPort)
              in .....storageprep.cs:line 106

=== Pre-bind state information ===
LOG: DisplayName = TestDev.AppServices
(Partial)
LOG: Appbase = E:/inetpub/wwwsites/TestSite/bin
LOG: Initial PrivatePath = E:/inetpub/wwwsites/TestSite/bin
Calling assembly : (Unknown).
===

LOG: Application configuration file does not exist.
LOG: Policy not being applied to reference at this time (private,
custom, partial, or location-based assembly bind).
LOG: Post-policy reference: TestDev.AppServices
LOG: Attempting download of new URL
file:///E:/inetpub/wwwsites/TestSite/bin/TestDev.AppServices.DLL.
LOG: Policy not being applied to reference at this time (private,
custom, partial, or location-based assembly bind).
LOG: Post-policy reference: TestDev.AppServices, Version=6.2.0.0,
Culture=neutral, PublicKeyToken=null

______________________________________________________________________

Call Stack:

Method Global.StoragePrep

Method Global.Application_Start
      sender: System.Object
      e: System.EventArgs

Method RuntimeMethodInfo.InternalInvoke
      obj: System.Object
      invokeAttr: System.Reflection.BindingFlags
      binder: System.Reflection.Binder
      parameters: System.Object[]
      culture: System.Globalization.CultureInfo
      isBinderDefault: System.Boolean
      caller: System.Reflection.Assembly
      verifyAccess: System.Boolean

Method RuntimeMethodInfo.InternalInvoke
      obj: System.Object
      invokeAttr: System.Reflection.BindingFlags
      binder: System.Reflection.Binder
      parameters: System.Object[]
      culture: System.Globalization.CultureInfo
      verifyAccess: System.Boolean

Method RuntimeMethodInfo.Invoke
      obj: System.Object
      invokeAttr: System.Reflection.BindingFlags
      binder: System.Reflection.Binder
      parameters: System.Object[]
      culture: System.Globalization.CultureInfo

Method HttpApplication.ProcessSpecialRequest
      context: System.Web.HttpContext
      method: System.Reflection.MethodInfo
      paramCount: System.Int32
      eventSource: System.Object
      eventArgs: System.EventArgs
      session: System.Web.SessionState.HttpSessionState

Method HttpApplicationFactory.FireApplicationOnStart
      context: System.Web.HttpContext

Runtime CLI Information: .NET Runtime
C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\
NET Version v1.1.4322 Release Build
[MSFT] - 16 Dec 2005 08:17 GMT
From your description, it seems to be a security issue. Your ASP.NET
application will use the current user's acount to load the app domain. To
confirm this, you can logon on as a local administrator, and browse to the
ASP.NET web page, what will be the result?

Luke
xenophon - 16 Dec 2005 14:40 GMT
Yes, I agree there is a security issue.

This is not an issue where a page can be browsed by one user and not
by another. The AppDomain work occurs in the Session_Start event,
presumably before any page is instanced. It appears to me that an
unknown user account does not have permissions to load or Reflect over
the external DLL for Remoting.

I am unable to properly debug this because if I am in the VS.NET 2003
debugger (where I develop as a local Administrator), the problem does
not occur. It occurs only when the app content is xcopy-deployed to
the remote web server and the site is then accessed by an unprivileged
user. I set up the web app to send an email when an Exception is
thrown, that is the only reason I have the info I previously posted.

The ACLs on the bin directory (where the external DLL is located)
allow "R"ead for the local group that can otherwise access the site.

Do I need to create custom Evidence so "everyone" can load the
Assembly?

>From your description, it seems to be a security issue. Your ASP.NET
>application will use the current user's acount to load the app domain. To
>confirm this, you can logon on as a local administrator, and browse to the
>ASP.NET web page, what will be the result?
>
>Luke
[MSFT] - 19 Dec 2005 05:52 GMT
To make the code in Session_start running under a powerful account, you may
change the account for the application pool: In IIS 6. 0 Manager, expand
"Applications Pools" and find the pool for your ASP.NET application, in its
properties page, change its identity to a powerful account, for example, a
local administrator and with network access permission. Will this fix the
problem?

Luke

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.