다음을 통해 공유


Windows Forms의 파일 및 데이터 액세스 추가 보안

업데이트: 2007년 11월

.NET Framework에서는 권한을 통해 리소스와 데이터를 보호합니다. 응용 프로그램이 데이터를 읽거나 쓸 수 있는 위치는 응용 프로그램에 부여된 권한에 따라 다릅니다. 부분 신뢰 환경에서 응용 프로그램을 실행할 때는 데이터에 액세스할 수 없거나 데이터 액세스 방법을 변경해야 할 수도 있습니다.

보안 제한이 있으면 응용 프로그램에 권한이 부여되었다고 간주하고 권한을 어설션하거나 부분 신뢰 환경에서 작동하도록 작성된 버전의 기능을 사용할 수 있습니다. 다음 단원에서는 부분 신뢰 환경에서 실행되는 응용 프로그램에서 파일, 데이터베이스 및 레지스트리에 액세스하는 방법을 설명합니다.

참고:

기본적으로 ClickOnce 배포를 생성하는 도구는 이 배포가 실행되는 컴퓨터에서 완전 신뢰를 요청하도록 지정합니다. 부분 신뢰 환경에서 실행될 때의 보안상 이점을 얻으려면 Visual Studio나 Windows SDK(소프트웨어 개발 키트) 도구인 Mage.exe 또는 MageUI.exe 중 하나에서 이 기본값을 변경해야 합니다. Windows Forms 보안에 대한 자세한 내용과 응용 프로그램의 적절한 신뢰 수준을 결정하는 방법에 대한 자세한 내용은 Windows Forms의 보안 개요를 참조하십시오.

파일 액세스

.NET Framework에서는 FileIOPermission 클래스가 파일 및 폴더 액세스를 제어합니다. 기본적으로 보안 시스템에서는 로컬 인트라넷과 인터넷 영역 등의 부분 신뢰 환경에는 FileIOPermission을 부여하지 않습니다. 그러나 응용 프로그램의 디자인을 수정하거나 다른 파일 액세스 방법을 사용하면 파일 액세스가 필요한 응용 프로그램이 이런 환경에서도 여전히 작동할 수 있습니다. 기본적으로 로컬 인트라넷 영역에는 사이트 액세스와 디렉터리 액세스를 동일하게 지정할 수 있는 권한, 원본 사이트에 다시 연결할 수 있는 권한 및 설치 디렉터리에서 읽을 수 있는 권한이 부여됩니다. 기본적으로 인터넷 영역에는 원본 사이트에 다시 연결할 수 있는 권한만 부여됩니다.

사용자 지정 파일

파일 액세스 권한을 가지고 있지 않은 경우 이를 처리하는 한 가지 방법은 OpenFileDialog 또는 SaveFileDialog 클래스를 사용하여 사용자에게 특정 파일 정보를 입력하도록 요구하는 것입니다. 이런 사용자 상호 작용을 이용하면 응용 프로그램에서 악의적으로 개인 파일을 로드하거나 중요한 파일을 덮어쓰는 것을 어느 정도 방지할 수 있습니다. OpenFileOpenFile 메서드는 사용자가 지정한 파일의 파일 스트림을 열어 파일에 대한 읽기 및 쓰기 액세스를 제공합니다. 또한 파일의 경로를 표시하지 않음으로써 사용자의 파일을 보호합니다.

참고:

이러한 권한은 응용 프로그램이 인터넷 영역에 있는지 인트라넷 영역에 있는지에 따라 달라집니다. 인터넷 영역 응용 프로그램에서는 OpenFileDialog 권한만 사용할 수 있는 반면 인트라넷 응용 프로그램에서는 파일 대화 상자 권한에 제한이 없습니다.

FileDialogPermission 클래스는 응용 프로그램에서 사용할 수 있는 파일 대화 상자의 종류를 지정합니다. 다음 표에서는 각 FileDialog 클래스를 사용하는 데 필요한 값을 보여 줍니다.

클래스

필요한 액세스 값

OpenFileDialog

Open

SaveFileDialog

Save

참고:

OpenFile 메서드가 실제로 호출되기 전까지는 특정 권한이 요청되지 않습니다.

파일 대화 상자 표시 권한을 부여 받았다고 하여 응용 프로그램에서 FileDialog, OpenFileDialogSaveFileDialog 클래스의 모든 멤버에 완전하게 액세스할 수 있는 것은 아닙니다. 각 메서드 호출에 필요한 정확한 권한은 .NET Framework 클래스 라이브러리 설명서에서 해당 메서드에 대한 참조 항목을 참조하십시오.

다음 코드 예제에서는 OpenFile 메서드를 사용하여 사용자 지정 파일을 RichTextBox 컨트롤에서 엽니다. 이 예제에는 FileDialogPermission 및 관련된 Open 열거형 값이 필요합니다. 이 예제에서는 SecurityException을 처리하여 저장 기능을 비활성화할지 여부를 결정하는 방법을 보여 줍니다. 이 예제를 실행하려면 Form에 이름이 ButtonOpen인 Button 컨트롤과 이름이 RtfBoxMain인 RichTextBox 컨트롤이 있어야 합니다.

참고:

