다음을 통해 공유


방법: RequestOptional 플래그를 사용하여 선택적 권한 요청

중요

.NET Framework 버전 4에서 런타임 지원은 Deny, RequestMinimum, RequestOptionalRequestRefuse 권한 요청을 적용하기 위해 제거되었습니다.이러한 요청은 .NET Framework 4 이상을 기반으로 하는 코드에서 사용하면 안 됩니다.이 변경 내용 및 다른 변경 내용에 대한 자세한 내용은 .NET Framework 4의 보안 변경 내용을 참조하십시오.

RequestOptional 플래그를 사용하면 특정 권한 집합만 요청하고 이 플래그를 사용하지 않을 경우 런타임에서 부여하는 다른 모든 권한은 암시적으로 거부할 수 있습니다.반면, RequestRefuse 플래그를 사용하면 코드에 부여하지 않을 권한을 명시적으로 지정하여 권한을 거부할 수 있습니다.

RequestOptional 플래그로 식별되는 선택적 권한 이외의 필수 권한을 식별하려면 RequestMinimum 플래그를 사용해야 합니다.RequestOptional 플래그로 식별된 권한이 코드에 없어도 해당 코드가 로드되고 실행됩니다.응용 프로그램이 액세스 권한이 없는 리소스를 사용하려고 하면 SecurityException이 throw됩니다.RequestOptional 권한을 사용하는 경우 코드에 선택적 권한이 부여되지 않았을 때 throw되는 예외를 코드에서 catch할 수 있도록 설정해야 합니다.

다음 절차의 Test 예제에서는 RequestMinimum 플래그를 사용하여 UIPermission을 요청하고 RequestOptional 플래그를 사용하여 FileIOPermission을 요청하므로 다른 모든 권한은 간접적으로 거부합니다.Main 메서드의 try 블록에 있는 코드는 새 파일을 만들려고 합니다.이 시도가 실패하면 catch 블록은 throw되는 SecurityException을 가로채고 메시지를 표시합니다.

샌드박스에서 응용 프로그램을 실행하려면

  1. Visual Studio에서 콘솔 응용 프로그램 프로젝트를 만듭니다.

  2. 예제 단원의 코드를 응용 프로그램 파일에 복사합니다.이 코드는 LocalIntranet 권한 집합으로 실행되는 샌드박스를 만듭니다.LocalIntranet 권한 집합은 FileIOPermission을 포함하지 않습니다.

  3. 프로젝트 메뉴에서 속성, 서명 탭을 차례로 클릭하고 강력한 이름 키를 사용하여 프로젝트에 서명합니다.

  4. Test라는 새 콘솔 응용 프로그램 프로젝트를 솔루션에 추가합니다.

  5. 다음 코드를 Test의 응용 프로그램 파일에 복사합니다.이 코드는 선택적 요구 사항으로 FileIOPermission을 요청합니다.응용 프로그램에 FileIOPermission이 없어도 해당 응용 프로그램을 시작할 수 있습니다.

    Imports System
    Imports System.Security.Permissions
    Imports System.IO
    
    <Assembly: FileIOPermission(SecurityAction.RequestMinimum, Unrestricted:=True)> 
    Namespace Test
        Class Program
    
            Shared Sub Main(ByVal args() As String)
                Console.WriteLine("Test is loaded.")
                File.Create("test.txt")
    
            End Sub 'Main
        End Class 'Program
    End Namespace
    
    
    using System;
    using System.Security.Permissions;
    using System.IO;
    [assembly: FileIOPermission(SecurityAction.RequestMinimum, Unrestricted=true)]
    namespace Test
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Test is loaded.");
                File.Create("test.txt");
            }
        }
    }
    
  6. 샌드박스 응용 프로그램을 실행합니다.이 응용 프로그램은 테스트 응용 프로그램을 로드하고 실행합니다.응용 프로그램을 실행하면 다음 메시지와 함께 예외가 throw됩니다.

    Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed. 
    

샌드박스에서 응용 프로그램을 실행하는 방법에 대한 자세한 내용은 방법: 샌드박스에서 부분 신뢰 코드 실행을 참조하십시오.

예제

다음 예제에서는 LocalIntranet 권한으로 실행되는 샌드박스를 만듭니다.

Imports System
Imports System.Collections
Imports System.Diagnostics
Imports System.Security
Imports System.Security.Permissions
Imports System.Security.Policy
Imports System.Reflection
Imports System.IO



