Compartir por


Acceso a archivos y datos más seguros en formularios Windows Forms

Importante

Este contenido solo se aplica a .NET Framework a menos que se especifique lo contrario.

.NET Framework usa permisos para ayudar a proteger los recursos y los datos. Donde la aplicación puede leer o escribir datos depende de los permisos concedidos a la aplicación. Cuando la aplicación se ejecuta en un entorno de confianza parcial, es posible que no tenga acceso a los datos o que tenga que cambiar la forma en que accede a los datos.

Cuando encuentre una restricción de seguridad, tiene dos opciones: aserte el permiso (suponiendo que se haya concedido a la aplicación) o use una versión de la característica escrita para funcionar en confianza parcial. En las secciones siguientes se describe cómo trabajar con el acceso a archivos, bases de datos y registro desde aplicaciones que se ejecutan en un entorno de confianza parcial.

Nota:

De forma predeterminada, las herramientas que generan implementaciones de ClickOnce tienen como valor predeterminado estas implementaciones para solicitar plena confianza desde los equipos en los que se ejecutan. Si decide que quiere las ventajas de seguridad agregadas de ejecutarse en confianza parcial, debe cambiar este valor predeterminado en Visual Studio o en una de las herramientas de Windows SDK (Mage.exe o MageUI.exe). Para obtener más información sobre la seguridad de Windows Forms y sobre cómo determinar el nivel de confianza adecuado para la aplicación, consulte Seguridad en La información general de Windows Forms.

Acceso a archivos

La clase FileIOPermission controla el acceso a archivos y carpetas en el .NET Framework. De forma predeterminada, el sistema de seguridad no concede FileIOPermission a entornos de confianza parciales, como la intranet local y las zonas de Internet. Sin embargo, una aplicación que requiere acceso a archivos puede seguir funcionando en estos entornos si modifica el diseño de la aplicación o usa métodos diferentes para acceder a los archivos. De forma predeterminada, a la zona de intranet local se le concede el derecho de tener el mismo acceso al sitio y al mismo acceso de directorio, para volver a conectarse al sitio de su origen y leer desde su directorio de instalación. De forma predeterminada, a la zona de Internet solo se le concede el derecho de volver a conectarse al sitio de su origen.

archivos de User-Specified

Una manera de tratar con no tener permiso de acceso a archivos es pedir al usuario que proporcione información de archivo específica mediante la OpenFileDialog clase o SaveFileDialog . Esta interacción del usuario ayuda a garantizar que la aplicación no puede cargar archivos privados de forma malintencionada ni sobrescribir archivos importantes. Los métodos OpenFile y OpenFile proporcionan acceso de lectura y escritura a los archivos abriendo el flujo del archivo especificado por el usuario. Los métodos también ayudan a proteger el archivo del usuario ocultando la ruta de acceso del archivo.

Nota:

Estos permisos difieren en función de si la aplicación está en la zona de Internet o en la zona intranet. Las aplicaciones de zona de Internet solo pueden usar el OpenFileDialog, mientras que las aplicaciones de intranet tienen permiso sin restricciones para el cuadro de diálogo de archivos.

La FileDialogPermission clase especifica qué tipo de cuadro de diálogo de archivo puede usar la aplicación. En la tabla siguiente se muestra el valor que debe tener para usar cada FileDialog clase.

Clase Valor de acceso obligatorio
OpenFileDialog Open
SaveFileDialog Save

Nota:

El permiso específico no se solicita hasta que realmente se llama al método OpenFile.

El permiso para mostrar un cuadro de diálogo de archivo no concede a la aplicación acceso completo a todos los miembros de las FileDialogclases , OpenFileDialogy SaveFileDialog . Para obtener los permisos exactos necesarios para llamar a cada método, consulte el tema de referencia de ese método en la documentación de la biblioteca de clases de .NET Framework.

En el ejemplo de código siguiente se usa el método OpenFile para abrir un archivo especificado por el usuario en un control RichTextBox. El ejemplo requiere FileDialogPermission y el valor de enumeración asociado Open . En el ejemplo se demuestra cómo manejar el SecurityException para determinar si se debe deshabilitar la función de guardado. En este ejemplo se requiere que su Form tenga un control denominado Button y un control denominado ButtonOpen.

