Validar usuários e roles com IIdentity e IPrincipal (C#)

Autor: Bruno Gross - mail@brunogross.com

Parceria - Extraído do site - www.codigofonte.com.br

O exemplo a seguir ajuda a criar um esquema de validação baseado no namespace System.Security, onde além de restringir o acesso a blocos de códigos (utilizando os métodos do IPrincipal e desvios condicionais) bem como restringir diretamente o acesso a métodos de acordo com as permissões de acesso.
Aumentando a segurança de sua aplicação.

Tal validação está implementada para ser utilizada com FormsAutentication por isso o uso de GenericPrincipal e GenericIdentity. Com uma simples mudança, pode-se alterar para utilizar o AD por exemplo...

- Adicionar as referências aos namespaces necessários:
using System.Security.Principal; // controla a principal
using System.Threading; // controle da thread do usuário atual

 - Cria-se um objeto do tipo Identity com as informações do usuário logado.

Ex.
IIdentity genIdentity = new GenericIdentity("userName"); //onde username é o usuário logado. Mais informações podem ser passadas. Consulte a documentação.
//isso controla no momento das checagens das permissões se o usuário em questão encontra-se ou não logado na aplicação.

 - Obtêm-se as permissões de acesso do usuário (Roles) criando um array de string pelo resultado e enviar para a montagem do Principal Genérico com os dados.

Ex:
//crio o array das permissões que no caso da aplicação será devolvido pelo banco
string[] _permissions = new string[3];
_permissions[0] = “funcao_1”;
_permissions[1] = “funcao_2”;
_permissions[2] = “funcao_3”;

//Crio um objeto do tipo da interface IPrincipal
IPrincipal genPrincipal;
//chamo o constructor da GenericPrincipal passando o Identity criado e o array de strings com as permissões.
genPrincipal = new GenericPrincipal(genIdentity , _permissions);

 - Após criados os objetos que precisarei usar, apenas adiciono na Thread da requisição atual o objeto da Iprincipal que passa a estar disponível a toda a aplicação
Thread.CurrentPrincipal = genPrincipal;


 - Após isso em qualquer parte da aplicação posso adicionar uma chamada ao namespace
Ex:
using System.Security.Permissions; // controle das permissões de acesso a métodos


 - E adicionar a tag de chamada que controla o acesso.
Ex:
 [PrincipalPermission(SecurityAction.Demand,Authenticated=true, Role="funcao_1")]
 public bool TestaTag()
 {
  return true;   
 }

 - Se na role da requisição atual existir funcao_1 (que no exemplo existe) será retornado true.

 - Caso contrário o resultado gerado será um Exception que retornará a Message “Request for Principal Permission Failed” que deverá ser tratado por Try/Catch onde o método no caso o “TestaTag()” for chamado.

 - Para testar uma role e restringir o acesso a um bloco espefífico de código pode se usar a verificação inLine
Ex:
  public bool TestaTag()
  {
    if(System.Threading.Thread.CurrentPrincipal.IsInRole("funcao_2"))
    {
 return true;
    }
  }- Adicionar as referências aos namespaces necessários:
using System.Security.Principal; // controla a principal
using System.Threading; // controle da thread do usuário atual

 - Cria-se um objeto do tipo Identity com as informações do usuário logado.

Ex.
IIdentity genIdentity = new GenericIdentity("userName"); //onde username é o usuário logado. Mais informações podem ser passadas. Consulte a documentação.
//isso controla no momento das checagens das permissões se o usuário em questão encontra-se ou não logado na aplicação.

 - Obtêm-se as permissões de acesso do usuário (Roles) criando um array de string pelo resultado e enviar para a montagem do Principal Genérico com os dados.

Ex:
//crio o array das permissões que no caso da aplicação será devolvido pelo banco
string[] _permissions = new string[3];
_permissions[0] = “funcao_1”;
_permissions[1] = “funcao_2”;
_permissions[2] = “funcao_3”;

//Crio um objeto do tipo da interface IPrincipal
IPrincipal genPrincipal;
//chamo o constructor da GenericPrincipal passando o Identity criado e o array de strings com as permissões.
genPrincipal = new GenericPrincipal(genIdentity , _permissions);

 - Após criados os objetos que precisarei usar, apenas adiciono na Thread da requisição atual o objeto da Iprincipal que passa a estar disponível a toda a aplicação
Thread.CurrentPrincipal = genPrincipal;


 - Após isso em qualquer parte da aplicação posso adicionar uma chamada ao namespace
Ex:
using System.Security.Permissions; // controle das permissões de acesso a métodos


 - E adicionar a tag de chamada que controla o acesso.
Ex:
 [PrincipalPermission(SecurityAction.Demand,Authenticated=true, Role="funcao_1")]
 public bool TestaTag()
 {
  return true;   
 }

 - Se na role da requisição atual existir funcao_1 (que no exemplo existe) será retornado true.

 - Caso contrário o resultado gerado será um Exception que retornará a Message “Request for Principal Permission Failed” que deverá ser tratado por Try/Catch onde o método no caso o “TestaTag()” for chamado.

 - Para testar uma role e restringir o acesso a um bloco espefífico de código pode se usar a verificação inLine
Ex:
  public bool TestaTag()
  {
    if(System.Threading.Thread.CurrentPrincipal.IsInRole("funcao_2"))
    {
 return true;
    }
  } Envie sua avaliação e comentários sobre este código

Nota Comentário Data Membro
Ainda não foi enviado nenhum comentário.

Regras:
Os comentários seguem as seguintes regras:
Todos os comentários são enviados por membros cadastrados no site.
Os comentários serão pré-aprovados, porém a equipe do site revisará o conteúdo de todos os comentários podendo ser invalidados (inclusive a pontuação).
Os comentários precisam ter, obrigatóriamente, coerência sobre o conteúdo que será comentado.
O membro que atingir 20 comentários invalidados não poderá mais comentar dentro do site. Com isso o membro não poderá mais ganhar pontos com comentários.
Envie sua avaliação e comentários sobre este código Veja também - Conteúdo Relacionado