Compartilhar via


Implementando uma permissão personalizada

Todos os objetos de permissão devem implementar o IPermission interface. Herdam o CodeAccessPermission classe é a maneira mais fácil de criar uma permissão personalizada como CodeAccessPermission implementa IPermission e fornece a maioria dos métodos necessários para uma permissão. Além disso, você deve implementar o IUnrestrictedPermission interface para todas as permissões de acesso do código personalizado. A classe de permissão personalizada é necessária para suporte tanto segurança imperativas e declarativas, para que você deve criar mesmo se você pretende usar a segurança declarativa somente.

Observação:

A permissão personalizada deve ser definido em um assembly diferente do assembly no qual é referenciado.Se a permissão personalizada inclui um atributo de segurança para a segurança declarativa, a permissão personalizada e o atributo devem ser definidos em um assembly separado .Isso ocorre porque th e segurança atributo é executado Quando o assembly é carregado e o atributo não pode ter sido criado no momento que a referência é encontrada.Tentando usar uma permissão declarativa no mesmo assembly em que ele está definido resultados em um TypeLoadException que está sendo lançada.

Definindo a classe de permissão

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

  • Copy cria uma duplicata do objeto de permissão corrente.

  • Intersect Retorna a interseção das permissões permitidas da classe corrente e uma classe passada.

  • IsSubsetOf Retorna true Se uma permissão passada inclui tudo permitidas pela permissão corrente.

  • FromXml decodifica uma representação em XML da sua permissão personalizada.

  • ToXml codifica uma representação em XML da sua permissão personalizada.

  • Union cria uma permissão que é a união de permissão corrente e a permissão especificada.

The IUnrestrictedPermission interface requer que você substituir e implementar um único método chamado IsUnrestrictedPermission.Para oferecer suporte a IUnrestrictedPermission interface, você deve implementar algum sistema, sistema autônomo um valor booliano que representa o estado da restrição do objeto corrente, para definir se a instância corrente da permissão é irrestrita.

O fragmento de código a seguir ilustra a maneira na qual uma classe de permissão personalizada pode ser definida.Um construtor que aceita um PermissionState enumeração e um valor booliano chamado unrestricted ambos são criados. The PermissionState enumeração tem um valor de qualquer um dos Irrestrito or Nenhum.Se a enumeração passada tiver um valor de Irrestrito, o construtor define unrestricted para True.Caso contrário, unrestricted é definido como False.Juntamente com construtores específicos para sua permissão personalizada, todas as permissões de acesso (qualquer permissão que herda de de códigoCodeAccessPermission) deve oferecer suporte a um construtor com apenas um PermissionState enumeração.

Juntamente com o código mostrado no exemplo a seguir, você deve implementar IsUnrestricted método e substituir de Cópia, Interseção, IsSubsetOf, ToXML, and FromXML métodos.Para obter informações sobre como concluir essas etapas, consulte as seções a seguir o exemplo.

Option Strict
Option Explicit
Imports System
Imports System.Security
Imports System.Security.Permissions
<SerializableAttribute()> NotInheritable Public Class CustomPermission
   Inherits CodeAccessPermission
   Implements IUnrestrictedPermission
   Private unrestricted As Boolean
   
   
   Public Sub New(state As PermissionState)
      If state = PermissionState.Unrestricted Then
         unrestricted = True
      Else
         unrestricted = False
      End If
   End Sub
   'Define the rest of your custom permission here. You must 
   'implement IsUnrestricted and override the Copy, Intersect, 
   'IsSubsetOf, ToXML, and FromXML methods.
End Class
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 está marcada com SerializableAttribute. Você deve marcar sua classe com SerializableAttribute para oferecer suporte à sintaxe declarativa usando um atributo.Para obter informações sobre como criar um atributo personalizado que usa um objeto de segurança personalizado, consulte Adicionando suporte à segurança declarativa.

Implementar o método IsUnrestricted

The IsUnrestricted é necessário para método a IUnrestrictedPermission interface e simplesmente retorna um valor booliano que indica se a instância da permissão corrente tem acesso irrestrito ao recurso protegido pela permissão.Para implementar esse método, basta retornar o valor de unrestricted.

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

Public Function IsUnrestricted() As Boolean Implements IUnrestrictedPermission.IsUnrestricted
   Return unrestricted
End Function
public bool IsUnrestricted()
{
   return unrestricted;
}

Substituindo o método Copy

O método de cópia é necessária para o CodeAccessPermission classe e retorna uma cópia da classe de permissão corrente.

O código a seguir ilustra como substituir o Cópia método.

Public Overrides Function Copy() As IPermission
   Dim myCopy As New CustomPermission(PermissionState.None)
   
   If Me.IsUnrestricted() Then
      myCopy.unrestricted = True
   Else
      myCopy.unrestricted = False
   End If
   Return myCopy