저장 기능에 대한 프로그래밍 논리는 이 예제에서 보여 주지 않습니다.

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

Visual C#에서 이벤트 처리기를 사용하기 위한 코드를 추가하십시오. 다음 코드에서는 위 예제의 코드를 사용하여 이벤트 처리기를 사용하는 방법을 보여 줍니다.this.ButtonOpen.Click += newSystem.Windows.Forms.EventHandler(this.ButtonOpen_Click);

기타 파일

응용 프로그램 설정을 유지해야 하는 경우와 같이 사용자가 지정하지 않은 파일을 읽거나 써야 하는 경우가 있습니다. 로컬 인트라넷과 인터넷 영역에서는 로컬 파일에 데이터를 저장할 수 있는 권한이 응용 프로그램에 부여되지 않습니다. 그러나 응용 프로그램에서 격리된 저장소에 데이터를 저장할 수는 있습니다. 격리된 저장소는 구체적인 저장소 위치가 아닌 추상적인 데이터 구획으로, 데이터가 저장된 실제 디렉터리 위치가 포함되어 있으며 저장소라고도 하는 하나 이상의 격리된 저장소 파일을 포함합니다. FileIOPermission과 같은 파일 액세스 권한은 필요하지 않습니다. 대신 IsolatedStoragePermission 클래스가 격리된 저장소에 대한 권한을 제어합니다. 기본적으로 로컬 인트라넷과 인터넷 영역에서 실행되는 응용 프로그램은 격리된 저장소를 사용하여 데이터를 저장할 수 있지만 디스크 할당량과 같은 설정은 다를 수 있습니다. 격리된 저장소에 대한 자세한 내용은 격리된 저장소 소개를 참조하십시오.

다음 예제에서는 격리된 저장소를 사용하여 저장소에 있는 파일에 데이터를 씁니다. 이 예제에는 IsolatedStorageFilePermissionDomainIsolationByUser 열거형 값이 필요합니다. 이 예제는 Button 컨트롤의 특정 속성 값을 격리된 저장소의 파일에서 읽고 쓰는 방법을 보여 줍니다. Read 함수는 응용 프로그램이 시작된 후 호출되고 Write 함수는 응용 프로그램이 끝나기 전에 호출됩니다. 이 예제를 실행하려면 Read 및 Write 함수가 이름이 MainButton인 Button컨트롤이 포함된 Form의 멤버여야 합니다.

' 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();
    }
}

데이터베이스 액세스

데이터베이스 액세스에 필요한 권한은 데이터베이스 공급자에 따라 다르지만 적절한 권한을 사용하여 실행되는 응용 프로그램만 데이터 연결을 통해 데이터베이스에 액세스할 수 있습니다. 데이터베이스에 액세스하는 데 필요한 권한에 대한 자세한 내용은 코드 액세스 보안 및 ADO.NET를 참조하십시오.

부분 신뢰 환경에서 응용 프로그램을 실행하려고 하기 때문에 데이터베이스에 직접 액세스할 수 없으면 대신 XML Web services를 사용하여 데이터에 액세스할 수 있습니다. XML Web services는 XML을 통해 네트워크에서 프로그래밍 방식으로 액세스할 수 있는 일종의 소프트웨어입니다. XML Web Services를 사용하면 응용 프로그램에서 코드 그룹 영역 간에 데이터를 공유할 수 있습니다. 기본적으로 로컬 인트라넷과 인터넷 영역의 응용 프로그램에는 원본 사이트에 액세스할 수 있는 권한이 부여되므로 XML Web services를 호출할 수 있습니다. XML Web services 빌드에 대한 자세한 내용은 ASP.NET을 사용하는 XML Web services를 참조하십시오. XML Web services를 사용하는 방법에 대한 자세한 내용은 XML Web Services 클라이언트 빌드를 참조하십시오.

레지스트리 액세스

RegistryPermission 클래스가 운영 체제 레지스트리에 대한 액세스를 제어합니다. 기본적으로 로컬에서 실행되는 응용 프로그램만 레지스트리에 액세스할 수 있습니다. RegistryPermission은 응용 프로그램에 레지스트리 액세스를 시도할 수 있는 권한만 부여할 뿐이며 운영 체제에서 레지스트리에 보안을 적용하기 때문에 해당 액세스가 성공하리라는 보장은 없습니다.

부분 신뢰 환경에서는 레지스트리에 액세스할 수 없으므로 다른 방법으로 데이터를 저장해야 합니다. 응용 프로그램 설정을 저장할 때는 레지스트리가 아닌 격리된 저장소를 사용합니다. 격리된 저장소는 기타 응용 프로그램 관련 파일을 저장할 때도 사용할 수 있습니다. 기본적으로 원본 사이트에 액세스할 수 있는 권한이 응용 프로그램에 부여되므로 원본 서버나 원본 사이트에 대한 전역 응용 프로그램 정보를 저장할 수도 있습니다.

참고 항목

개념

Windows Forms의 인쇄 추가 보안

Windows Forms의 추가 보안 고려 사항

Windows Forms의 보안 개요

참조

매니페스트 생성 및 편집 도구(Mage.exe)

매니페스트 생성 및 편집 도구, 그래픽 클라이언트(MageUI.exe)

기타 리소스

Windows Forms 보안