Como: Execução de código parcialmente confiável em uma área de segurança

Modo seguro é a prática de executar um aplicativo em um ambiente de segurança restrito, que limita as permissões de acesso do código concedidas a ele.Por exemplo, os controles que são baixados para o Internet Explorer executado usando o Internet permissão definido. Executar aplicativos que residem em compartilhamentos de rede local no seu computador usando o LocalIntranet conjunto de permissões. (Para obter mais informações sobre essas permissões, consulte O Conjunto de permissão nomeada.)

Você pode usar o modo seguro para executar aplicativos parcialmente confiável que você baixou para seu computador.Você também pode usar o modo seguro para testar aplicativos você distribuindo que serão executados parcialmente confiável em ambientes sistema autônomo a intranet.Para obter uma descrição completa de segurança de acesso do código (CAS) e o modo seguro, consulte Descubra o que há de novo com segurança do acesso ao código do .NET estrutura 2.0 no MSDN, o Microsoft Developer rede.

Você pode usar o CreateDomain(String, Evidence, String, String, Boolean, AppDomainInitializer, array<String[]) sobrecarga de método para especificar a permissão conjunto para aplicativos executados em uma área de segurança. Essa sobrecarga permite que você especifique as permissões concedidas a um aplicativo, que fornece o nível exato de segurança de acesso do código desejado.Ele não utiliza a diretiva padrão de CAS (diretiva de computador não é aplicada).Por exemplo, se o assembly que é chamado está assinado com uma chave de nome forte e existe um agrupar de código personalizado para esse nome de alta segurança, o agrupar de códigos não serão aplicadas.Assemblies que são carregados utilizando essa sobrecarga podem ter a doação especificada conjunto apenas, ou pode ter confiança total.O assembly é concedido confiança total, se estiver no cache global de assemblies ou na lista de certificados confiáveis total.No entanto, como destino um assembly confiança total ignora o uso de um modo seguro.

A sobrecarga tem a seguinte assinatura:

AppDomain.CreateDomain( string friendlyName,
                        Evidence securityInfo,
                        AppDomainSetup info,
                        PermissionSet grantSet,
                        params StrongName[] fullTrustAssemblies);

Os parâmetros para o CreateDomain(String, Evidence, AppDomainSetup, PermissionSet, array<StrongName[]) sobrecarga de método, especifique o nome dos AppDomain, a evidência do assembly, o AppDomainSetup objeto que identifica a base de aplicativo para a área de segurança, a permissão conjunto para uso e o nome forte para assemblies confiáveis.

O base de aplicativo especificado no info parâmetro não deve ser o base de aplicativo para o aplicativo de hospedagem. Se for, o assembly hospedado poderão usar o Load método para carregar outros assemblies na pasta, que pode não foi criada para detectar chamadas de chamadores parcialmente confiável.

O grantSet parâmetro, você pode especificar um uma permissão conjunto criado explicitamente ou do nomeado permissão define sistema autônomo Internet ou LocalIntranet. O exemplo completo fornecido neste tópico demonstra como usar permissões nomeadas conjunto s em vez de criar uma permissão personalizada conjunto.

Diferentemente a maioria dos AppDomain é carregado, a evidência do assembly (que é fornecido pela securityInfo parâmetro) não é usado para determinar o conjunto de concessão. Em vez disso, ele é especificado pelo independentementegrantSet parâmetro. No entanto, a evidência pode ser usada para outras finalidades, sistema autônomo determinar o armazenamento isolado.

Para executar um aplicativo em uma caixa de proteção

  1. A permissão Criar conjunto ser concedido ao aplicativo.

    Observação:

    O aplicativo Em Este exemplo requer Execution permissão para executar e UIPermission para gravar no console. O código a seguir cria uma nova permissão conjunto com essas permissões.sistema autônomo alternativa, você pode usar um existente chamado permissão conjunto, por exemplo, LocalIntranet. Para obter um exemplo de como usar um conjunto de permissões nomeadas, consulte a seção "Exemplo" mais adiante neste tópico.

    PermissionSet pset = new PermissionSet(PermissionState.None);
    pset.AddPermission(new      SecurityPermission(SecurityPermissionFlag.Execution));
    pset.AddPermission(new UIPermission(PermissionState.Unrestricted));
    
  2. Inicialize a pasta que será usada sistema autônomo o modo seguro.Não use a pasta que o aplicativo de hospedagem está usando.Se você colocar o aplicativo na pasta hospedagem, o assembly de hospedagem terá a capacidade de carregar qualquer assembly na pasta.

    AppDomainSetup ads = new AppDomainSetup();
    // Identify the folder to use for the sandbox.
    ads.ApplicationBase = "C:\\Sandbox";
    // Copy the application you want to run to the sandbox. File.Copy("HelloWorld.exe","C:\\sandbox\\HelloWorld.exe",true);
    
  3. Use o CreateDomain(String, Evidence, String, String, Boolean, AppDomainInitializer, array<String[]) sobrecarga de método para criar o domínio. Nesse caso, a evidência e o nome forte para o conjunto pai é especificado.Consulte a seção "Exemplo" neste tópico para o código para oGetStrongName método.

    // Create the sandboxed application domain.
    AppDomain sandbox = AppDomain.CreateDomain(
    "Sandboxed Domain",
    AppDomain.CurrentDomain.Evidence,
    ads, pset, GetStrongName(Assembly.GetExecutingAssembly()));
    
  4. Execute o aplicativo.

    sandbox.ExecuteAssemblyByName("HelloWorld");
    

