Bezpieczniejszy dostęp do plików i danych w formularzach systemu Windows

Program .NET Framework używa uprawnień do ochrony zasobów i danych. Miejsce, w którym aplikacja może odczytywać lub zapisywać dane, zależy od uprawnień przyznanych aplikacji. Gdy aplikacja działa w środowisku częściowo zaufania, może nie mieć dostępu do danych lub może być konieczne zmiana sposobu uzyskiwania dostępu do danych.

W przypadku wystąpienia ograniczenia zabezpieczeń masz dwie opcje: potwierdzanie uprawnień (przy założeniu, że udzielono jej aplikacji) lub użycie wersji funkcji napisanej w celu pracy w częściowym zaufaniu. W poniższych sekcjach omówiono sposób pracy z dostępem do plików, bazy danych i rejestru z aplikacji działających w środowisku częściowo zaufania.

Uwaga

Domyślnie narzędzia generujące wdrożenia Technologii ClickOnce domyślnie domyślnie żądają pełnego zaufania z komputerów, na których są uruchamiane. Jeśli zdecydujesz, że chcesz, aby dodatkowe korzyści zabezpieczeń były uruchamiane w częściowym zaufaniu, musisz zmienić tę wartość domyślną w programie Visual Studio lub jednym z narzędzi zestawu Windows SDK (Mage.exe lub MageUI.exe). Aby uzyskać więcej informacji na temat zabezpieczeń formularzy systemu Windows oraz sposobu określania odpowiedniego poziomu zaufania dla aplikacji, zobacz Security in Windows Forms Overview (Zabezpieczenia w formularzach systemu Windows — omówienie).

Dostęp do plików

Klasa FileIOPermission kontroluje dostęp do plików i folderów w programie .NET Framework. Domyślnie system zabezpieczeń nie udziela FileIOPermission uprawnień do częściowych środowisk zaufania, takich jak lokalny intranet i strefy internetowe. Jednak aplikacja, która wymaga dostępu do plików, nadal może działać w tych środowiskach, jeśli zmodyfikujesz projekt aplikacji lub użyjesz różnych metod uzyskiwania dostępu do plików. Domyślnie lokalna strefa intranetowa ma prawo dostępu do tej samej lokacji i tego samego dostępu do katalogu, aby połączyć się z lokacją źródła i odczytywać z katalogu instalacyjnego. Domyślnie strefa internetowa ma tylko prawo do łączenia się z witryną pochodzenia.

Pliki określone przez użytkownika

Jednym ze sposobów radzenia sobie z brakiem uprawnień dostępu do plików jest monitowanie użytkownika o podanie określonych informacji o pliku przy użyciu OpenFileDialog klasy lub SaveFileDialog . Ta interakcja użytkownika pomaga zapewnić, że aplikacja nie może złośliwie załadować plików prywatnych ani zastąpić ważnych plików. Metody OpenFile i OpenFile zapewniają dostęp do plików odczytu i zapisu, otwierając strumień plików dla określonego przez użytkownika. Metody pomagają również chronić plik użytkownika, zaciemniając ścieżkę pliku.

Uwaga

Te uprawnienia różnią się w zależności od tego, czy aplikacja znajduje się w strefie internetowej, czy w strefie intranetu. Aplikacje strefy internetowej mogą używać OpenFileDialogtylko aplikacji intranetowych, a aplikacje intranetowe mają nieograniczone uprawnienia do okna dialogowego plików.

Klasa FileDialogPermission określa, jakiego typu okna dialogowego pliku może używać aplikacja. W poniższej tabeli przedstawiono wartość, która musi być używana przez każdą FileDialog klasę.

Klasa Wymagana wartość dostępu
OpenFileDialog Open
SaveFileDialog Save

Uwaga

Określone uprawnienie nie jest wymagane, dopóki OpenFile metoda nie zostanie wywołana.

Uprawnienie do wyświetlania okna dialogowego pliku nie udziela aplikacji pełnego dostępu do wszystkich elementów członkowskich FileDialogklas , OpenFileDialogi SaveFileDialog . Aby uzyskać dokładne uprawnienia wymagane do wywołania każdej metody, zobacz temat referencyjny dla tej metody w dokumentacji biblioteki klas programu .NET Framework.

W poniższym przykładzie kodu użyto OpenFile metody , aby otworzyć plik określony przez użytkownika w kontrolce RichTextBox . W przykładzie jest wymagana FileDialogPermission i skojarzona Open wartość wyliczenia. W przykładzie pokazano, jak obsłużyć funkcję SecurityException w celu określenia, czy funkcja zapisywania powinna być wyłączona. W tym przykładzie Form wymagana jest kontrolka Button o nazwie ButtonOpen, a kontrolka RichTextBox o nazwie RtfBoxMain.

