Categorias

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

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;
    }
  }