Class Program

    Shared Sub Main(ByVal args() As String)
        ' Create the permission set to grant to other assemblies.
        ' In this case we are granting the permissions found in the LocalIntranet zone.
        Dim e As New Evidence()
        e.AddHostEvidence(New Zone(SecurityZone.Intranet))
        Dim pset As PermissionSet = SecurityManager.GetStandardSandbox(e)
        ' Optionally you can create your own permission set by explicitly adding permissions.
        '     PermissionSet pset = new PermissionSet(PermissionState.None);
        '     pset.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
        '     pset.AddPermission(new UIPermission(PermissionState.Unrestricted));
        Dim ads As New AppDomainSetup()
        ' Identify the folder to use for the sandbox.
        ads.ApplicationBase = "C:\Sandbox"
        ' Copy the application to be executed to the sandbox.
        File.Copy("..\..\..\HelloWorld\Bin\Debug\HelloWorld.exe", "C:\sandbox\HelloWorld.exe", True)

        Dim hostEvidence As New Evidence()
        ' Commenting out the following statement has no effect on the sample.
        ' The grant set is determined by the grantSet parameter, not the evidence 
        ' for the assembly.  However, the evidence can be used for other reasons, 
        ' for example, isolated storage.
        hostEvidence.AddHostEvidence(New Zone(SecurityZone.Intranet))


        ' Create the sandboxed domain.
        ' You can replace the null parameter with a strong name that identifies full trust assemblies: 
        ' GetStrongName(Assembly.GetExecutingAssembly()));  This identifies any assemblies in the folder
        ' that are signed with the same strong name as this assembly as being full trust assemblies.
        Dim sandbox As AppDomain = AppDomain.CreateDomain("Sandboxed Domain", hostEvidence, ads, pset, Nothing)

        sandbox.ExecuteAssemblyByName("HelloWorld")

    End Sub 'Main


    Public Shared Function GetStrongName(ByVal [assembly] As [Assembly]) As StrongName
        If [assembly] Is Nothing Then
            Throw New ArgumentNullException("assembly")
        End If
        Dim assemblyName As AssemblyName = [assembly].GetName()
        Debug.Assert(Not (assemblyName Is Nothing), "Could not get assembly name")

        ' Get the public key blob.
        Dim publicKey As Byte() = assemblyName.GetPublicKey()
        If publicKey Is Nothing OrElse publicKey.Length = 0 Then
            Throw New InvalidOperationException("Assembly is not strongly named")
        End If
        Dim keyBlob As New StrongNamePublicKeyBlob(publicKey)

        ' Return the strong name.
        Return New StrongName(keyBlob, assemblyName.Name, assemblyName.Version)

    End Function 'GetStrongName
End Class 'Program 
using System;
using System.Collections;
using System.Diagnostics;
using System.Security;
using System.Security.Permissions;
using System.Security.Policy;
using System.Reflection;
using System.IO;

namespace SimpleSandboxing
{
    class Program
    {
        static void Main(string[] args)
        {
            // Create the permission set to grant to other assemblies.
            // In this case we are granting the permissions found in the LocalIntranet zone.
            Evidence e = new Evidence();
            e.AddHostEvidence(new Zone(SecurityZone.Intranet));
            PermissionSet pset = SecurityManager.GetStandardSandbox(e);
            // Optionally you can create your own permission set by explicitly adding permissions.
            //     PermissionSet pset = new PermissionSet(PermissionState.None);
            //     pset.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
            //     pset.AddPermission(new UIPermission(PermissionState.Unrestricted));
            AppDomainSetup ads = new AppDomainSetup();
            // Identify the folder to use for the sandbox.
            ads.ApplicationBase = "C:\\Sandbox";
            // Copy the application to be executed to the sandbox.
            File.Copy("..\\..\\..\\HelloWorld\\Bin\\Debug\\HelloWorld.exe", "C:\\sandbox\\HelloWorld.exe", true);

            Evidence hostEvidence = new Evidence();
            // Commenting out the following statement has no effect on the sample.
            // The grant set is determined by the grantSet parameter, not the evidence 
            // for the assembly.  However, the evidence can be used for other reasons, 
            // for example, isolated storage.
            hostEvidence.AddHostEvidence(new Zone(SecurityZone.Intranet));


            // Create the sandboxed domain.
            // You can replace the null parameter with a strong name that identifies full trust assemblies: 
            // GetStrongName(Assembly.GetExecutingAssembly()));  This identifies any assemblies in the folder
            // that are signed with the same strong name as this assembly as being full trust assemblies.
            AppDomain sandbox = AppDomain.CreateDomain(
               "Sandboxed Domain",
               hostEvidence,
               ads,
               pset,
               null);   // Optionally: GetStrongName(Assembly.GetExecutingAssembly()));

            sandbox.ExecuteAssemblyByName("HelloWorld");
        }

        public static StrongName GetStrongName(Assembly assembly)
        {
            if (assembly == null)
                throw new ArgumentNullException("assembly");

            AssemblyName assemblyName = assembly.GetName();
            Debug.Assert(assemblyName != null, "Could not get assembly name");

            // Get the public key blob.
            byte[] publicKey = assemblyName.GetPublicKey();
            if (publicKey == null || publicKey.Length == 0)
                throw new InvalidOperationException("Assembly is not strongly named");

            StrongNamePublicKeyBlob keyBlob = new StrongNamePublicKeyBlob(publicKey);

            // Return the strong name.
            return new StrongName(keyBlob, assemblyName.Name, assemblyName.Version);
        }

    }
}

참고 항목

참조

SecurityAction

FileIOPermission

UIPermission

개념

특성을 사용하여 메타데이터 확장

권한 요청

코드 액세스 보안