Windows 窗体中更加安全的文件和数据访问
更新:2007 年 11 月
.NET Framework 使用权限来帮助保护资源和数据。应用程序可以读取或写入数据的位置取决于为应用程序授予的权限。当应用程序在部分信任环境中运行时,您可能不具有对数据的访问权限,或者必须更改访问数据的方式。
遇到安全限制时,您有两个选择:断言权限(假定已授权给应用程序),或者使用为用于部分信任环境而编写的功能的版本。以下各节讨论如何从部分信任的环境运行的应用程序处理文件、数据库和注册表访问。
说明: |
---|
默认情况下,生成 ClickOnce 部署的工具将这些部署默认为向它们运行计算机请求“完全信任”。如果您决定要获得部分信任环境中运行的附加安全性优点,则必须在 Visual Studio 或 Windows 软件开发工具包 (SDK) 工具(Mage.exe 或 MageUI.exe)之一中更改此默认设置。有关 Windows 窗体安全性的更多信息,以及如何确定适当的应用程序信任级别,请参见 Windows 窗体中的安全性概述。 |
文件访问
在 .NET Framework 中,FileIOPermission 类控制对文件和文件夹的访问。默认情况下,安全系统不会将 FileIOPermission 授予部分信任环境(例如,本地 Intranet 和 Internet 区域)。不过,如果修改应用程序的设计或使用不同的方法访问文件,则要求访问文件的应用程序仍可以在这些环境中工作。默认情况下,本地 Intranet 区域将被授予相同的站点访问权限和相同的目录访问权限,以便连接回其原始站点,并从其安装目录读取数据。默认情况下,Internet 区域仅被授予连接回其原始站点的权限。
用户指定的文件
处理不具有文件访问权限的一种方法是,提示用户使用 OpenFileDialog 或 SaveFileDialog 类提供特定的文件信息。这种用户交互有助于在一定程度上保证,应用程序无法恶意加载私有文件或改写重要的文件。OpenFile 和 OpenFile 方法通过打开用户指定文件的文件流,来提供读写文件的访问权限。这些方法还可以隐藏文件的路径,从而有助于保护用户的文件。
说明: |
---|
根据应用程序是位于 Internet 区域还是在 Intranet 区域,这些权限会有所不同。Internet 区域中的应用程序只能使用 OpenFileDialog,而 Intranet 应用程序具有无限制的文件对话框权限。 |
FileDialogPermission 类指定应用程序可以使用的文件对话框的类型。下表显示使用每个 FileDialog 类时必须提供的值。
类 |
必需的访问值 |
---|---|
说明: |
---|
只有在实际调用 OpenFile 方法时才会请求特定权限。 |
用于显示文件对话框的权限并不会向应用程序授予对 FileDialog、OpenFileDialog 和 SaveFileDialog 类的所有成员的完全访问权。有关调用每个方法时所需的确切权限,请参见 .NET Framework 类库文档中该方法的参考主题。
下面的代码示例使用 OpenFile 方法,在 RichTextBox 控件中打开用户指定的文件。此示例要求提供 FileDialogPermission 和关联的 Open 枚举值。此示例演示如何处理 SecurityException,以确定是否应禁用保存功能。此示例要求 Form 具有一个名为 ButtonOpen 的 Button 控件,以及一个名为 RtfBoxMain 的 RichTextBox 控件。
说明: |
---|
此示例中未显示保存功能的编程逻辑。 |
[Visual Basic]
Private Sub ButtonOpen_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles ButtonOpen.Click
Dim editingFileName as String = ""
Dim saveAllowed As Boolean = True
' Displays the OpenFileDialog.
If (OpenFileDialog1.ShowDialog() = DialogResult.OK) Then
Dim userStream as System.IO.Stream
Try
' Opens the file stream for the file selected by the user.
userStream =OpenFileDialog1.OpenFile()
Me.RtfBoxMain.LoadFile(userStream, _
RichTextBoxStreamType.PlainText)
Finally
userStream.Close()
End Try
' Tries to get the file name selected by the user.
' Failure means that the application does not have
' unrestricted permission to the file.
Try
editingFileName = OpenFileDialog1.FileName
Catch ex As Exception
If TypeOf ex Is System.Security.SecurityException Then
' The application does not have unrestricted permission
' to the file so the save feature will be disabled.
saveAllowed = False
Else
Throw ex
End If
End Try
End If
End Sub
private void ButtonOpen_Click(object sender, System.EventArgs e)
{
String editingFileName = "";
Boolean saveAllowed = true;
// Displays the OpenFileDialog.
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
// Opens the file stream for the file selected by the user.
using (System.IO.Stream userStream = openFileDialog1.OpenFile())
{
this.RtfBoxMain.LoadFile(userStream,
RichTextBoxStreamType.PlainText);
userStream.Close();
}
// Tries to get the file name selected by the user.
// Failure means that the application does not have
// unrestricted permission to the file.
try
{
editingFileName = openFileDialog1.FileName;
}
catch (Exception ex)
{
if (ex is System.Security.SecurityException)
{
// The application does not have unrestricted permission
// to the file so the save feature will be disabled.
saveAllowed = false;
}
else
{
throw ex;
}
}
}
}
说明: |
---|
在 Visual C# 中,请确保添加启用事件处理程序的代码。以下代码使用上一示例中的代码,演示如何启用事件处理程序。this.ButtonOpen.Click += newSystem.Windows.Forms.EventHandler(this.ButtonOpen_Click); |
其他文件
有时,您需要向用户未指定的文件读取或写入数据,如当您必须保持应用程序设置时。在本地 Intranet 区域和 Internet 区域中,应用程序无权在本地文件中存储数据。但是,应用程序可以在独立存储中存储数据。独立存储是一个抽象的数据舱而非特定的存储位置,它含有一个或多个独立存储文件,这些文件称为存储区,其中包含存储数据的实际目录位置。独立存储的权限由 IsolatedStoragePermission 类进行控制,而不需要类似于 FileIOPermission 的文件访问权限。默认情况下,在本地 Intranet 区域和 Internet 区域中运行的应用程序可以使用独立存储来存储数据;但是,某些设置可能会有所不同,如磁盘配额。有关独立存储的更多信息,请参见 独立存储介绍。
下面的示例使用独立存储将数据写入存储区内的文件中。此示例需要 IsolatedStorageFilePermission 和 DomainIsolationByUser 枚举值。此示例演示从独立存储内的文件中读取 Button 控件的特定属性值,以及如何将该属性值写入独立存储内的文件中。Read 函数将在应用程序启动后调用;而 Write 函数将在应用程序终止前调用。此示例要求 Read 和 Write 函数作为 Form(包含一个名为 MainButton 的 Button 控件)的成员存在。
' Reads the button options from the isolated storage. Uses Default values
' for the button if the options file does not exist.
Public Sub Read()
Dim isoStore As System.IO.IsolatedStorage.IsolatedStorageFile = _
System.IO.IsolatedStorage.IsolatedStorageFile. _
GetUserStoreForDomain()
Dim filename As String = "options.txt"
Try
' Checks to see if the options.txt file exists.
If (isoStore.GetFileNames(filename).GetLength(0) <> 0) Then
' Opens the file because it exists.
Dim isos As New System.IO.IsolatedStorage.IsolatedStorageFileStream _
(filename, IO.FileMode.Open,isoStore)
Dim reader as System.IO.StreamReader
Try
reader = new System.IO.StreamReader(isos)
' Reads the values stored.
Dim converter As System.ComponentModel.TypeConverter
converter = System.ComponentModel.TypeDescriptor.GetConverter _
(GetType(Color))
Me.MainButton.BackColor = _
CType(converter.ConvertFromString _
(reader.ReadLine()), Color)
me.MainButton.ForeColor = _
CType(converter.ConvertFromString _
(reader.ReadLine()), Color)
converter = System.ComponentModel.TypeDescriptor.GetConverter _
(GetType(Font))
me.MainButton.Font = _
CType(converter.ConvertFromString _
(reader.ReadLine()), Font)
Catch ex As Exception
Debug.WriteLine("Cannot read options " + _
ex.ToString())
Finally
reader.Close()
End Try
End If
Catch ex As Exception
Debug.WriteLine("Cannot read options " + ex.ToString())
End Try
End Sub
' Writes the button options to the isolated storage.
Public Sub Write()
Dim isoStore As System.IO.IsolatedStorage.IsolatedStorageFile = _
System.IO.IsolatedStorage.IsolatedStorageFile. _
GetUserStoreForDomain()
Dim filename As String = "options.txt"
Try
' Checks if the file exists, and if it does, tries to delete it.
If (isoStore.GetFileNames(filename).GetLength(0) <> 0) Then
isoStore.DeleteFile(filename)
End If
Catch ex As Exception
Debug.WriteLine("Cannot delete file " + ex.ToString())
End Try
' Creates the options.txt file and writes the button options to it.
Dim writer as System.IO.StreamWriter
Try
Dim isos As New System.IO.IsolatedStorage.IsolatedStorageFileStream _
(filename, IO.FileMode.CreateNew, isoStore)
writer = New System.IO.StreamWriter(isos)
Dim converter As System.ComponentModel.TypeConverter
converter = System.ComponentModel.TypeDescriptor.GetConverter _
(GetType(Color))
writer.WriteLine(converter.ConvertToString( _
Me.MainButton.BackColor))
writer.WriteLine(converter.ConvertToString( _
Me.MainButton.ForeColor))
converter = System.ComponentModel TypeDescriptor.GetConverter _
(GetType(Font))
writer.WriteLine(converter.ConvertToString( _
Me.MainButton.Font))
Catch ex as Exception
Debug.WriteLine("Cannot write options " + ex.ToString())
Finally
writer.Close()
End Try
End Sub
// Reads the button options from the isolated storage. Uses default values
// for the button if the options file does not exist.
public void Read()
{
System.IO.IsolatedStorage.IsolatedStorageFile isoStore =
System.IO.IsolatedStorage.IsolatedStorageFile.
GetUserStoreForDomain();
string filename = "options.txt";
try
{
// Checks to see if the options.txt file exists.
if (isoStore.GetFileNames(filename).GetLength(0) != 0)
{
// Opens the file because it exists.
System.IO.IsolatedStorage.IsolatedStorageFileStream isos =
new System.IO.IsolatedStorage.IsolatedStorageFileStream
(filename, System.IO.FileMode.Open,isoStore);
System.IO.StreamReader reader = null;
try
{
reader = new System.IO.StreamReader(isos);
// Reads the values stored.
TypeConverter converter ;
converter = TypeDescriptor.GetConverter(typeof(Color));
this.MainButton.BackColor =
(Color)(converter.ConvertFromString(reader.ReadLine()));
this.MainButton.ForeColor =
(Color)(converter.ConvertFromString(reader.ReadLine()));
converter = TypeDescriptor.GetConverter(typeof(Font));
this.MainButton.Font =
(Font)(converter.ConvertFromString(reader.ReadLine()));
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine
("Cannot read options " + ex.ToString());
}
finally
{
reader.Close();
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine
("Cannot read options " + ex.ToString());
}
}
// Writes the button options to the isolated storage.
public void Write()
{
System.IO.IsolatedStorage.IsolatedStorageFile isoStore =
System.IO.IsolatedStorage.IsolatedStorageFile.
GetUserStoreForDomain();
string filename = "options.txt";
try
{
// Checks if the file exists and, if it does, tries to delete it.
if (isoStore.GetFileNames(filename).GetLength(0) != 0)
{
isoStore.DeleteFile(filename);
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine
("Cannot delete file " + ex.ToString());
}
// Creates the options file and writes the button options to it.
System.IO.StreamWriter writer = null;
try
{
System.IO.IsolatedStorage.IsolatedStorageFileStream isos = new
System.IO.IsolatedStorage.IsolatedStorageFileStream(filename,
System.IO.FileMode.CreateNew,isoStore);
writer = new System.IO.StreamWriter(isos);
TypeConverter converter ;
converter = TypeDescriptor.GetConverter(typeof(Color));
writer.WriteLine(converter.ConvertToString(
this.MainButton.BackColor));
writer.WriteLine(converter.ConvertToString(
this.MainButton.ForeColor));
converter = TypeDescriptor.GetConverter(typeof(Font));
writer.WriteLine(converter.ConvertToString(
this.MainButton.Font));
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine
("Cannot write options " + ex.ToString());
}
finally
{
writer.Close();
}
}
数据库访问
访问数据库所需的权限因数据库提供程序而异;但是,只有用适当权限运行的应用程序才可以通过数据连接访问数据库。有关访问数据库所需权限的更多信息,请参见 代码访问安全性和 ADO.NET。
如果您希望应用程序在部分信任环境中运行,导致无法直接访问数据库,则可以将 XML Web services 用作访问数据的备选方法。XML Web services 是一个软件,可以用 XML 通过网络以编程方式进行访问。借助于 XML Web services,应用程序可以跨代码组区域共享数据。默认情况下,本地 Intranet 和 Internet 区域中的应用程序被授予访问其原始站点的权限,从而使这些应用程序可以调用 XML Web services。有关如何生成 XML Web services 的信息,请参见 使用 ASP.NET 的 XML Web services。有关如何使用 XML Web services 的更多信息,请参见生成 XML Web services 客户端。
注册表访问
RegistryPermission 类控制对操作系统注册表的访问。默认情况下,只有本地运行的应用程序才能访问注册表。RegistryPermission 只向应用程序授予尝试访问注册表的权限;它不保证访问可获得成功,因为操作系统仍在对注册表强制应用安全性。
由于无法在部分信任环境下访问注册表,因此可能需要使用其他方法来存储数据。在存储应用程序设置时,请使用独立存储而不是注册表。独立存储还可以用于存储其他应用程序特定的文件。您还可以存储有关源服务器或源站点的全局应用程序信息,因为默认情况下,应用程序被授予访问其源站点的权限。
请参见
概念
参考
图形化客户端中的清单生成和编辑工具 (MageUI.exe)