我在单独的 AppDomain 中启动了一些代码,并且代码需要能够查询 SQLite 数据库。如果我将 AppDomain 的 PermissionState 设置为 Unrestricted,那么一切正常。但是,我想为 AppDomain 提供完成其任务所需的最低权限。
经过大量研究和反复试验,我确定以下安全权限是必要的:执行、非托管代码和 SkipVerification。包含正在 AppDomain 中运行的程序集的目录需要以下 FileIOPermissions:PathDiscovery 和 Read。包含 SQLite db3 文件的目录需要以下 FileIOPermissions:PathDiscovery、Read 和 Write。
但是,当我尝试打开 SQLite DB 时,这些权限给了我以下无用的异常:
System.Security.SecurityException 未由用户代码处理
HResult=-2146233078 消息=请求失败。
Source=System.Data.SQLite StackTrace:在 System.Data.SQLite.SQLiteConnectionHandle.op_Implicit(IntPtr db) 在 System.Data.SQLite.SQLite3.Open(String strFilename, SQLiteOpenFlagsEnum flags, Int32 maxPoolSize, Boolean usePool) 在 System.Data .SQLite.SQLiteConnection.Open() ...
这是生成 AppDomain 的代码:
public static ServerCacheSandboxer GetDomainInstance(string cachePath)
{
string assembliesPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ADENIUM_SERVER_ASSEMBLIES_FOLDER);
AppDomainSetup appDomainSetup = new AppDomainSetup();
appDomainSetup.ApplicationBase = assembliesPath;
appDomainSetup.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
PermissionSet permissionSet = new PermissionSet(PermissionState.None);
permissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution | SecurityPermissionFlag.UnmanagedCode | SecurityPermissionFlag.SkipVerification));
permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.PathDiscovery | FileIOPermissionAccess.Read, assembliesPath));
permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.PathDiscovery | FileIOPermissionAccess.Read | FileIOPermissionAccess.Write, cachePath));
StrongName fullTrustAssembly = typeof(ServerCacheSandboxer).Assembly.Evidence.GetHostEvidence<StrongName>();
AppDomain appDomain = AppDomain.CreateDomain("ServerCacheSandbox", null, appDomainSetup, permissionSet, fullTrustAssembly);
ObjectHandle objectHandle = Activator.CreateInstanceFrom(appDomain, typeof(ServerCacheSandboxer).Assembly.ManifestModule.FullyQualifiedName, typeof(ServerCacheSandboxer).FullName);
ServerCacheSandboxer domainInstance = objectHandle.Unwrap() as ServerCacheSandboxer;
return domainInstance;
}