End Function
public override IPermission Copy()
{
   CustomPermission copy = new CustomPermission(PermissionState.None);

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

Substituindo os métodos IsSubsetOf e interseção

Todas as permissões devem implementar o Interseção and IsSubsetOf métodos.O comportamento dessas operações deve ser implementado sistema autônomo segue:

  • X.IsSubsetOf(Y) é True se permissão Y inclui tudo permitido pelo X.

  • X.Intersect(Y) resultados em uma permissão que permite que todas as operações e apenas essas operações permitidas pelas permissões de X e Y.

O exemplo a seguir ilustra como substituir e implementar o Interseção método.O método aceita uma classe que deriva de IPermission e inicializa essa classe para uma nova instância do CustomPermisison objeto. Nesse caso, a interseção entre o objeto corrente e o objeto passado for um objeto final com o valor da irrestrita se ambos os objetos possuem esse valor.No entanto, se um dos dois objetos possui um False valor de para irrestrito e, em seguida, também o objeto final terá um False valor para irrestrito.Esse código retorna um objeto irrestrito somente se os dois objetos forem irrestritos.

Public Overrides Function Intersect(target As IPermission) As IPermission
   If Nothing Is target Then
      Return Nothing
   End If
   Try
      Dim PassedPermission As CustomPermission = CType(target, CustomPermission)
      If Not PassedPermission.IsUnrestricted() Then
         Return PassedPermission
      End If
      Return Me.Copy()
   Catch InvalidCastException As Exception
      Throw New ArgumentException("Argument_WrongType", Me.GetType().FullName)
      End Try
End Function
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, a IsSubsetOfmétodo é substituído.Para que esse método para retornar True, a instância corrente e uma instância passada devem permitir que o mesmo conjunto de operações.Nesse caso, o método substituído inicializa uma nova instância do CustomPermission objeto para o objeto passado permissão. Se o unrestricted valores são iguais e, em seguida, o método retorna True.Se não, o método retorna False.

Public Overrides Function IsSubsetOf(target As IPermission) As Boolean
   If Nothing Is target Then
      Return Not Me.unrestricted
   End If
   Try
      Dim passedpermission As CustomPermission = CType(target, CustomPermission)
      If Me.unrestricted = passedpermission.unrestricted Then
         Return True
      Else
         Return False
      End If
   Catch InvalidCastException As Exception
      Throw New ArgumentException("Argument_WrongType", Me.GetType().FullName)
      End Try
End Function
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);
   }                
}

Substituindo ToXml e FromXml métodos

Permissões de suportam a XML para que um objeto de permissão pode ser salvo sistema autônomo XML e depois outro objeto de permissão podem ser restaurados para o valor original de codificação, usando o arquivo XML.Para oferecer suporte à codificação XML, a permissão personalizada deve implementar o ISecurityEncodable interface, que define um ToXml and a FromXml método.Porque os dois métodos são implementados por CodeAccessPermission, se sua classe de permissão personalizada derivada 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.The FromXML método pode usar qualquer representação em XML, desde que ToXML pode interpretá-lo e restauração o estado do mesmo.No entanto, o recipiente Permissão elemento deve ser de um formulário padrão.Por exemplo, o formulário de CustomPermission pode parecer o seguinte:

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

The IPermission elemento contém três atributos:

  • classe: Contém o nome de tipo disambiguated pelo nome do assembly que o contém.

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

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

Todas as permissões devem ser codificadas em um elemento XML chamado IPermission a ser usada pelo sistema de segurança de tempo de execução linguagem comum.

Novas versões de um objeto de permissão devem permanecer com versões anteriores compatível com versões anteriores com informações persistentes no XML de versões anteriores.A marca de versão fornece informações para um objeto de permissão sobre qual versão codificados originalmente os dados.

The SecurityElement classe encapsula a funcionalidade principal que precisa para criar e interagir com objetos de permissão codificados em XML. No entanto, como o modelo de objeto XML usado para a segurança do .NET estrutura é diferente dos outros modelos de objeto XML, a SecurityElement classe não deve ser usado para gerar outros tipos de arquivos XML.Consulte a descrição do SecurityElement classe para uma lista completa de seus membros.

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

Public Overrides Function ToXml() As SecurityElement
   Dim element As New SecurityElement("IPermission")
   Dim type As Type = Me.GetType()
   Dim AssemblyName As New StringBuilder(type.Assembly.ToString())
   AssemblyName.Replace(ControlChars.Quote, "'"c)
   element.AddAttribute("class", type.FullName & ", " & AssemblyName.ToString)
   element.AddAttribute("version", "1")
   element.AddAttribute("Unrestricted", unrestricted.ToString())
   Return element