Uwaga

Logika programowania dla funkcji zapisywania nie jest wyświetlana w przykładzie.

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;  
            }  
        }  
    }  
}  

Uwaga

W programie Visual C# upewnij się, że dodasz kod umożliwiający obsługę zdarzeń. Korzystając z kodu z poprzedniego przykładu, poniższy kod pokazuje, jak włączyć procedurę obsługi zdarzeń.this.ButtonOpen.Click += newSystem.Windows.Forms.EventHandler(this.ButtonOpen_Click);

Inne pliki

Czasami trzeba będzie odczytywać lub zapisywać w plikach, których użytkownik nie określa, na przykład w przypadku utrzymywania ustawień aplikacji. W lokalnych strefach intranetowych i internetowych aplikacja nie będzie miała uprawnień do przechowywania danych w pliku lokalnym. Jednak aplikacja będzie mogła przechowywać dane w izolowanym magazynie. Izolowany magazyn to abstrakcyjny przedział danych (nie określona lokalizacja magazynu), który zawiera co najmniej jeden izolowany plik magazynu, nazywany magazynami zawierający rzeczywiste lokalizacje katalogów, w których są przechowywane dane. Uprawnienia dostępu do plików, takie jak FileIOPermission nie są wymagane; IsolatedStoragePermission zamiast tego klasa kontroluje uprawnienia dla izolowanego magazynu. Domyślnie aplikacje działające w lokalnym intranecie i strefach internetowych mogą przechowywać dane przy użyciu izolowanego magazynu; jednak ustawienia, takie jak limit przydziału dysku, mogą się różnić. Aby uzyskać więcej informacji na temat izolowanego magazynu, zobacz Izolowany magazyn.

W poniższym przykładzie użyto izolowanego magazynu do zapisywania danych w pliku znajdującym się w magazynie. W przykładzie jest wymagana IsolatedStorageFilePermissionDomainIsolationByUser wartość i wartość wyliczenia. W tym przykładzie pokazano odczytywanie i zapisywanie określonych wartości właściwości kontrolki Button w pliku w izolowanym magazynie. Funkcja Read zostanie wywołana po uruchomieniu aplikacji, a Write funkcja zostanie wywołana przed zakończeniem aplikacji. Przykład wymaga, aby Read funkcje i Write istniały jako elementy członkowskie obiektu Form zawierającego kontrolkę Button o nazwie 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();  
    }  
}  

Dostęp do bazy danych

Uprawnienia wymagane do uzyskania dostępu do bazy danych różnią się w zależności od dostawcy bazy danych; jednak tylko aplikacje z odpowiednimi uprawnieniami mogą uzyskiwać dostęp do bazy danych za pośrednictwem połączenia danych. Aby uzyskać więcej informacji na temat uprawnień wymaganych do uzyskania dostępu do bazy danych, zobacz Zabezpieczenia dostępu kodu i ADO.NET.

Jeśli nie możesz uzyskać bezpośredniego dostępu do bazy danych, ponieważ aplikacja ma działać w częściowym zaufaniu, możesz użyć usługi sieci Web jako alternatywnego sposobu uzyskiwania dostępu do danych. Usługa sieci Web to oprogramowanie, które może być programowo dostępne za pośrednictwem sieci. Za pomocą usług sieci Web aplikacje mogą udostępniać dane między strefami grup kodu. Domyślnie aplikacje w lokalnych strefach intranetowych i internetowych mają prawo dostępu do swoich witryn pochodzenia, co umożliwia wywoływanie usługi sieci Web hostowanej na tym samym serwerze. Aby uzyskać więcej informacji, zobacz Usługi sieci Web w programie ASP.NET AJAX lub Windows Communication Foundation.

Dostęp do rejestru

Klasa RegistryPermission kontroluje dostęp do rejestru systemu operacyjnego. Domyślnie tylko aplikacje uruchomione lokalnie mogą uzyskiwać dostęp do rejestru. RegistryPermission przyznaje aplikacji prawo do wypróbowania dostępu do rejestru; Nie gwarantuje to powodzenia dostępu, ponieważ system operacyjny nadal wymusza zabezpieczenia rejestru.

Ponieważ nie można uzyskać dostępu do rejestru w ramach częściowego zaufania, może być konieczne znalezienie innych metod przechowywania danych. Podczas przechowywania ustawień aplikacji użyj izolowanego magazynu zamiast rejestru. Izolowany magazyn może być również używany do przechowywania innych plików specyficznych dla aplikacji. Można również przechowywać globalne informacje o aplikacji o serwerze lub lokacji pochodzenia, ponieważ domyślnie aplikacja ma prawo dostępu do witryny jej źródła.

Zobacz też