2010-03-13 120 views
2

我正在構建一個使用插件的C#應用​​程序。應用程序必須向用戶保證,插件不會在用戶機器上執行任何他們想要的操作,並且應用程序本身的權限會更小(例如,應用程序可以訪問自己的日誌文件,而插件則不能) 。執行不可信代碼

我考慮過三種選擇。

  1. 使用System.AddIn。我首先嚐試了這種方法,因爲它的功能非常強大,但是我真的很失望,因爲每次我想修改某些內容時,需要在七個不同的項目中修改相同的代碼七次。此外,即使對於簡單的Hello World應用程序也有大量的問題需要解決。

  2. 使用System.Activator.CreateInstance(assemblyName,typeName)。這是我在前一個版本的應用程序中使用的。我再也不能使用它了,因爲它沒有提供限制權限的方法。

  3. 使用System.Activator.CreateInstance(AppDomain域,[...])。這就是我現在要實現的目標,但似乎要做到這一點的唯一方法是通過ObjectHandle,這需要對每個使用的類進行序列化。儘管插件包含不可序列化的WPF UserControls。

那麼,有沒有一種方法來創建一個包含用戶控件或其他非序列化對象的插件和一個自定義的PermissionSet執行這些插件?

回答

1

您可以做的一件事就是將當前AppDomain的策略級別設置爲受限權限集,並添加證據標記以基於強名稱或位置進行限制。最簡單的做法可能是要求插件位於特定的目錄中,並給它們一個限制性策略。

例如

public static void SetRestrictedLevel(Uri path) 
{ 
    PolicyLevel appDomainLevel = PolicyLevel.CreateAppDomainLevel();    

    // Create simple root policy normally with FullTrust 
    PolicyStatement fullPolicy = new PolicyStatement(appDomainLevel.GetNamedPermissionSet("FullTrust")); 
    UnionCodeGroup policyRoot = new UnionCodeGroup(new AllMembershipCondition(), fullPolicy); 

    // Build restrictred permission set 
    PermissionSet permSet = new PermissionSet(PermissionState.None);    
    permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));    
    PolicyStatement permissions = new PolicyStatement(permSet, PolicyStatementAttribute.Exclusive); 
    policyRoot.AddChild(new UnionCodeGroup(new UrlMembershipCondition(path.ToString()), permissions));    

    appDomainLevel.RootCodeGroup = policyRoot; 

    AppDomain.CurrentDomain.SetAppDomainPolicy(appDomainLevel); 
} 

static void RunPlugin() 
{ 
    try 
    {     
     SetRestrictedLevel(new Uri("file:///c:/plugins/*"));     

     Assembly a = Assembly.LoadFrom("file:///c:/plugins/ClassLibrary.dll"); 
     Type t = a.GetType("ClassLibrary.TestClass"); 
     /* Will throw an exception */     
     t.InvokeMember("DoSomething", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, 
       null, null, null); 
    } 
    catch (Exception e) 
    { 
     Console.WriteLine(e.ToString()); 
    } 
} 

當然這不是嚴格的測試和CAS的政策是衆所周知的複雜,所以總是有風險的,這個代碼可以讓一些東西繞過政策,因人而異:)

+0

感謝。我試過了,我認爲這正是我需要的。 – 2010-03-14 11:42:42