Более безопасный доступ к файлам и данным в Windows Forms
Обновлен: Ноябрь 2007
.NET Framework использует разрешения для защиты ресурсов и данных. В зависимости от полученных разрешений приложение может выполнять чтение и запись данных. Если приложение выполняется среде c частичным доверием, то, возможно, доступ к данным будет запрещен или необходимо будет изменить способ доступа к данным.
При возникновении ограничений системы безопасности, имеются две возможности: подтверждение разрешения (предполагая, что оно было предоставлено приложению) или использование специальной версии кода, написанной для работы в условиях частичного доверия. В следующих разделах обсуждаются способы доступа к файлам, базам данных и реестру из приложений, работающих в среде с частичным доверием.
![]() |
---|
По умолчанию средства, развертывающие ClickOnce, настраивают экземпляры этой среды таким образом, чтобы требовать полного доверия от компьютеров, на которых они запущены. Если необходимо воспользоваться преимуществами повышенной безопасности при выполнении в среде с частичным доверием, следует изменить стандартное поведение либо в Visual Studio, либо в одном из средств SDK (пакет средств разработки программного обеспечения) для Windows (Mage.exe или MageUI.exe). Дополнительные сведения о системе безопасности Windows Forms и о том, как определить оптимальный уровень доверия для приложения, см. в разделе Общие сведения о безопасности в Windows Forms. |
Доступ к файлам
Класс FileIOPermission управляет доступом к файлам и папкам в .NET Framework. По умолчанию система безопасности не предоставляет разрешение FileIOPermission в средах с частичным доверием, таких как зоны локальной интрасети или Интернета. Однако приложение, которому требуется доступ к файлам, может работать в таких средах, если изменить структуру приложения или использовать другие методы доступа к файлам. По умолчанию зоне локальной интрасети предоставляется право на доступ к тому же узлу и к той же папке, чтобы подключаться к исходному узлу и считывать файлы из папки установки. Приложениям в зоне Интернета по умолчанию разрешено подключаться только к исходному узлу.
Файлы, определенные пользователем
Одним из способов разрешения проблем, связанных с отсутствием разрешения на доступ к файлам, является запрос у пользователя предоставления сведений о конкретном файле с помощью класса OpenFileDialog или SaveFileDialog. Взаимодействие с пользователем помогает получить некоторую уверенность в том, что приложение не сможет злоумышленно загрузить личные файлы или перезаписать важные файлы. Методы OpenFile и OpenFile предоставляют доступ на чтение и запись файла, открывая файловый поток для файла, указанного пользователем. Эти методы также помогают защитить файл пользователя, скрывая путь к файлу.
![]() |
---|
Данные разрешения зависят от того, в какой зоне находится приложение: интрасеть или Интернет. Приложения зоны Интернета могут использовать только класс OpenFileDialog, тогда как приложения интрасети имеют неограниченное разрешение на файловые диалоговые окна. |
Класс FileDialogPermission указывает какой тип диалогового окна может использовать приложение. В следующей таблице приведены значения, которые необходимо использовать для каждого класса FileDialog.
Класс |
Необходимое значение для доступа |
---|---|
![]() |
---|
Конкретные разрешения не запрашиваются до тех пор, пока не будет вызван метод OpenFile. |
Разрешение на отображение файлового диалогового окна не дает приложению полный доступ ко всем членам классов FileDialog, OpenFileDialog и SaveFileDialog. Точные разрешения, требуемые для вызова каждого метода, приведены в разделах, относящихся к этому методу в документации по библиотеке классов .NET Framework.
В следующем примере кода метод OpenFile используется для открытия указанного пользователем файла в элементе управления RichTextBox. Для этого пример требуется класс FileDialogPermission и связанное с ним значение перечисления Open. В примере показано, как обрабатывать исключение SecurityException, чтобы определить, нужно ли отключить функцию сохранения. В этом примере требуется, чтобы форма Form содержала элемент управления Button с именем ButtonOpen и элемент управления RichTextBox с именем RtfBoxMain.
![]() |
---|
Программная логика для функции сохранения в примере не представлена. |
[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); |
Другие файлы
Иногда необходимо считывать или записывать файлы, которые не указываются пользователем, например если требуется сохранить параметры приложения. В зонах локальной интрасети и Интернета приложение не имеет разрешения сохранять данные в локальном файле. Тем не менее, приложение может сохранять данные в изолированном хранилище. Изолированное хранилище — это абстрактный отсек данных (а не конкретное хранилище), содержащий один или несколько изолированных файлов хранения, называемых хранилищами, которые содержат сведения о действительных папках расположения данных. Разрешения доступа к файлам, такие как FileIOPermission, не обязательны; вместо этого класс IsolatedStoragePermission управляет разрешениями для изолированного хранилища. По умолчанию приложения, запущенные в зонах локальной интрасети и Интернета, могут хранить данные с помощью изолированного хранилища; однако такие параметры, как дисковая квота, могут меняться. Дополнительные сведения об изолированном хранилище см. в разделе Знакомство с изолированным хранилищем.
В следующем примере для записи данных в файл, расположенный в хранилище, используется изолированное хранилище. Для этого примера требуется разрешение IsolatedStorageFilePermission и значение перечисления DomainIsolationByUser. В примере демонстрируется чтение и запись определенных значений свойств элемента управления Button в файл в изолированном хранилище. Функция Read может быть вызвана после запуска приложения, а функция Write — до окончания работы приложения. В этом примере требуется существования функций Read и Write как членов формы Form, которая содержит элемент управления Buttonс именем MainButton.
' 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 как альтернативное средство доступа к данным. Веб-служба XML — это программа, доступ к которой можно получить программными средствами по сети с помощью XML. При помощи XML (веб-службы) приложения могут совместно использовать данные из различных зон. По умолчанию приложения в зонах локальной интрасети и Интернета получают право на доступ к исходным узлам, что позволяет им вызывать веб-службы XML. Сведения о построении веб-службы XML см. в разделе XML Web Services Using ASP.NET. Дополнительные сведения об использовании веб-службы XML см. в разделе Построение клиентов веб-служб XML.
Доступ к реестру
Класс RegistryPermission управляет доступом к реестру операционной системы. По умолчанию, доступ к реестру могут получить только локально запущенные приложения. Разрешение RegistryPermission предоставляет приложению только право выполнить попытку доступа к реестру; он не гарантирует, что доступ будет успешным, поскольку операционная система по-прежнему обеспечивает безопасность реестра.
Поскольку в среде с частичным доверием доступ к реестру получить не удается, необходимо найти другие способы хранения данных. Для хранения параметров приложения используйте вместо реестра изолированное хранилище. Изолированное сохранение можно использовать также для хранения файлов, относящихся к приложению. Можно хранить общие сведения приложения о сервере или исходном узле, поскольку по умолчанию приложение имеет право на доступ к исходному узлу.
См. также
Основные понятия
Более безопасная печать в Windows Forms
Дополнительные вопросы безопасности в формах Windows Forms
Общие сведения о безопасности в Windows Forms
Ссылки
Средство создания и редактирования манифеста (Mage.exe)
Средство создания и редактирования манифестов, графический клиент (MageUI.exe)