Exportar (0) Imprimir
Expandir Tudo
Este artigo foi traduzido por máquina. Coloque o ponteiro do mouse sobre as frases do artigo para ver o texto original. Mais informações.
Tradução
Original

Implementando uma permissão personalizada

Todos os objetos de permissão devem implementar a interface de IPermission . Herdar da classe de CodeAccessPermission é a maneira mais fácil de criar uma permissão personalizado como CodeAccessPermission implementa IPermission e fornece a maioria dos métodos necessários para uma permissão. Além disso, você deve implementar a interface de IUnrestrictedPermission para todas as permissões de acesso do código personalizado. A classe de permissão personalizado é necessária para suporte obrigatório e declarativo de segurança, você deve criá-la mesmo se você planeja usar somente a segurança declarativa imposta.

Observação Observação

A permissão personalizado deve ser definida em um assembly diferente do assembly no qual é referenciado. Se a permissão personalizado inclui um atributo de segurança para segurança declarativa, a permissão personalizado e o atributo devem ser definidos em um assembly separado. Isso ocorre porque o atributo de segurança é executado quando o assembly é carregado, e o atributo pode não ter sido criado na referência a ele está localizada. Tentar usar uma permissão declarativa no mesmo assembly no qual é definida na TypeLoadException que está sendo lançada.

Para derivar da classe de CodeAccessPermission , você deve substituir os seguintes cinco métodos chaves e fornecer sua própria implementação:

  • Copy cria uma duplicata do objeto da permissão atual.

  • Intersect retorna a interseção de permissões permitidas da classe atual e uma classe transmitida.

  • IsSubsetOf retorna true se uma permissão passada incluem todos reservado pela permissão atual.

  • FromXml decodifica uma representação XML da permissão personalizado.

  • ToXml codifica uma representação XML da permissão personalizado.

  • Union cria uma permissão que é a união da permissão atual e a permissão especificada.

A interface de IUnrestrictedPermission exige que você substituir e implementar um único método chamado IsUnrestrictedPermission. Para dar suporte à interface de IUnrestrictedPermission , você deve implementar qualquer sistema, como um valor booliano que representa o estado de restrição no objeto atual, para definir se a instância atual da permissão é irrestrito.

O seguinte fragmento de código a seguir ilustra o modo em que uma classe de permissão personalizado pode ser definida. Um construtor que aceita uma enumeração de PermissionState e um valor booliano chamados unrestricted ambos é criado. A enumeração de PermissionState tem um valor de Irrestrito ou de None. Se a enumeração passada tem um valor de Irrestrito, o construtor unrestricted define a true. Caso contrário, unrestricted é definido como false. Além dos construtores específicos à permissão personalizado, todos afeta permissões de acesso (qualquer permissão que herdam de CodeAccessPermission) devem oferecer suporte a um construtor que só considera uma enumeração de PermissionState .

Além do código mostrado no exemplo a seguir, você deve implementar o método de IsUnrestricted e substituir Copiar, Interseccionar, métodos de IsSubsetOf, de ToXML, e de FromXML . Para obter informações sobre como concluir essas etapas, consulte as seções a seguir listam o exemplo.

using System;
using System.Security;
using System.Security.Permissions;

[SerializableAttribute()]
public sealed class CustomPermission: CodeAccessPermission, IUnrestrictedPermission
{  
   private bool unrestricted;

   public CustomPermission(PermissionState state)
   {
      if(state == PermissionState.Unrestricted)
      {
         unrestricted = true;
      }
      else
      {
         unrestricted = false;
      }
   }     

   //Define the rest of your custom permission here. You must 
   //implement IsUnrestricted and override the Copy, Intersect, 
   //IsSubsetOf, ToXML, and FromXML methods.
}

Observe que a classe é marcada com SerializableAttribute. Marque sua classe com SerializableAttribute para dar suporte à sintaxe declarativa usando um atributo. Para obter informações sobre como criar um atributo personalizado que usa um objeto de segurança personalizada, consulte Adicionando suporte declarativo de segurança.

O método de IsUnrestricted é exigido pela interface de IUnrestrictedPermission e retorna apenas um valor booliano que indica se a instância atual da permissão tem acesso irrestrito ao recurso protegido pela permissão. Para implementar esse método retornar, apenas o valor de unrestricted.

O exemplo de código implementa o método de IsUnrestricted .

public bool IsUnrestricted()
{
   return unrestricted;
}

O método de cópia é exigido pela classe de CodeAccessPermission e retorna uma cópia da classe da permissão atual.

O seguinte código a seguir mostra como substituir o método de Copiar .