Exemplo

O exemplo a seguir é um exemplo completo que implementa o procedimento na seção anterior.Este exemplo mostra como é possível executar um aplicativo usando as mesmas permissões que seriam concedida em um ambiente de intranet.Você terá que criar seu próprio aplicativo de teste para substituir o HelloWorld.exe assembly no exemplo.

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 pset As PermissionSet = GetNamedPermissionSet("LocalIntranet")
        If pset Is Nothing Then
            Return
        End If
        ' 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.exe", "C:\sandbox\HelloWorld.exe", True)

        Dim hostEvidence As New Evidence()
        ' Commenting out the following two statements 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.AddHost(New Zone(SecurityZone.Intranet))
        hostEvidence.AddHost(New Url("C:\Sandbox"))

        ' Create the sandboxed domain.
        Dim sandbox As AppDomain = AppDomain.CreateDomain("Sandboxed Domain", hostEvidence, ads, pset, GetStrongName([Assembly].GetExecutingAssembly()))
        sandbox.ExecuteAssemblyByName("HelloWorld")

    End Sub 'Main


    '' <summary>
    '' Get a strong name that matches the specified assembly.
    '' </summary>
    '' <exception cref="ArgumentNullException">
    '' if <paramref name="assembly"/> is null
    '' </exception>
    '' <exception cref="InvalidOperationException">
    '' if <paramref name="assembly"/> does not represent a strongly named assembly
    '' </exception>
    '' <param name="assembly">Assembly to create a StrongName for</param>
    '' <returns>A StrongName for the given assembly</returns>
    '' 
    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

    Private Shared Function GetNamedPermissionSet(ByVal name As String) As PermissionSet
        Dim policyEnumerator As IEnumerator = SecurityManager.PolicyHierarchy()

        ' Move through the policy levels to the machine policy level.
        While policyEnumerator.MoveNext()
            Dim currentLevel As PolicyLevel = CType(policyEnumerator.Current, PolicyLevel)

            If currentLevel.Label = "Machine" Then
                Dim copy As NamedPermissionSet = currentLevel.GetNamedPermissionSet(name)
                Return CType(copy, PermissionSet)
            End If
        End While
        Return Nothing

    End Function 'GetNamedPermissionSet
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.
            PermissionSet pset = GetNamedPermissionSet("LocalIntranet");
            if (pset == null)
                return;
            // 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.exe", "C:\\sandbox\\HelloWorld.exe", true);

            Evidence hostEvidence = new Evidence();
            // Commenting out the following two statements 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.AddHost(new Zone(SecurityZone.Intranet));
            hostEvidence.AddHost(new Url("C:\\Sandbox"));

            // Create the sandboxed domain.
            AppDomain sandbox = AppDomain.CreateDomain(
                "Sandboxed Domain",
                hostEvidence,
                ads,
                pset,
                GetStrongName(Assembly.GetExecutingAssembly()));
            sandbox.ExecuteAssemblyByName("HelloWorld");
        }

        /// <summary>
        /// Get a strong name that matches the specified assembly.
        /// </summary>
        /// <exception cref="ArgumentNullException">
        /// if <paramref name="assembly"/> is null
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// if <paramref name="assembly"/> does not represent a strongly named assembly
        /// </exception>
        /// <param name="assembly">Assembly to create a StrongName for</param>
        /// <returns>A StrongName for the given assembly</returns>
        /// 
        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);
        }
        private static PermissionSet GetNamedPermissionSet(string name)
        {
            IEnumerator policyEnumerator = SecurityManager.PolicyHierarchy();

            // Move through the policy levels to the machine policy level.
            while (policyEnumerator.MoveNext())
            {
                PolicyLevel currentLevel = (PolicyLevel)policyEnumerator.Current;

                if (currentLevel.Label == "Machine")
                {
                    NamedPermissionSet copy = currentLevel.GetNamedPermissionSet(name);
                    return (PermissionSet)copy;
                }
            }
            return null;
        }

    }
}