Condividi tramite


File e accesso ai dati più protetti in Windows Form

Aggiornamento: novembre 2007

Per 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 decide di aggiungere i vantaggi in termini di sicurezza 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 protezione 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 ciascuna classe FileDialog.

Classe

Valore di accesso richiesto

OpenFileDialog

Open

SaveFileDialog

Save

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 conoscere 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 disattivare 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.

 [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;
            }
        }
    }
}
Nota:

In Visual C#, assicurarsi di aggiungere il codice per l'attivazione del 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 Introduzione all'archiviazione isolata.

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 XML come mezzo alternativo per l'accesso ai dati. Un servizio Web XML è un componente software accessibile a livello di codice in una rete tramite XML. Con Servizi Web XML, le applicazioni possono condividere i dati tra più aree di gruppi di codice. Per impostazione predefinita, alle applicazioni nelle aree Intranet locale e Internet è concesso il diritto di accesso ai relativi siti di origine, che permette di chiamare un servizio Web XML. Per informazioni sulla creazione di un servizio Web XML, vedere Creare servizi Web XML mediante ASP.NET. Per ulteriori informazioni sull'utilizzo di un servizio Web XML, vedere Generazione di client di servizi Web XML.

Accesso al Registro di sistema

La classe RegistryPermission controlla l'accesso al Registro di sistema del sistema operativo. Per impostazione predefinita, soltanto le applicazioni in esecuzione localmente possono accedere al Registro di sistema. L'autorizzazione RegistryPermission concede a un'applicazione soltanto il diritto per tentare di accedere al Registro di sistema ma non garantisce che l'accesso venga eseguito correttamente, poiché esiste un ulteriore controllo di sicurezza da parte del sistema operativo.

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

Concetti

Stampa più protetta in Windows Form

Considerazioni aggiuntive sulla protezione in Windows Form

Cenni preliminari sulla protezione in Windows Form

Riferimenti

Strumento per la generazione e la modifica di manifesti (Mage.exe)

Strumento per la generazione e la modifica di manifesti con interfaccia grafica (MageUI.exe)

Altre risorse

Protezione di Windows Form