End Function
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 StringBuilder.substituir método.Atributos do SecurityElement classe não pode conter aspas duplas, mas algumas informações de nome do assembly são aspas duplas.Para lidar com essa situação, a Substituir método converte aspas duplas ("") no nome do assembly em aspas simples (').

O método a seguir lê um SecurityElement objeto criado pelo método anterior e define o valor corrente do Irrestrito propriedade àquela especificada pelo objeto passado.Esse método deve garantir que as informações armazenadas pelo ToXml método é recuperado.

Public Overrides Sub FromXml(PassedElement As SecurityElement)
   Dim element As String = PassedElement.Attribute("Unrestricted")
   If Not element Is Nothing Then
      Me.unrestricted = Convert.ToBoolean(element)
   End If
End Sub
public override void FromXml(SecurityElement PassedElement)
{
   string element = PassedElement.Attribute("Unrestricted");
   if(null != element)
   {  
      this.unrestricted = Convert.ToBoolean(element);
   }
}

Exemplo de permissão personalizada

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

Option Explicit
Option Strict
Imports System
Imports System.Text
Imports System.Security
Imports System.Security.Permissions
Imports Microsoft.VisualBasic

<Serializable()>NotInheritable Public Class CustomPermission
   Inherits CodeAccessPermission
   Implements IUnrestrictedPermission
   Private unrestricted As Boolean
   Public Sub New(state As PermissionState)
      If state = PermissionState.Unrestricted Then
         unrestricted = True
      Else
         unrestricted = False
      End If
   End Sub

   Public Function IsUnrestricted() As Boolean Implements IUnrestrictedPermission.IsUnrestricted
      Return unrestricted
   End Function

   Public Overrides Function Copy() As IPermission
      'Create a new instance of CustomPermission with the current
      'value of unrestricted.
      Dim myCopy As New CustomPermission(PermissionState.None)
      
      If Me.IsUnrestricted() Then
         myCopy.unrestricted = True
      Else
         myCopy.unrestricted = False
      End If
      'Return the copy.
      Return copy
   End Function

   Public Overrides Function Intersect(target As IPermission) As IPermission
      'If nothing was passed, return null.
      If Nothing Is target Then
         Return Nothing
      End If
      Try
         'Create a new instance of CustomPermission from the passed object.
         Dim PassedPermission As CustomPermission = CType(target, CustomPermission)
         '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 Not PassedPermission.unrestricted Then
            Return target
         End If
         'Return a copy of the current class if the passed one has
         'an unrestricted value of true.
         Return Me.Copy()

      'Catch an InvalidCastException.
      'Throw ArgumentException to notify the user.
      Catch InvalidCastException As Exception
         Throw New ArgumentException("Argument_WrongType", Me.GetType().FullName)
      End Try

   End Function

   Public Overrides Function IsSubsetOf(target As IPermission) As Boolean
      'If nothing was passed and unrestricted is false,
      ' return true. 
 
      If Nothing Is target Then
         Return Not Me.unrestricted
      End If
      Try
         'Create a new instance of CustomPermission from the passed object.
         Dim passedpermission As CustomPermission = CType(target, CustomPermission)
         'If unrestricted has the same value in both objects, then
         'one is the subset of the other.
         If Me.unrestricted = passedpermission.unrestricted Then
            Return True
         Else
            Return False
         End If

      'Catch an InvalidCastException.
      'Throw ArgumentException to notify the user.
      Catch InvalidCastException As Exception
         Throw New ArgumentException("Argument_WrongType", Me.GetType().FullName)
      End Try

   End Function
   
   
   Public Overrides Sub FromXml(PassedElement As SecurityElement)
      'Get the unrestricted value from the XML and initialize 
      'the current instance of unrestricted to that value.
      Dim element As String = PassedElement.Attribute("Unrestricted")
      If Not element Is Nothing Then
         Me.unrestricted = Convert.ToBoolean(element)
   End If
   End Sub
   
   
   Public Overrides Function ToXml() As SecurityElement
      'Encode the current permission to XML using the 
      'SecurityElement class.
      Dim element As New SecurityElement("IPermission")
      Dim type As Type = Me.GetType()
      Dim AssemblyName As New StringBuilder(type.Assembly.ToString())
      AssemblyName.Replace(ControlChars.Quote, "'"c)
      element.AddAttribute("class", type.FullName & ", " & AssemblyName.ToString)
      element.AddAttribute("version", "1")
      element.AddAttribute("Unrestricted", unrestricted.ToString())
      Return element
   End Function
End Class
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;
   }
}

Consulte também

Conceitos

Criando suas próprias permissões de acesso ao código

Adicionando suporte à segurança declarativa

Referência

IPermission

CodeAccessPermission

IUnrestrictedPermission

SerializableAttribute

ISecurityEncodable

SecurityElement

Outros recursos

Segurança de Acesso de código