public override IPermission Copy()
{
   CustomPermission copy = new CustomPermission(PermissionState.None);

   if(this.IsUnrestricted())
   {
      copy.unrestricted = true;
   }
   else
   {
      copy.unrestricted = false;
   }
   return copy;
} 

Todas as permissões devem implementar Interseccionar e os métodos de IsSubsetOf . O comportamento dessas operações deve ser implementado como segue:

  • X.IsSubsetOf (Y) é true se a permissão Y incluem todos reservado por X.

  • X.Intersect (Y) resultados em uma permissão que permita todas as operações e apenas as operações permitidas por permissões X e Y.

O exemplo a seguir mostra como substituir e implementar o método de Interseccionar . O método aceita uma classe que deriva de IPermission e se inicialize essa classe para uma nova instância do objeto de CustomPermisison . Nesse caso, a interseção do objeto atual e o objeto passado é um objeto final com o valor de ilimitado se os dois objetos tiverem esse valor. No entanto, se um dos dois objetos tem um valor de false para ilimitado, o objeto final também terá um valor de false para ilimitado. Esse código retorna um objeto ilimitado somente se os dois objetos forem ilimitados.

public override IPermission Intersect(IPermission target)
{
   try
   {
      if(null == target)
      {
         return null;
      }
      CustomPermission PassedPermission = (CustomPermission)target;

      if(!PassedPermission.IsUnrestricted())
      {
         return PassedPermission;
      }
      return this.Copy();
   }
   catch (InvalidCastException)
   {
      throw new ArgumentException("Argument_WrongType", this.GetType().FullName);
   }                
}

No exemplo a seguir, o método de IsSubsetOf é substituído. Para que esse método retorna true, a instância atual e uma instância passada devem permitir exatamente o mesmo conjunto de operações. Nesse caso, o método substituído inicializa uma nova instância do objeto de CustomPermission ao objeto de permissão passado. Se os valores de unrestricted são os mesmos, o método retorna true. Se não for, o método retornará false.

public override bool IsSubsetOf(IPermission target)
{  
   if(null == target)
   {
      return !this.unrestricted;
   }
   try
   {        
      CustomPermission passedpermission = (CustomPermission)target;
      if(this.unrestricted == passedpermission.unrestricted)
      {
         return true;
      }
      else
      {
         return false;
      }
   }
   catch (InvalidCastException)
   {
      throw new ArgumentException("Argument_WrongType", this.GetType().FullName);
   }                
}

Suporte a XML das permissões que codifica de modo que um objeto de permissão pode ser salvo como XML e em outro objeto de permissão pode ser restaurado ao valor original, usando o arquivo XML. Para dar suporte a codificação XML, a permissão personalizado deve implementar a interface de ISecurityEncodable , que define ToXml e um método de FromXml . Como ambos os métodos serão implementados por CodeAccessPermission, se sua classe de permissão personalizado se deriva de CodeAccessPermission, você deve substituir esses métodos.

O conteúdo do elemento XML que representa o estado do objeto é determinado pelo próprio objeto. O método de FromXML pode usar qualquer representação XML como ToXML o pode interpretar e restaurar o mesmo estado. No entanto, o elemento de conteúdo de Permissão deve ser de um formulário padrão. Por exemplo, o formulário para CustomPermission poderia ser assim:

<IPermission class="CustomPermissions.CustomPermission, CustomPermissionAssembly " version="1" Unrestricted="True">

O elemento de IPermission contém três atributos:

  • class: Contém o nome do tipo resolvida pelo nome do assembly que contém o.

  • version: Especifica a versão da codificação XML (não a versão do assembly da classe).

  • Irrestrito: Especifica se a permissão tem direitos ilimitado.

Todas as permissões devem ser codificadas em um elemento XML chamado IPermission para ser usado pelo sistema de segurança do Common Language Runtime.

As novas versões de um objeto de permissão devem permanecer para trás - compatíveis com as informações persistente em XML das versões anteriores. A marca de versão fornece informações em um objeto de permissão em que a versão codificada dos dados originalmente.

A classe de SecurityElement encapsula a funcionalidade principal que você precisa para criar e interagir com os objetos de permissão em codificados. Porém, como o modelo de objeto de XML usado para a segurança do .NET Framework é diferente de outros modelos de objeto XML, a classe de SecurityElement não deve ser usada para produzir outros tipos de arquivos XML. Consulte a descrição da classe de SecurityElement para obter uma lista completa de seus membros.

O seguinte fragmento de código cria um elemento XML Permissão :

