2012-09-24 30 views
2

我有一个使用插件的应用程序。该组件链看起来像这样:请求失败.net程序集

附录 - > A - >乙 - > A - >乙

的组件是 “应用程序”(应用程序正在运行), “A” - 一个在组件连接和“B” - 一个加载了Assembly.LoadFile或Assembly.LoadFrom的程序集(两种方法都得到相同的错误)。

这是抛出一个安全异常,试图链接和不受限制的权限。当A再次呼叫B时发生异常。 B是不是一个签名的程序集(因此我从我读过的没有一个强有力的命名程序集中收集)。我也尝试在B的attribute.cs文件中放置[assembly:AllowPartiallyTrustedCallers]属性(并试图将其放在所有程序集上)。我甚至试图把权限声明为无限制的权限,但从我读过的内容来看,这对LinkDemand应该没有任何影响。

我知道程序集已经减少了权限(猜测这与通过Assembly加载它有关)。然而,我读过的所有内容似乎都表明LinkDemand只检查调用权限,所以我不确定为什么它会在第二次而不是第一次失败。

我很困惑,因为:a。为什么它不是第一次失败,b。为什么会发生这种情况(不使用强大的命名组件afaik)和c。为什么不添加APTC属性修复事情。

要明确一点,我没有任何程序集中的任何方法的安全性需求属性(不包括LinkDemands)。我在程序集A中确实拥有一些权限声明,但我不明白这会如何影响任何内容。

[System.Security.SecurityException] {"Request failed."} System.Security.SecurityException 
Action        LinkDemand System.Security.Permissions.SecurityAction 
Demanded       {<PermissionSet class="System.Security.PermissionSet" version="1" Unrestricted="true"/> } object {System.Security.PermissionSet} 
DenySetInstance      null object 
FailedAssemblyInfo     {B, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null} System.Reflection.AssemblyName 
FirstPermissionThatFailed   null System.Security.IPermission 
GrantedSet       "<PermissionSet class=\"System.Security.PermissionSet\"\r\nversion=\"1\">\r\n<IPermission class=\"System.Security.Permissions.FileDialogPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nAccess=\"Open\"/>\r\n<IPermission class=\"System.Security.Permissions.IsolatedStorageFilePermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nAllowed=\"ApplicationIsolationByUser\"\r\nUserQuota=\"512000\"/>\r\n<IPermission class=\"System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nFlags=\"Execution\"/>\r\n<IPermission class=\"System.Security.Permissions.UIPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nWindow=\"SafeTopLevelWindows\"\r\nClipboard=\"OwnClipboard\"/>\r\n<IPermission class=\"System.Security.Permissions.UrlIdentityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nUrl=\"file:///Z:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/B.dll\"/>\r\n<IPermission class=\"System.Security.Permissions.ZoneIdentityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nZone=\"Internet\"/>\r\n<IPermission class=\"System.Drawing.Printing.PrintingPermission, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\"\r\nversion=\"1\"\r\nLevel=\"SafePrinting\"/>\r\n</PermissionSet>\r\n" string 
Method        null System.Reflection.MethodInfo 
PermissionState      "<PermissionSet class=\"System.Security.PermissionSet\"\r\nversion=\"1\"\r\nUnrestricted=\"true\"/>\r\n" string 
PermissionType      {Name = "PermissionSet" FullName = "System.Security.PermissionSet"} System.Type {System.RuntimeType} 
PermitOnlySetInstance    null object 
RefusedSet       "" string 
Url         "file:///Z:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/B.dll" string 
Zone        Internet System.Security.SecurityZone 

正如Hans Passant所建议的,这似乎与安全区域互联网有关。我自从尝试了以下caspol命令无济于事:

caspol -m -ag 1.2 -url file://z:/* FullTrust 
caspol -m -ag 1.2 -url file://\\sam-crazycasta.dyndns.org/crazycasta/* FullTrust 
caspol -m -ag 1.3 -url file://z:/* FullTrust 
caspol -m -ag 1.3 -url file://\\sam-crazycasta.dyndns.org/crazycasta/* FullTrust 

