Segurança em aplicações .NET: utilizando o provider ASP.NET Membership
Veja neste artigo o que é o provider ASP.NET Membership e de que maneira o mesmo pode ser utilizado na implementação de rotinas de segurança em aplicações.
Muitas aplicações podem manipular em algum momento informações de caráter restrito, sobretudo quando se consideram sistemas direcionados ao ambiente corporativo. Em tais casos existirá uma forte preocupação no que se refere à privacidade dos dados, procurando-se evitar com isto o acesso não autorizado a funcionalidades de um software.
Estabelecer regras limitando o acesso a recursos é um procedimento rotineiro no mundo do desenvolvimento de softwares, principalmente em soluções concebidas para a utilização a partir de redes (sejam privadas ou, mesmo, a partir da própria Internet). A implementação de controles visando garantir a segurança de um sistema deve levar em conta alguns conceitos gerais:
- Confidencialidade: ideia que gira em torno da necessidade de garantir a privacidade de um conjunto de informações, impedindo que pessoas não autorizadas tomem conhecimento de dados sigilosos de forma inadvertida;
- Integridade: é a garantia de que os dados que estão sendo manipulados por uma aplicação não serão alterados de forma deliberada;
- Autenticação: processo no qual um usuário apresenta sua identificação (normalmente um login e uma senha correspondente) junto a um mecanismo de validação, o qual tem por responsabilidade conceder ou não o acesso às diferentes funcionalidades de uma aplicação;
- Autorização: uma vez que um usuário passe pela etapa de autenticação, este procedimento determina se o mesmo terá ou não acesso a uma determinada função do sistema em questão. A verificação de quem conseguirá utilizar uma funcionalidade ou informação pode envolver tanto a checagem de logins/contas individuais, quanto a análise de grupos de usuários (roles) aos quais uma pessoa esteja associada.
A criação de um mecanismo que gerencie o acesso de usuários a uma aplicação costuma demandar um tempo considerável, com o produto desse esforço podendo estar sujeito a vulnerabilidades não diagnosticadas num primeiro instante. Se realmente existirem falhas nos módulos que controlam a segurança de um sistema, as consequências poderão ser desastrosas, causando danos à imagem de uma organização, além de prováveis prejuízos financeiros e problemas legais.
Procurando oferecer uma alternativa simples e rápida para a segurança de aplicações ASP.NET, a Microsoft desenvolveu um provider conhecido como ASP.NET Membership. Trata-se de um conjunto de recursos voltados ao gerenciamento de regras de acesso, contas e perfis de usuários, sendo que este mecanismo pode utilizar como repositórios de informações as seguintes fontes:
- Um banco de dados SQL Server;
- O recurso Active Directory do Windows;
- Um provider customizado desenvolvido em atendimento a uma finalidade específica.
Maiores informações sobre o ASP.NET Membership podem ser obtidas através do link:
http://msdn.microsoft.com/en-us/library/tw292whz(v=vs.100).aspx
Muito embora tenha sido projetado para soluções Web, o ASP.NET Membership pode ser facilmente integrado a outros tipos de aplicações .NET (como Windows Forms). Isto contribui, sem sombra de dúvidas, para uma maior produtividade no desenvolvimento de novos sistemas, desonerando os programadores de tarefas como a implementação de toda uma lógica de controle de acessos/gerenciamento de usuários.
O objetivo deste artigo é demonstrar, em termos gerais, como o ASP.NET Membership pode ser configurado para uso em projetos .NET. Além disso, serão apresentadas algumas das classes e estruturas que permitem o acesso às funcionalidades fornecidas por este provider.
Configurando as estruturas do ASP.NET Membership em um banco de dados SQL Server
Disponibilizado a partir da versão 2.0 do .NET Framework, o provider Membership foi concebido inicialmente para uso em aplicações Web, conforme já mencionado anteriormente. A menos que definido explicitamente no arquivo Web.config de um projeto, o acesso à funcionalidade conhecida como “Web Site Administration Tool” (menu “Project” > opção “ASP.NET Configuration” do Visual Studio) costuma gerar um banco de dados que contempla toda a estrutura requerida pelo ASP.NET Membership.
Para efeitos de testes, esta é certamente uma boa opção. No entanto, em cenários que envolvam a utilização desse mecanismo de segurança num ambiente de produção, muito provavelmente existirá um banco de dados que precisará ser configurado com todos os elementos esperados pelo ASP.NET Membership.
A fim de demonstrar como este ajuste pode ser realizado, estaremos considerando um banco de dados chamado TesteMembership. A Figura 1 apresenta a estrutura desta base antes da geração dos elementos de controle de acesso, sendo possível observar a existência de três tabelas.
Figura 1: Estrutura do banco de dados TesteMembership antes do ajuste
Para a criação dos objetos de banco de dados necessários à utilização do provider Membership será necessário, primeiramente, acionar o utilitário Aspnet_regsql.exe a partir do prompt de comando do Visual Studio 2012 (no Windows 7: Menu Iniciar > Microsoft Visual Studio 2012 > Visual Studio Tools > Developer Command Prompt for VS2012). Na Figura 2 é possível ver o prompt em execução.
Figura 2: Prompt de comando do Visual Studio 2012
O Aspnet_regsql.exe é uma ferramenta que permite criar (ou ainda remover) os objetos usados pelo ASP.NET Membership em uma base de dados SQL Server. Para isto, o mesmo apresenta um wizard a partir do qual é possível selecionar a base de dados de destino (Figura 3).
Figura 3: Executando o utilitário Aspnet_regsql.exe
Ao se clicar no botão “Next”, será exibida uma tela similar àquela que consta na Figura 4. Manter selecionada a opção “Configure SQL Server for application services”, clicando em seguida no botão “Next”.
Figura 4: Selecionando opção para a configuração do ASP.NET Membership em uma base SQL Server
Na janela que aparecerá neste momento (Figura 5) preencher as configurações para acesso à base TesteMembership. Executar em seguida a opção “Next”.
Figura 5: Selecionando uma base de dados via Aspnet_regsql.exe
Confirmar então a realização dos ajustes na base TesteMembership, clicando no botão “Next” da tela que é apresentada na Figura 6.
Figura 6: Confirmando a realização de ajustes no banco TesteMembership
Concluído o acerto da base TesteMembership, será apresentada uma janela que indica que este processo transcorreu com sucesso (Figura 7).
Figura 7: Término dos ajustes no banco de dados TesteMembership
OBSERVAÇÃO: A geração das estruturas utilizadas pelo ASP.NET Membership também pode ser efetuada em uma base de dados voltada exclusivamente para este fim (e que, portanto, não conta com nenhum outro tipo de objeto que tenha sido previamente criado no mesmo).
Acessando a base de dados TesteMembership via SQL Server Management Studio (Figura 8), será possível observar a existência de diversas tabelas cujo nome se inicia por “aspnet_” (essas são algumas das estruturas utilizadas pelo provider Membership).
Figura 8: Banco de dados TesteMembership com as estruturas do ASP.NET Membership já criadas
Configurando a utilização do ASP.NET Membership em uma aplicação
Aplicações que venham a utilizar o ASP.NET Membership como mecanismo para controle de acesso de usuários deverão, obrigatoriamente, referenciar as bibliotecas System.Web.dll e System.Web.ApplicationServices.dll (Figura 9). Por mais que estes arquivos estejam normalmente associados a soluções Web, faz-se necessária a inclusão dos mesmos em outros tipos de projetos que dependam do provider Membership.
Figura 9: Adicionando referências a bibliotecas requeridas pelo ASP.NET Membership
Além disso, algumas alterações deverão ser efetuadas no arquivo de configuração da aplicação considerada. Na Listagem 1 estão indicados quais itens deverão incluídos, a fim de possibilitar com isso o uso dos mecanismos de autenticação e autorização disponibilizados pelo provider Membership:
O primeiro dos elementos que deverá ser declarado é uma string de conexão, com a mesma apontando para a base em que foram criados os objetos requeridos pelo ASP.NET Membership (no nosso exemplo, o banco de dados TesteMembership).
Na sequência, incluir dentro do item system.web os elementos:
- roleManager: configurações utilizadas no processo de autorização (controle de acesso a recursos de um sistema);
- membership: definições relativas à autenticação de usuários.
Listagem 1: Ajustes a serem realizados no arquivo de configuração
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
...
<connectionStrings>
<add name="TesteMembership"
providerName="System.Data.SqlClient"
connectionString="Data Source=.;Initial Catalog=TesteMembership;Integrated Security=True;"/>
</connectionStrings>
...
<system.web>
<roleManager
defaultProvider="SqlProvider"
enabled="true">
<providers>
<clear />
<add
name="SqlProvider"
type="System.Web.Security.SqlRoleProvider"
connectionStringName="TesteMembership"
applicationName="TesteMembership" />
</providers>
</roleManager>
<membership defaultProvider="SqlProvider">
<providers>
<clear />
<add
name="SqlProvider"
type="System.Web.Security.SqlMembershipProvider"
connectionStringName="TesteMembership"
applicationName="TesteMembership"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="false"
requiresUniqueEmail="false"
passwordFormat="Hashed"
minRequiredPasswordLength="8"
minRequiredNonalphanumericCharacters="0" />
</providers>
</membership>
</system.web>
...
</configuration>
Estão sendo preenchidos em roleManager os seguintes itens:
- type: o tipo de provider a ser utilizado para o gerenciamento de regras de acesso (System.Web.Security.SqlRoleProvider é o default ao se usar o ASP.NET Membership em conjunto com o SQL Server);
- connectionStringName: nome da string de conexão;
- applicationName: identificação da aplicação.
Já em membership foram informados os parâmetros:
- type: o tipo de provider a ser usado na autenticação de usuários (System.Web.Security.SqlMembershipProvider é o default ao se utilizar o ASP.NET Membership em conjunto com o SQL Server);
- connectionStringName: nome da string de conexão;
- applicationName: identificação da aplicação;
- enablePasswordRetrieval: indica se haverá a possibilidade de recuperação de uma senha;
- enablePasswordReset: define se é possível ou não "resetar" uma senha;
- requiresQuestionAndAnswer: determina se estará sendo utilizada uma pergunta (com resposta) durante o processo de recuperação de uma senha;
- requiresUniqueEmail: define se o e-mail associado a um usuário deve ser único (impede que outros logins fiquem assim vinculados a uma mesma conta de e-mail);
- passwordFormat: formato utilizado para a criptografia de senhas;
- minRequiredPasswordLength: número mínimo de caracteres para a definição de uma senha;
- minRequiredNonalphanumericCharacters: número mínimo de caracteres não alfanuméricos que deverão existir em uma senha.
Exemplos de utilização das classes do ASP.NET Membership
Aplicações Web Forms podem fazer uso de controles para login, criação de novos usuários e, até mesmo, a recuperação de senhas (http://msdn.microsoft.com/en-us/library/ms178329(v=vs.100).aspx). Já o acesso às diferentes funcionalidades do sistema pode ser configurado dentro do próprio arquivo Web.config. Essas características facilitam bastante o desenvolvimento, evitando em muitos casos a necessidade de se escrever código controlando os processos de autenticação de usuários e autorização de acesso a recursos.
Projetos construídos sob o framework ASP.NET também dispõem de mecanismos que facilitam a utilização do ASP.NET Membership, com isto acontecendo através do atributo AuthorizeAttribute (https://www.devmedia.com.br/filters-no-asp-net-mvc-3-revista-net-magazine-94/23663).
Já em outras soluções concebidas a partir do .NET Framework (como projetos Windows Forms), a utilização do ASP.NET Membership forçará a escrita de instruções validando as credenciais de usuários e verificando os direitos de acesso destes. Para tais situações, os desenvolvedores poderão empregar as seguintes classes definidas no namespace System.Web.Security:
- Membership: tipo usado na autenticação de usuários, criação de novos logins, alterações de senhas, dentre outras tarefas relacionadas à manutenção de contas de acesso;
- Roles: possibilita a criação de novas regras (roles) de acesso, a vinculação de usuários a tais roles, além de checagens determinando se um usuário tem acesso a um determinado recurso.
Na Listagem 2 é apresentado um exemplo de criação de um novo usuário, com isto acontecendo a partir de uma chamada ao método CreateUser da classe Membership; devem ser informados como parâmetros a esta operação o login de acesso, além da senha correspondente.
Listagem 2: Criando um novo usuário
...
string loginUsuario;
string senha;
...
Membership.CreateUser(loginUsuario, senha);
...
Já na Listagem 3 é demonstrado como se criar uma nova regra de acesso (role), através da invocação do método CreateRole (o qual é disponibilizado pelo tipo Roles).
Listagem 3: Criando uma nova role
...
string regra;
...
Roles.CreateRole(regra);
...
A associação de um usuário a uma regra de acesso também depende do uso da classe Roles (Listagem 4), sendo que neste último caso é utilizado o método AddUserToRole (que recebe como parâmetros o login e a role à qual este ficará vinculado).
Listagem 4: Vinculando um usuário a uma role
...
string loginUsuario;
string regra;
...
Roles.AddUserToRole(loginUsuario, regra);
...
Para a autenticação de um usuário deverá ser acionada a operação ValidateUser do tipo Membership; serão fornecidos como parâmetros a este método o login e a senha de acesso (Listagem 5).
Listagem 5: Autenticando um usuário
...
string loginUsuario;
string senha;
...
if (Membership.ValidateUser(loginUsuario, senha))
{
// Ações a serem executadas quando o login for válido
...
}
else
{
// Ações a serem executadas quando o login for inválido
...
}
...
Para determinar se um usuário realmente possui acesso a um recurso, será necessário efetuar uma chamada ao método IsUserInRole, o qual encontra-se definido na classe Roles (Listagem 6).
Listagem 6: Verificando se um usuário está associado a uma role
...
string loginUsuario;
string regra;
...
if (Roles.IsUserInRole(loginUsuario, regra))
{
// Ações a serem executadas quando o usuário
// estiver associado a uma role
...
}
else
{
// Ações a serem executadas quando o usuário
// não estiver associado a uma role
...
}
...
Conclusão
Embora desenvolvido inicialmente para uso em aplicações Web, os mecanismos de autenticação/autorização do ASP.NET Membership podem ser empregados sem maiores dificuldades em outros tipos de aplicações .NET. As diversas funcionalidades oferecidas por este provider (autenticação, autorização, gerenciamento de usuários e seus respectivos direitos) simplificam consideravelmente a implementação de aplicações mais seguras, evitando com isto a necessidade de se “reinventar a roda” (através da criação de um mecanismo próprio de controle de acessos).
Espero que conteúdo aqui apresentado possa ser útil em seu dia-a-dia. Até uma próxima oportunidade!
Artigos relacionados
-
Artigo
-
Artigo
-
Artigo
-
Artigo
-
Artigo