File e accesso ai dati più protetti in Windows Form
Per consentire di proteggere le risorse e i dati, in .NET Framework vengono utilizzate le autorizzazioni. La capacità di leggere o scrivere dati dipende dalle autorizzazioni concesse all'autorizzazione. Se l'applicazione viene eseguita in un ambiente parzialmente attendibile, è possibile che non si disponga dell'accesso ai dati o che occorra modificare la modalità di accesso ai dati.
Quando si incontra una restrizione di sicurezza, esistono due possibilità: eseguire l'asserzione dell'autorizzazione (assumendo che sia stata concessa all'applicazione) oppure utilizzare una versione della funzionalità scritta per funzionare in un ambiente parzialmente attendibile. Nelle sezioni successive viene illustrato come gestire l'accesso a file, database e Registro di sistema da applicazioni in esecuzione in un ambiente parzialmente attendibile.
Nota
Per impostazione predefinita, gli strumenti che generano distribuzioni ClickOnce impostano queste ultime in modo che siano necessarie autorizzazioni di attendibilità totale nei computer in cui vengono eseguite. Se si opta per sfruttare i vantaggi in termini di sicurezza aggiuntiva offerti dall'esecuzione in un ambiente parzialmente attendibile, è necessario modificare questa impostazione predefinita in Visual Studio o utilizzando uno degli strumenti di Windows Software Development Kit (SDK) (Mage.exe o MageUI.exe). Per ulteriori informazioni sulla sicurezza di Windows Form e su come determinare il livello di attendibilità appropriato per un'applicazione, vedere Cenni preliminari sulla sicurezza in Windows Form.
Accesso ai file
La classe FileIOPermission controlla l'accesso a file e cartelle in .NET Framework. Per impostazione predefinita, il sistema di sicurezza non concede l'autorizzazione FileIOPermission agli ambienti parzialmente attendibili quali le aree Intranet locale e Internet. Un'applicazione che richieda l'accesso ai file è comunque in grado di funzionare in tali ambienti se si modifica la progettazione o si utilizzano metodi diversi per l'accesso ai file. Per impostazione predefinita, all'area Intranet locale viene concesso il diritto per accedere allo stesso sito e alla stessa directory, riconnettersi al sito di origine e leggere dalla relativa directory di installazione. All'area Internet, invece, per impostazione predefinita viene concesso unicamente il diritto per riconnettersi al sito di origine.
File specificati dall'utente
Per gestire la mancanza di autorizzazione di accesso ai file, è possibile chiedere all'utente di fornire informazioni specifiche sui file utilizzando la classe OpenFileDialog o SaveFileDialog. Questo assicura che l'applicazione non possa caricare file riservati né sovrascrivere file importanti. I metodi OpenFile e OpenFile forniscono l'accesso in lettura e scrittura ai file mediante l'apertura del flusso per il file specificato dall'utente. Per proteggere il file dell'utente, il percorso del file viene nascosto.
Nota
Il comportamento di queste autorizzazioni dipende dall'area in cui viene eseguita l'applicazione, ovvero Internet o Intranet. Le applicazioni in esecuzione nell'area Internet possono utilizzare soltanto OpenFileDialog, mentre a quelle nell'area Intranet vengono concesse autorizzazioni illimitate sulla finestra di dialogo dei file.
La classe FileDialogPermission specifica il tipo di finestra di dialogo dei file che può essere utilizzato dall'applicazione. Nella tabella riportata di seguito viene indicato il valore necessario per poter utilizzare ogni classe FileDialog.
Classe |
Valore di accesso richiesto |
---|---|
Nota
L'autorizzazione specifica non è richiesta finché non viene effettivamente chiamato il metodo OpenFile.
L'autorizzazione per la visualizzazione di una finestra di dialogo dei file non assegna all'applicazione l'accesso completo a tutti i membri delle classi FileDialog, OpenFileDialog e SaveFileDialog. Per sapere quali siano esattamente le autorizzazioni necessarie per chiamare ciascun metodo, fare riferimento all'argomento relativo al metodo nella documentazione sulla libreria di classi di .NET Framework.
Nell'esempio riportato di seguito viene utilizzato il metodo OpenFile per aprire un file specificato dall'utente in un controllo RichTextBox. Questo esempio richiede FileDialogPermission e il valore di enumerazione Open associato. Nell'esempio viene illustrato come gestire l'eccezione SecurityException per determinare se occorre disabilitare la funzionalità di salvataggio. Nell'esempio si presuppone che in Form sia contenuto un controllo Button denominato ButtonOpen e un controllo RichTextBox denominato RtfBoxMain.
Nota
Nell'esempio non è illustrata la logica di programmazione della funzionalità di salvataggio.
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;
}
}
}
}
Nota
In Visual C#, assicurarsi di aggiungere il codice per abilitare il gestore eventi. Utilizzando il codice dell'esempio precedente, nel codice riportato di seguito viene illustrato come attivare il gestore eventi.this.ButtonOpen.Click += newSystem.Windows.Forms.EventHandler(this.ButtonOpen_Click);
Altri file
In alcuni casi sarà necessario leggere o scrivere su file non specificati dall'utente, ad esempio quando occorre rendere persistenti le impostazioni delle applicazioni. Nelle aree Intranet locale e Internet l'applicazione non dispone dell'autorizzazione per l'archiviazione dei dati in un file locale. Tuttavia, i dati potranno essere memorizzati in un'area di archiviazione isolata, ovvero in un contesto dati astratto (non uno specifico percorso di archiviazione) contenente uno o più file di archiviazione isolata, detti archivi, che contengono gli effettivi percorsi alle directory in cui sono archiviati i dati. Non è necessario disporre delle autorizzazioni di accesso ai file quali FileIOPermission. Le autorizzazioni per l'archiviazione isolata, infatti, sono controllate dalla classe IsolatedStoragePermission. Per impostazione predefinita, le applicazioni eseguite nelle aree Intranet locale e Internet possono memorizzare i dati mediante l'archiviazione isolata. Alcune impostazioni, tuttavia, ad esempio la quota disco, possono variare. Per ulteriori informazioni sull'archiviazione isolata, vedere Spazio di memorizzazione isolato.
Nell'esempio che segue viene utilizzata l'archiviazione isolata per scrivere dati in un file contenuto in un archivio. Questo esempio richiede IsolatedStorageFilePermission e il valore di enumerazione DomainIsolationByUser. Nell'esempio viene illustrato come leggere e scrivere i valori di alcune proprietà del controllo Button in un file nell'archiviazione isolata. La funzione Read viene chiamata dopo l'avvio dell'applicazione e la funzione Write prima del termine dell'applicazione. Si presuppone che le funzioni Read e Write siano membri di un oggetto Form contenente un controllo Button denominato 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();
}
}
Accesso al database
Le autorizzazioni necessarie per l'accesso a un database variano in base al provider del database. Tuttavia, soltanto le applicazioni in esecuzione con le autorizzazioni appropriate possono accedere a un database tramite una connessione dati. Per ulteriori informazioni sulle autorizzazioni necessarie per l'accesso a un database, vedere Sicurezza dall'accesso di codice e ADO.NET.
Se non è possibile accedere direttamente a un database poiché si desidera eseguire l'applicazione in un ambiente parzialmente attendibile, è possibile utilizzare un servizio Web come mezzo alternativo per l'accesso ai dati. Un servizio Web è un componente software accessibile a livello di codice su una rete. Con i servizi Web, le applicazioni possono condividere i dati tra più aree di gruppi di codice. Per impostazione predefinita, alle applicazioni nelle aree Intranet locale e Internet è attribuito diritto di accesso ai relativi siti di origine, il che consente a tali applicazioni di chiamare un servizio Web sullo stesso server. Per ulteriori informazioni vedere ASP.NET AJAX and Web Services o Windows Communication Foundation.
Accesso al Registro di sistema
La classe RegistryPermission controlla l'accesso al Registro di sistema del sistema operativo. Per impostazione predefinita, solo le applicazioni con esecuzione locale possono accedere al Registro di sistema. RegistryPermission attribuisce a un'applicazione soltanto il diritto di tentare di accedere al Registro di sistema; non garantisce che il tentativo riuscirà, in quanto il sistema operativo continua a proteggere il Registro di sistema.
Non essendo possibile accedere al Registro di sistema in situazioni di attendibilità parziale, può essere necessario trovare altri metodi per l'archiviazione dei dati. Per memorizzare le impostazioni dell'applicazione è possibile utilizzare in alternativa l'archiviazione isolata. L'archiviazione isolata può essere utilizzata anche per memorizzare altri file specifici dell'applicazione. È anche possibile memorizzare le informazioni globali relative al server o al sito di origine, poiché a un'applicazione è concesso automaticamente il diritto per l'accesso al sito di origine.
Vedere anche
Riferimenti
Mage.exe (Strumento per la generazione e la modifica di manifesti)
MageUI.exe (Strumento per la generazione e la modifica di manifesti, client grafico)
Concetti
Stampa più protetta in Windows Form
Considerazioni aggiuntive sulla sicurezza in Windows Form
Cenni preliminari sulla sicurezza in Windows Form