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ż
- Bezpieczniejsze drukowanie w formularzach Windows Forms
- Dodatkowe zagadnienia z zakresu zabezpieczeń dotyczące formularzy Windows Forms
- Przegląd zabezpieczeń w formularzach Windows Forms
- Zabezpieczenia formularzy Windows Forms
- Mage.exe (narzędzie generowania manifestu i edytowania)
- MageUI.exe (narzędzie generowania i edytowania manifestu, klient z interfejsem graficznym)
.NET Desktop feedback