独立存储
独立存储是一种数据存储机制,它在代码与保存的数据之间定义了标准化的关联方式,从而提供隔离性和安全性。同时,标准化也提供了其他好处。管理员可以使用旨在操作独立存储的工具来配置文件存储空间、设置安全策略及删除未使用的数据。通过独立存储,代码不再需要使用唯一的路径来指定文件系统中的安全位置,同时可以保护数据免遭只具有独立存储访问权限的其他应用程序的损坏。不再需要指示应用程序的存储区域位置的“硬编码”信息。通过使用独立存储,可以使部分受信的应用程序以由计算机安全策略控制的方式存储数据。对于用户需慎重运行的 Web 应用程序和下载的组件来说,这尤为有用。安全策略很少向这种代码授予使用标准 I/O 机制访问文件系统的权限,但是默认情况下,会对在本地计算机、本地网络或 Internet 中运行的代码授予使用独立存储的权限。
独立存储介绍
当应用程序在文件中存储数据时,必须小心选择文件名和存储位置,最大程度地减小其他应用程序知道该存储位置的可能性,从而使数据不易受到损坏。如果没有标准的系统来处理这些问题,想开发出最大程度地减少存储冲突的特别技术可能并非易事,而且开发出来的技术也不见得可靠。
通过使用独立存储,数据将始终按用户和程序集进行隔离。程序集的源或强名称等凭据确定程序集的身份。通过使用类似的凭据,数据还可以按应用程序域进行隔离。
当使用独立存储时,应用程序将数据保存到一个与代码标识的某些方面(例如 Web 站点、发行者或签名)相关联的独特数据舱。数据舱是一个抽象的存储位置,而不是具体的存储位置,它由一个或多个独立的存储文件(叫做存储区)组成,这些独立的存储文件包含存储数据的实际目录位置。例如,Web 应用程序可能有一个与其关联的数据舱,文件系统中的某个目录将实现实际保留应用程序数据的存储区。保存在存储区中的数据可以是任意类型的数据,无论是用户首选项信息还是应用程序状态都可以。对于开发人员,数据舱的位置是透明的;存储区通常驻留在客户端,但服务器应用程序可以通过模拟它所服务的用户来使用独立存储区存储信息。独立存储还可以将信息和用户漫游配置文件一起保存在服务器上,这样漫游用户就可以随时使用该信息。
管理员可以根据适当的信任级别限制应用程序或用户可以使用多少独立存储。另外,管理员可以移除用户的所有持久性数据。要创建或访问独立存储,必须授予代码适当的 IsolatedStorageFilePermission。
要访问独立存储,代码必须具有所有必要的本机平台操作系统权限。例如,在 Windows 2000 上必须满足访问控制列表 (ACL),该列表控制哪些用户具有使用文件系统的权限。除非执行(平台特定的)模拟,否则 Microsoft .NET 框架应用程序已经具有访问独立存储的操作系统权限。在这种情况下,应用程序负责确保被模拟的用户标识具有访问独立存储的适当操作系统权限。对于在 Web 上运行或从 Web 下载的代码而言,这种访问为之提供了一种读写与特定用户相关的存储区域的简便方法。
有时候,使用操作系统的文件系统来验证对独立存储进行的更改会非常有帮助。开发人员可能还需要了解独立存储文件的位置。该位置随操作系统的不同而不同。下表显示了在几个常见操作系统上创建独立存储的根位置。在此根位置下查找 Microsoft\IsolatedStorage 目录。您必须更改文件夹设置以显示隐藏文件和文件夹,才能查看到文件系统中的独立存储。
操作系统
在文件系统中的位置
Windows 98、ME
——用户配置文件未启用
启用漫游的存储区 =
<SYSTEMROOT>\Application Data
非漫游存储区 =
WINDOWS\Local Settings\Application Data
Windows 98、ME
——用户配置文件已启用
启用漫游的存储区 =
<SYSTEMROOT>\Profiles\<用户>\Application Data
非漫游存储区 =
Windows\Local Settings\Application Data
Windows NT 4.0
<SYSTEMROOT>\Profiles\<用户>\Application Data
Windows NT 4.0
——Service Pack 4
启用漫游的存储区 =
<SYSTEMROOT>\Profiles\<用户>\Application Data
非漫游存储区 =
<SYSTEMROOT>\Profiles\<用户>\Local Settings\Application Data
Windows 2000
——从 NT 4.0 升级
启用漫游的存储区 =
<SYSTEMROOT>\Profiles\<用户>\Application Data
非漫游存储区 =
<SYSTEMROOT>\Profiles\<用户>\Local Settings\Application Data
Windows 2000
——全新安装(和从 Windows 98 及 NT 3.51 升级)
启用漫游的存储区 =
<SYSTEMDRIVE>\Documents and Settings\<用户>\Application Data
非漫游存储区 =
<SYSTEMDRIVE>\Documents and Settings\<用户>\Local Settings\Application Data
独立存储的情况
独立存储可用于许多情况。以下介绍了五种最典型的情况:
下载的控件。不允许从 Internet 下载的托管代码控件通过正常的 I/O 类写入硬盘,但它们可以使用独立存储来持久保存用户设置和应用程序状态。
持久的 Web 应用程序存储。Web 应用程序也被禁止使用 I/O 类。这些程序可以出于与下载组件相同的目的使用独立存储。
共享组件存储。应用程序间共享的组件可以使用独立存储来提供对数据存储区的有控制的访问。
服务器存储。服务器应用程序可以使用独立存储为请求应用程序的大量用户提供单独的存储区。因为独立存储始终按用户进行隔离,所以服务器必须模拟发出请求的用户。在这种情况下,根据用户的标识隔离数据,该标识与应用程序用来区分其用户的标识是同一个标识。
漫游。应用程序还可以将独立存储和漫游用户配置文件一起使用。这允许用户的独立存储区和配置文件一起漫游。
虽然独立存储非常适合于以上所述的情况,但在少数情况下,您“不”应该使用独立存储:
独立存储不应该用于存储重要机密(例如不加密的密钥或密码),因为对高度受信代码、非托管代码或计算机的受信用户不设防。
独立存储不应该用来存储代码。
独立存储不应该用来存储配置和部署设置,它们是由管理员来控制的。(因为管理员不控制用户首选项,所以用户首选项不被认为是配置设置。)
当今的许多应用程序都使用数据库来存储和隔离数据,在这种情况下,数据库中的一个或多个行可能代表某个特定用户的存储。当用户数较少时、当使用数据库的系统开销非常大时或当不存在数据库功能时,您可以选择使用独立存储而不使用数据库。另外,当应用程序要求比数据库的行所提供的存储更加灵活和复杂的存储时,独立存储也可以提供一个可行的替代方案。
隔离的类型
对独立存储的访问总是限制在创建该存储的用户。要实现这种类型的隔离,公共语言运行库使用的用户标识注记与操作系统识别的注记相同,该用户标识注记是与存储区打开时代码在其中运行的进程相关联的标识。虽然该标识是已验证身份的用户标识,但是模拟可以导致当前用户的标识动态地改变。
除了按用户隔离之外,还根据与应用程序的域和程序集相关的(或仅与程序集相关的)标识限制对独立存储的访问。运行库以下面几种方式获得这些标识:
代表应用程序的证据的域标识,在 Web 应用程序情况下,该域标识可能是完整 URL。对于寄宿于外壳的代码,该域标识可能基于应用程序目录路径。例如,如果可执行文件在路径 C:\Office\MyApp.exe 中运行,域标识可能为 C:\Office\MyApp.exe。
程序集标识是程序集的证据。程序集标识可能来自于加密的数字签名,它可以是程序集的强名称、程序集的发行者或其 URL 标识。如果程序集同时具有强名称和发行者标识,则使用发行者标识。如果程序集来自 Internet 并且未签名,则使用 URL 标识。
漫游存储区和具有漫游用户配置文件的用户一起移动。文件被写入网络目录并被下载到用户登录的任何一台计算机上。有关漫游用户配置文件的更多信息,请参阅 IsolatedStorageScope.Roaming。
将用户、域和程序集标识的概念结合起来,独立存储可以按下面几种方式隔离数据,每种方式都有其自己的使用情况:
按用户和程序集隔离。
按用户、域和程序集隔离。
这两种隔离的每一种都可以和漫游用户配置文件结合。
下面的插图说明了如何将存储区隔离在不同的范围。
独立存储的类型
请注意,除了漫游存储区之外,独立存储始终被计算机隐式隔离,这是因为独立存储使用给定计算机本地的存储功能。
按用户和程序集隔离
当需要从任何应用程序域都可以访问程序集使用的数据存储区时,按用户和程序集隔离比较合适。通常,在这种情况下,独立存储用于存储跨多个应用程序应用的数据(例如用户的名称或许可证信息),这些数据不依赖于任何特定的应用程序。要访问按用户和程序集隔离的存储,代码必须受信以在应用程序之间传输信息。通常,允许在 Intranet 上使用按用户和程序集隔离,但不允许在 Internet 上使用。调用 IsolatedStorageFile 的静态 GetStore 方法并传入用户和程序集 IsolatedStorageScope 将返回具有这种隔离的存储。
下面的代码示例检索按用户和程序集隔离的存储区。可通过 isoFile 对象访问该存储区。
[C#]
IsolatedStorageFile isoFile = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null);
另一个方法可作为快捷方式,如下面的代码示例中所示。此快捷方式无法用于打开能够漫游的存储区,在这种情况下,请使用 GetStore。
[C#]
IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForAssembly();
按用户、域和程序集隔离
如果应用程序使用需要私有数据存储区的第三方程序集,隔离存储可用于存储私有数据。按用户、域和程序集隔离确保只有当在程序集创建存储区时运行的应用程序使用该程序集时,并且只有当为其创建存储区的用户运行该应用程序时,只有给定程序集中的代码才可以访问数据。按用户、域和程序集隔离使第三方程序集不能向其他应用程序泄露数据。如果您知道要使用隔离存储但不确定要使用哪种类型的隔离,这种隔离类型应该是您的默认选择。调用 IsolatedStorageFile 的静态 GetStore 方法并传入用户、域和程序集 IsolatedStorageScope 将返回具有这种隔离的存储。
下面的代码示例检索按用户、域和程序集隔离的存储区。可通过 isoFile 对象访问该存储区。
[C#]
IsolatedStorageFile isoFile = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Domain | IsolatedStorageScope.Assembly, null, null);
另一个方法可作为快捷方式,如下面的代码示例中所示。此快捷方式无法用于打开能够漫游的存储区,在这种情况下,请使用 GetStore。
[C#]
IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForDomain();
独立存储和漫游
漫游用户配置文件是 Microsoft Windows 的一项功能(在 Windows NT、Windows 2000 和某些经过更新的 Windows 98 系统上提供该功能),它使用户可以在网络上设置标识并使用该标识来登录任何网络计算机,所有个人设置在不同的计算机上都不会发生改变。使用独立存储的程序集可以指定用户的独立存储和漫游用户配置文件一起移动。漫游可以和按用户和程序集隔离或按用户、域和程序集隔离一起使用。如果未使用漫游范围,即使使用了漫游用户配置文件,存储区也不漫游。
下面的代码示例检索按用户和程序集隔离的漫游存储区。可通过 isoFile 对象访问该存储区。
[C#]
IsolatedStorageFile isoFile = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly | IsolatedStorageScope.Roaming, null, null);
可以添加域范围来创建按用户、域和应用程序隔离的漫游存储区。下面的代码示例对此进行了演示。
[C#]
IsolatedStorageFile isoFile = IsolatedStorageFile.GetStore(IsolatedStorageScope.User |
IsolatedStorageScope.Assembly |
IsolatedStorageScope.Domain |
IsolatedStorageScope.Roaming, null, null);
独立存储的配额
配额是对可使用的独立存储数量的限制。配额包括文件空间的字节及与存储区中目录和其他信息关联的系统开销。独立存储使用权限配额,这是使用 IsolatedStoragePermission 对象设置的存储限制。如果试图超出配额写入数据,则会引发 IsolatedStorageException。安全策略确定向代码授予的权限,它可以使用 .NET 框架配置工具 (Mscorcfg.msc) 来修改。被授予 IsolatedStoragePermission 的代码限制在使用不超过 UserQuota 属性所允许使用存储的范围内。但是,由于代码可以通过表示不同的用户标识绕过权限配额,所以权限配额用作指导代码如何工作的指南,而不是对代码行为的硬性限制。
不对漫游存储区强制执行配额。因此,对使用它们的代码要求稍高级别的权限。AssemblyIsolationByRoamingUser 和 DomainIsolationByRoamingUser 是两种指定使用漫游用户独立存储权限的枚举。
保护独立存储
要控制对独立存储的访问,公共语言运行库使用 IsolatedStorageFilePermission 对象。每个 IsolatedStorageFilePermission 对象都具有指定以下值的属性:
允许的用法,这指出了所允许的访问类型。该值是 IsolatedStorageContainment 枚举的成员。
存储的配额.
当代码第一次尝试打开存储区时,运行库要求此权限。它根据代码的受信程度决定是否授予 IsolatedStorageFilePermission。如果授予了该权限,允许的用法和存储配额值由安全策略和代码对 IsolatedStorageFilePermission 的请求决定。安全策略使用 .NET 框架配置工具 (Mscorcfg.msc) 来进行设置。检查调用堆栈中的所有调用方以确保每个调用方至少具有适当的允许的用法。运行库还检查强加于代码的配额,该代码打开或创建将在其中保存文件的存储区。如果满足这些条件,就授予权限。每次文件写入存储区时,都将再次检查配额。
因为公共语言运行库将根据安全策略授予任何适当的 IsolatedStorageFilePermission,所以请求权限不需要应用程序代码。但是,有很好的理由来请求应用程序需要的特定权限,包括 IsolatedStorageFilePermission。
允许的用法和安全风险
IsolatedStorageFilePermission 指定的许可用法确定允许代码创建和使用独立存储的程度。下表显示了权限中指定的允许的用法如何与隔离的类型对应,并总结了与每种允许的用法关联的安全风险。
允许的用法
隔离类型
安全影响
None
不允许使用任何独立存储。
没有安全影响。
DomainIsolationByUser
按用户、域和程序集隔离。每个程序集在域中都有单独的子存储区。使用此权限的存储区也由计算机隐式隔离。
此权限级别无法阻止他人未经授权滥用资源,尽管强制的配额对此做法增添了一些难度。这叫做拒绝服务攻击。
DomainIsolationByRoamingUser
与前一个相同,但如果启用漫游用户配置文件而且不强制配额,则存储区保存到将漫游的位置。
因为必须禁用配额,所以存储资源更易受到拒绝服务攻击。
AssemblyIsolationByUser
按用户和程序集隔离。使用此权限的存储区也由计算机隐式隔离。
在此级别强制实施配额以帮助防止拒绝服务攻击。由于另一个域中相同的程序集可以访问该存储区,这就使信息可能在应用程序间泄露。
AssemblyIsolationByRoamingUser
与前一个相同,但如果启用漫游用户配置文件而且不强制配额,则存储区保存到将漫游的位置。
与前一个相同,但没有配额,增加了拒绝服务攻击的风险。
AdministerIsolatedStorageByUser
按用户隔离。通常,只有管理或调试工具才使用此级别的权限。
使用该权限访问允许代码查看或删除任何的用户独立存储文件或目录(而不论程序集是否隔离)。存在的风险包括(但不限于)泄露信息和数据丢失。
UnrestrictedIsolatedStorage
按所有用户、域和程序集隔离。通常,只有管理或调试工具才使用此级别的权限。
此权限有可能会整个危害所有用户的所有独立存储区。
执行独立存储任务
提供了三个主要的类来帮助您执行涉及独立存储的任务:
从 IsolatedStorage 派生的 IsolatedStorageFile 提供对存储的程序集和应用程序文件的基本管理。IsolatedStorageFile 类的实例表示位于文件系统中的单个存储区。
从 System.IO.FileStream 派生的 IsolatedStorageFileStream 提供对存储区中文件的访问。
IsolatedStorageScope 是一个枚举,使您可以创建并选择具有适当隔离类型的存储区。
独立存储类使您可以创建、枚举并删除独立存储。通过 IsolatedStorageFile 对象可以使用执行这些任务的方法。某些操作要求您具有 IsolatedStorageFilePermission(它代表管理独立存储的权限);您可能还需要具有访问文件或目录的操作系统权限。在 Microsoft Windows NT 和 Microsoft Windows 2000 上,文件上的访问控制列表 (ACL) 设置可以防止您访问独立存储。独立存储工具 (Storeadm.exe) 也可以用于简单的存储区管理,例如列出或删除当前用户的所有存储区。