Nota:

La lógica de programación de la característica de guardado no se muestra en el ejemplo.

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:

En Visual C#, asegúrese de agregar código para habilitar el controlador de eventos. Con el código del ejemplo anterior, el código siguiente muestra cómo habilitar el controlador de eventos.this.ButtonOpen.Click += newSystem.Windows.Forms.EventHandler(this.ButtonOpen_Click);

Otros archivos

A veces, tendrá que leer o escribir en archivos que el usuario no especifique, como cuando deba conservar la configuración de la aplicación. En la intranet local y las zonas de Internet, la aplicación no tendrá permiso para almacenar datos en un archivo local. Sin embargo, la aplicación podrá almacenar datos en almacenamiento aislado. El almacenamiento aislado es un compartimiento de datos abstracto (no una ubicación de almacenamiento específica) que contiene uno o varios archivos de almacenamiento aislados, denominados almacenes, que contienen las ubicaciones de directorio reales donde se almacenan los datos. Los permisos de acceso a archivos como FileIOPermission no son necesarios; en su lugar, la IsolatedStoragePermission clase controla los permisos para el almacenamiento aislado. De forma predeterminada, las aplicaciones que se ejecutan en la intranet local y las zonas de Internet pueden almacenar datos mediante almacenamiento aislado; sin embargo, la configuración como la cuota de disco puede variar. Para más información sobre el almacenamiento aislado, consulte Almacenamiento aislado.

En el ejemplo siguiente se usa el almacenamiento aislado para escribir datos en un archivo ubicado en un almacén. El ejemplo requiere IsolatedStorageFilePermission y el valor de enumeración DomainIsolationByUser. En el ejemplo se muestra cómo leer y escribir determinados valores de propiedad del Button control en un archivo en almacenamiento aislado. La función Read se llamaría después de iniciar la aplicación y la función Write se llamaría antes de que finalice la aplicación. El ejemplo requiere que las Read funciones y Write existan como miembros de un Form objeto que contenga un Button control denominado 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();
    }
}

Acceso a la base de datos

Los permisos necesarios para acceder a una base de datos varían en función del proveedor de base de datos; Sin embargo, solo las aplicaciones que se ejecutan con los permisos adecuados pueden acceder a una base de datos a través de una conexión de datos. Para obtener más información sobre los permisos necesarios para acceder a una base de datos, consulte Seguridad de acceso al código y ADO.NET.

Si no puede acceder directamente a una base de datos porque desea que la aplicación se ejecute en confianza parcial, puede usar un servicio web como medio alternativo para acceder a los datos. Un servicio web es un fragmento de software al que se puede acceder mediante programación a través de una red. Con los servicios web, las aplicaciones pueden compartir datos entre zonas de grupo de código. De forma predeterminada, a las aplicaciones de la intranet local y a las zonas de Internet se les concede el derecho de acceder a sus sitios de origen, lo que les permite llamar a un servicio web hospedado en el mismo servidor. Para obtener más información, vea Servicios web en ASP.NET AJAX o Windows Communication Foundation.

Acceso al Registro

La RegistryPermission clase controla el acceso al registro del sistema operativo. De forma predeterminada, solo las aplicaciones que se ejecutan localmente pueden acceder al registro. RegistryPermission solo concede a una aplicación el derecho de probar el acceso al Registro; no garantiza que el acceso se realice correctamente, ya que el sistema operativo sigue aplicando seguridad en el Registro.

Dado que no puede acceder al registro bajo confianza parcial, es posible que tenga que encontrar otros métodos para almacenar los datos. Al almacenar la configuración de la aplicación, use el almacenamiento aislado en lugar del registro. El almacenamiento aislado también se puede usar para almacenar otros archivos específicos de la aplicación. También puede almacenar información de aplicación global sobre el servidor o el sitio de origen, ya que, de forma predeterminada, se concede a una aplicación el derecho de acceder al sitio de su origen.

Consulte también