我剛纔問了如何限制插件訪問(我想阻止他們寫入磁盤或網絡),並且我被告知要使用AppDomain。我已經搜索,並嘗試和失敗,如何得到這個工作。限制插件通過appdomain訪問文件系統和網絡
任何人都可以提供一些信息,所以我可以開始,簡單地把一個AppDomain,不允許寫入文件或網絡。
我剛纔問了如何限制插件訪問(我想阻止他們寫入磁盤或網絡),並且我被告知要使用AppDomain。我已經搜索,並嘗試和失敗,如何得到這個工作。限制插件通過appdomain訪問文件系統和網絡
任何人都可以提供一些信息,所以我可以開始,簡單地把一個AppDomain,不允許寫入文件或網絡。
我想這是你需要的,如果我正確理解你的觀點。
System.Security.PermissionSet ps =
new System.Security.PermissionSet(System.Security.Permissions.PermissionState.None);
ps.AddPermission(new System.Security.Permissions.FileIOPermission(System.Security.Permissions.FileIOPermissionAccess.NoAccess, "C:\\"));
System.Security.Policy.PolicyLevel pl = System.Security.Policy.PolicyLevel.CreateAppDomainLevel();
pl.RootCodeGroup.PolicyStatement = new System.Security.Policy.PolicyStatement(ps);
AppDomain.CurrentDomain.SetAppDomainPolicy(pl);
System.Reflection.Assembly myPluginAssembly = AppDomain.CurrentDomain.Load("MyPluginAssembly");
這更確切地說是你的意思嗎?
請注意,您可能會提供一個包含不希望插件訪問的路徑的字符串數組。您可以提供是否在初始化FileIOPermission類的新實例時。
讓我知道這是否有幫助。 :-)
如果您使用的是插件,您可能會了解代理。
在通過代理加載您的程序集時,如果我沒有記錯,您可以通過LoadAssembly()方法指定此特定程序集的安全策略級別。換句話說,這是通過反思完成的。
我知道我的答案沒有那麼詳細,但我希望它能讓你知道在哪裏尋找解決方案。我會留意找出有關這個問題的更多細節,以便我可以得到更好的幫助。 =)
希望你會分享你的發現,當你做完它。
對於.net framework 4.0,請按照以下代碼從this MSDN文章。
以下示例實現了上一節中的過程。在該示例中,Visual Studio解決方案中名爲Sandboxer的項目還包含名爲UntrustedCode的項目,該項目實現UntrustedClass類。此方案假定您已下載庫程序集,其中包含預期返回true或false的方法,以指示您提供的數字是否爲斐波納契數字。相反,該方法嘗試從您的計算機讀取文件。以下示例顯示了不可信代碼。
using System;
using System.IO;
namespace UntrustedCode
{
public class UntrustedClass
{
// Pretend to be a method checking if a number is a Fibonacci
// but which actually attempts to read a file.
public static bool IsFibonacci(int number)
{
File.ReadAllText("C:\\Temp\\file.txt");
return false;
}
}
}
以下示例顯示了執行非信任代碼的Sandboxer應用程序代碼。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Security;
using System.Security.Policy;
using System.Security.Permissions;
using System.Reflection;
using System.Runtime.Remoting;
//The Sandboxer class needs to derive from MarshalByRefObject so that we can create it in another
// AppDomain and refer to it from the default AppDomain.
class Sandboxer : MarshalByRefObject
{
const string pathToUntrusted = @"..\..\..\UntrustedCode\bin\Debug";
const string untrustedAssembly = "UntrustedCode";
const string untrustedClass = "UntrustedCode.UntrustedClass";
const string entryPoint = "IsFibonacci";
private static Object[] parameters = { 45 };
static void Main()
{
//Setting the AppDomainSetup. It is very important to set the ApplicationBase to a folder
//other than the one in which the sandboxer resides.
AppDomainSetup adSetup = new AppDomainSetup();
adSetup.ApplicationBase = Path.GetFullPath(pathToUntrusted);
//Setting the permissions for the AppDomain. We give the permission to execute and to
//read/discover the location where the untrusted code is loaded.
PermissionSet permSet = new PermissionSet(PermissionState.None);
permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
//We want the sandboxer assembly's strong name, so that we can add it to the full trust list.
StrongName fullTrustAssembly = typeof(Sandboxer).Assembly.Evidence.GetHostEvidence<StrongName>();
//Now we have everything we need to create the AppDomain, so let's create it.
AppDomain newDomain = AppDomain.CreateDomain("Sandbox", null, adSetup, permSet, fullTrustAssembly);
//Use CreateInstanceFrom to load an instance of the Sandboxer class into the
//new AppDomain.
ObjectHandle handle = Activator.CreateInstanceFrom(
newDomain, typeof(Sandboxer).Assembly.ManifestModule.FullyQualifiedName,
typeof(Sandboxer).FullName
);
//Unwrap the new domain instance into a reference in this domain and use it to execute the
//untrusted code.
Sandboxer newDomainInstance = (Sandboxer) handle.Unwrap();
newDomainInstance.ExecuteUntrustedCode(untrustedAssembly, untrustedClass, entryPoint, parameters);
}
public void ExecuteUntrustedCode(string assemblyName, string typeName, string entryPoint, Object[] parameters)
{
//Load the MethodInfo for a method in the new Assembly. This might be a method you know, or
//you can use Assembly.EntryPoint to get to the main function in an executable.
MethodInfo target = Assembly.Load(assemblyName).GetType(typeName).GetMethod(entryPoint);
try
{
//Now invoke the method.
bool retVal = (bool)target.Invoke(null, parameters);
}
catch (Exception ex)
{
// When we print informations from a SecurityException extra information can be printed if we are
//calling it with a full-trust stack.
(new PermissionSet(PermissionState.Unrestricted)).Assert();
Console.WriteLine("SecurityException caught:\n{0}", ex.ToString());
CodeAccessPermission.RevertAssert();
Console.ReadLine();
}
}
}
這似乎是exacly im後,我得到給定的程序集名稱或代碼庫是無效的。 (從HRESULT異常:0x80131047)現在,但我還沒有時間去更多地瞭解它(我可以猜測做錯了什麼)。 明天我得到更多的時間,我會讓你知道 – EKS 2009-09-01 22:00:25
所以,最後,這是你在找什麼?我想,因爲你似乎已經檢查過它。 :-) – 2009-09-11 16:27:11
@EKS您必須從相同的文件夾或文件夾的其中一個子文件加載。 – 2009-10-16 08:15:38