2012-09-24 32 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(); 
     } 
    } 
}