public override SecurityElement ToXml()
{
   SecurityElement element = new SecurityElement("IPermission");
   Type type = this.GetType();
   StringBuilder AssemblyName = new StringBuilder(type.Assembly.ToString());
   AssemblyName.Replace('\"', '\'');
   element.AddAttribute("class", type.FullName + ", " + AssemblyName);
   element.AddAttribute("version", "1");
   element.AddAttribute("Unrestricted", unrestricted.ToString());
   return element;
}

Observe que o exemplo anterior usa o método de StringBuilder.Replace . Os atributos da classe de SecurityElement não podem conter aspas duplas, mas algumas informações do nome do assembly estão entre aspas duplas. Para tratar essa situação, o método de Substituir converte aspas duplas (") no nome do assembly para as aspas simples (').

O método a seguir lê um objeto de SecurityElement criado pelo método anterior e define o valor atual da propriedade de Irrestrito a aquela especificada pelo objeto passado. Esse método deve assegurar que todas as informações armazenadas pelo método de ToXml ser recuperada.

public override void FromXml(SecurityElement PassedElement)
{
   string element = PassedElement.Attribute("Unrestricted");
   if(null != element)
   {  
      this.unrestricted = Convert.ToBoolean(element);
   }
}

O exemplo de código a seguir mostra uma classe de permissão personalizado inteira:

using System;
using System.Text;
using System.Security;
using System.Security.Permissions;

[Serializable()]
public sealed class CustomPermission: CodeAccessPermission , IUnrestrictedPermission
{
   private bool unrestricted;

   public CustomPermission(PermissionState state)
   {
      if(state == PermissionState.Unrestricted)
      {
         unrestricted = true;
      }
      else
      {
         unrestricted = false;
      }
   }
      
   public bool IsUnrestricted()
   {
      return unrestricted;
   }

   public override IPermission Copy()
   {
      //Create a new instance of CustomPermission with the current
      //value of unrestricted.
      CustomPermission copy = new CustomPermission(PermissionState.None);

      if(this.IsUnrestricted())
      {
         copy.unrestricted = true;
      }
      else
      {
         copy.unrestricted = false;
      }
      //Return the copy.
      return copy;
   }

   public override IPermission Intersect(IPermission target)
   {
      //If nothing was passed, return null.
      if(null == target)
      {
         return null;
      }
      try
      {
         //Create a new instance of CustomPermission from the passed object.
         CustomPermission PassedPermission = (CustomPermission)target;

         //If one class has an unrestricted value of false, then the
         //intersection will have an unrestricted value of false.
         //Return the passed class with the unrestricted value of false.
         if(!PassedPermission.unrestricted)
         {
            return target;
         }
         //Return a copy of the current class if the passed one has
         //an unrestricted value of true.
         return this.Copy();
      }
      //Catch an InvalidCastException.
      //Throw ArgumentException to notify the user.
      catch (InvalidCastException)
      {
         throw new ArgumentException("Argument_WrongType", this.GetType().FullName);
      }                
   }

   public override bool IsSubsetOf(IPermission target)
   {
      //If nothing was passed and unrestricted is false,
      //then return true. 
      if(null == target)
      {
         return !this.unrestricted;
      }
       try
      {        
         //Create a new instance of CustomPermission from the passed object.
         CustomPermission passedpermission = (CustomPermission)target;

         //If unrestricted has the same value in both objects, then
         //one is the subset of the other.
         if(this.unrestricted == passedpermission.unrestricted)
         {
            return true;
         }
         else
         {
            return false;
         } 
      }
      //Catch an InvalidCastException.
      //Throw ArgumentException to notify the user.
      catch (InvalidCastException)
      {
         throw new ArgumentException("Argument_WrongType", this.GetType().FullName);
      }                    
   }

   public override void FromXml(SecurityElement PassedElement)
   {
      //Get the unrestricted value from the XML and initialize 
      //the current instance of unrestricted to that value.
      string element = PassedElement.Attribute("Unrestricted");         
 
      if(null != element)
      {  
         this.unrestricted = Convert.ToBoolean(element);
      }
   }

   public override SecurityElement ToXml()
   {
      //Encode the current permission to XML using the 
      //SecurityElement class.
      SecurityElement element = new SecurityElement("IPermission");
      Type type = this.GetType();
      StringBuilder AssemblyName = new StringBuilder(type.Assembly.ToString());
      AssemblyName.Replace('\"', '\'');
      element.AddAttribute("class", type.FullName + ", " + AssemblyName);
      element.AddAttribute("version", "1");
      element.AddAttribute("Unrestricted", unrestricted.ToString());
      return element;
   }
}

Contribuições da comunidade

ADICIONAR
Mostrar:
© 2014 Microsoft