但是,复制本地文件确实有效。我想要一个通用的解决方案,允许我从网络驱动器等运行。最好是我可以在程序中做的事情,以便用户不需要知道任何错误。

编辑1:我抓住从MSDN一些代码打印出来的政策,这是我所得到的,像FullTrust应该得到授权在我看来(最后一行是问题除外):

Policy Level Enterprise: 
    FullTrust 
    LocalIntranet 
    Internet 
    SkipVerification 
    Execution 
    Nothing 
    Everything 
Policy Level Machine: 
    Nothing 
    FullTrust 
    LocalIntranet 
    Internet 
    SkipVerification 
    Execution 
    Everything 
Policy Level User: 
    FullTrust 
    LocalIntranet 
    Internet 
    SkipVerification 
    Execution 
    Nothing 
    Everything 
A first chance exception of type 'System.Security.SecurityException' occurred in mscorlib.dll 

无论从失败的网络运行还是从硬盘运行,该打印输出都完全相同。

我也尝试添加以下功能和失败的调用之前调用它:

[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.LinkDemand, Unrestricted = true)] 
public void dummy() {} 

由于它的链接,要求不受限制的权限,我不明白为什么这个功能的工作原理和其他没有。

+1

注意区,互联网是高度不信任。您需要运行Caspol.exe将信任分配给映射的驱动器:http://blogs.msdn.com/b/shawnfa/archive/2004/12/30/344554.aspx –

+0

不知道如何或如果它会影响的东西,但我应该提到我以管理员身份运行应用程序本身。另外,我尝试使用caspol来使共享和z:驱动器完全信任,并且它没有效果。 但是,如果我将文件复制到C驱动器,一切正常。 这些是我使用的命令: caspol -m -ag 1.3 -url file:// z:/ * FullTrust caspol -m -ag 1.3 -url file:// \\ sam-crazycasta.dyndns.org/crazycasta/* FullTrust – CrazyCasta

+0

您正在使用哪种版本的.NET Framework?您正在从驱动器Z:加载程序集。它是本地网络驱动器吗? – Jehof

回答

0

我试图杀死程序集B中的一个进程。这只是部分答案。我仍然感到困惑,因为调试器指向程序集A中调用程序集B的行而不是程序集B中的行,我试图终止进程。下面是一些演示问题的代码,如果有人能告诉我我应该怎么知道异常来自程序集B,我会接受这个答案。

议会答:

using System; 
using System.Text; 

namespace A 
{ 
    public interface IA 
    { 
     void A(); 
     void B(); 
    } 

    public class A 
    { 
     public IA a; 

     public A(IA _a) 
     { 
      a = _a; 
     } 

     public void callA() 
     { 
      Console.WriteLine("callA called, calling A."); 
      a.A(); 
     } 

     public void callB() 
     { 
      Console.WriteLine("callB called, calling B."); 
      a.B(); 
     } 
    } 
} 

大会B:

using System; 
using System.Text; 

using System.Diagnostics; 

namespace B 
{ 
    public class _B : A.IA 
    { 
     public A.A a; 

     public _B(A.A _a) 
     { 
      a = _a; 
     } 

     #region IA Members 

     public void A() 
     { 
      Console.WriteLine("A called, calling callB."); 
      a.callB(); 
     } 

     public void B() 
     { 
      Console.WriteLine("B called."); 
      Process.GetCurrentProcess().Kill(); 
     } 

     #endregion 
    } 
} 

应用:

using System; 
using System.Text; 

using System.Reflection; 

namespace App 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      A.IA ia; 
      Assembly b; 
      Type tb; 
      A.A a; 

      a = new A.A(null); 
      b = Assembly.LoadFrom("../../../B/bin/Debug/B.dll"); 
      tb = b.GetType("B._B"); 
      ia = (A.IA)tb.GetConstructor(new Type[] { typeof(A.A) }).Invoke(new object[]{a}); 
      a.a = ia; 
      a.callA(); 
     } 
    } 
}