Поделиться через


Более безопасный доступ к файлам и данным в Windows Forms

Обновлен: Ноябрь 2007

.NET Framework использует разрешения для защиты ресурсов и данных. В зависимости от полученных разрешений приложение может выполнять чтение и запись данных. Если приложение выполняется среде c частичным доверием, то, возможно, доступ к данным будет запрещен или необходимо будет изменить способ доступа к данным.

При возникновении ограничений системы безопасности, имеются две возможности: подтверждение разрешения (предполагая, что оно было предоставлено приложению) или использование специальной версии кода, написанной для работы в условиях частичного доверия. В следующих разделах обсуждаются способы доступа к файлам, базам данных и реестру из приложений, работающих в среде с частичным доверием.

3wtbwh77.alert_note(ru-ru,VS.90).gifПримечание.

По умолчанию средства, развертывающие ClickOnce, настраивают экземпляры этой среды таким образом, чтобы требовать полного доверия от компьютеров, на которых они запущены. Если необходимо воспользоваться преимуществами повышенной безопасности при выполнении в среде с частичным доверием, следует изменить стандартное поведение либо в Visual Studio, либо в одном из средств SDK (пакет средств разработки программного обеспечения) для Windows (Mage.exe или MageUI.exe). Дополнительные сведения о системе безопасности Windows Forms и о том, как определить оптимальный уровень доверия для приложения, см. в разделе Общие сведения о безопасности в Windows Forms.

Доступ к файлам

Класс FileIOPermission управляет доступом к файлам и папкам в .NET Framework. По умолчанию система безопасности не предоставляет разрешение FileIOPermission в средах с частичным доверием, таких как зоны локальной интрасети или Интернета. Однако приложение, которому требуется доступ к файлам, может работать в таких средах, если изменить структуру приложения или использовать другие методы доступа к файлам. По умолчанию зоне локальной интрасети предоставляется право на доступ к тому же узлу и к той же папке, чтобы подключаться к исходному узлу и считывать файлы из папки установки. Приложениям в зоне Интернета по умолчанию разрешено подключаться только к исходному узлу.

Файлы, определенные пользователем

Одним из способов разрешения проблем, связанных с отсутствием разрешения на доступ к файлам, является запрос у пользователя предоставления сведений о конкретном файле с помощью класса OpenFileDialog или SaveFileDialog. Взаимодействие с пользователем помогает получить некоторую уверенность в том, что приложение не сможет злоумышленно загрузить личные файлы или перезаписать важные файлы. Методы OpenFile и OpenFile предоставляют доступ на чтение и запись файла, открывая файловый поток для файла, указанного пользователем. Эти методы также помогают защитить файл пользователя, скрывая путь к файлу.

3wtbwh77.alert_note(ru-ru,VS.90).gifПримечание.

Данные разрешения зависят от того, в какой зоне находится приложение: интрасеть или Интернет. Приложения зоны Интернета могут использовать только класс OpenFileDialog, тогда как приложения интрасети имеют неограниченное разрешение на файловые диалоговые окна.

Класс FileDialogPermission указывает какой тип диалогового окна может использовать приложение. В следующей таблице приведены значения, которые необходимо использовать для каждого класса FileDialog.

Класс

Необходимое значение для доступа

OpenFileDialog

Open

SaveFileDialog

Save

3wtbwh77.alert_note(ru-ru,VS.90).gifПримечание.

Конкретные разрешения не запрашиваются до тех пор, пока не будет вызван метод OpenFile.

Разрешение на отображение файлового диалогового окна не дает приложению полный доступ ко всем членам классов FileDialog, OpenFileDialog и SaveFileDialog. Точные разрешения, требуемые для вызова каждого метода, приведены в разделах, относящихся к этому методу в документации по библиотеке классов .NET Framework.

В следующем примере кода метод OpenFile используется для открытия указанного пользователем файла в элементе управления RichTextBox. Для этого пример требуется класс FileDialogPermission и связанное с ним значение перечисления Open. В примере показано, как обрабатывать исключение SecurityException, чтобы определить, нужно ли отключить функцию сохранения. В этом примере требуется, чтобы форма Form содержала элемент управления Button с именем ButtonOpen и элемент управления RichTextBox с именем RtfBoxMain.

3wtbwh77.alert_note(ru-ru,VS.90).gifПримечание.

Программная логика для функции сохранения в примере не представлена.

 [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;
            }
        }
    }
}
3wtbwh77.alert_note(ru-ru,VS.90).gifПримечание.

В 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)

Другие ресурсы

Безопасность Windows Forms