我在单独的AppDomain中启动了一些代码,代码需要能够查询SQLite数据库。如果我为AppDomain设置PermissionState为Unrestricted,那么一切正常。但是,我想为AppDomain提供完成其任务所需的最低权限。
经过大量研究以及反复试验后,我确定需要以下安全权限:Execution,UnmanagedCode和SkipVerification。 包含在AppDomain中运行的程序集的目录需要以下FileIOPermissions:PathDiscovery和Read。 包含SQLite db3文件的目录需要以下FileIOPermissions:PathDiscovery,Read和Write。
但是,当我尝试打开SQLite数据库时,这些权限给了我以下无用的异常:
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;
}