Usando as classes MemberShip e Roles em uma aplicação Windows Forms


Em meu artigo ASP.NET  2.0 - Usando o Roles e MemberShip eu apresentei os conceitos sobre as classes Membership e Roles para ASP.NET 2.0 e no artigo ASP.NET  2.0 - Acessando Roles e MemeberShip via código  mostrei como podemos acessar algumas propriedades e métodos destas classes. Será que não podemos usar algumas das funcionalidades expostas por essas classes em uma aplicação Windows Forms ? Sim , podemos e vou mostrar como...

Os recursos MemberShip e Roles (Perfis) são implementados através de uma série de classes do .NET Framerwork e você pode acessar essas classes para ler e definir propriedades e chamar métodos em seu código se você necessitar complementar as funcionalidades oferecidas pela ASP.NET para membership e roles. As classes principais são:

Neste artigo eu vou mostrar como você pode usar o provedor MemberShip e Roles em uma aplicação Windows Forms no Visual Basic 2005 Express Edition.

Para começar sugiro que você leia os artigos citados ,e , se você não for um programador ASP.NET , tenha um pouco de paciência e procure focar no segundo artigo. Vamos lá...

Vou começar criando um novo projeto Windows Forms no VB 2005 Express usando a linguagem Visual Basic com o nome : segurancaNet e alterando o nome do formulário form1.vb para Categorias.vb.

No formulário Categorias.vb inclua um controle DataGridView e defina um Data Source usando o banco de dados Northwind.mdf usando a tabela Categories de forma a exibir todos os registros no formulário. Abaixo temos o resultado final obtido pela execução do projeto neste momento:

Para abrir o Assistente de configuração de Data Source selecione na guia DataGridView Tasks a opção : Choose Data Source e a seguir clique no link : add Project Data Source.

Depois e só selecionar DataBase e definir a conexão com o Northwind.mdf e selecionar a tabela Categories.
O formulário Categorias.vb exibindo os dados da tabela Categories Definindo um Data Source para o DataGridView no formulário

Vamos supor que você deseja restringir o acesso a este formulário implementando uma autenticação de usuários no seu projeto de forma que somente os usuários que forem autenticados tenham acesso ao formulário categorias.vb.

Vamos incluir um novo item no projeto clicando com o botão direito do mouse sobre o nome do projeto; Vou aproveitar o template Login Form alterando o seu nome para Login.vb

Abaixo temos o formulário Login.vb já criado e exibido :

Teremos que incluir o código para autenticar o usuário no evento Click do botão OK e aqui é que vamos usar as funcionalidades das classes MemberShip e Roles da ASP.NET 2.0. Como ???

Simples, inclua uma referência no projeto clicando com o botão direito do mouse sobre o nome do projeto e no menu suspenso selecione a opção Add Reference...

Na janela Add Reference, na guia .NET, selecione o componente - System.web e clique no botão OK.

A seguir abra o formulário Login.vb e inclua a seguinte declaração no início do formulário:

Imports System.Web.security

Pronto ! com estas etapas cumpridas já podemos usar alguns dos recursos das classes MemberShip e Roles.

Então no evento Click do botão OK inclua o código que irá autenticar o usuário:

Private Sub OK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK.Click

' Valida o o usuário/senha
If Membership.ValidateUser(txtUsuario.Text, txtSenha.Text) Then
      MsgBox("Usuário validado.")
      nomeUsuario = txtUsuario.Text
      Me.Hide()
      My.Forms.Categorias.Show()
Else
     MsgBox("Usuário/Senha inválido(s)!")
End If
End Sub

O código acima usa o método ValidateUser da classe MemberShip e verifica se o nome do usuário e a senha fornecidas são válidos.

Se você executar o projeto, definindo o formulário Login.vb como o startup form  do projeto e tentar autenticar qualquer usuário irá obter a mensagem : Usuário/Senha inválido(s).

O comportamento já era esperado , afinal , não temos nenhum usuário com nome e senhas definidos. Então vamos definir um usuário e senha. Para fazer isso vamos usar o código abaixo no evento Load do formulário Login.vb. (faremos isto apenas para mostrar que funciona , depois iremos remover este código do evento)

Dim status As MembershipCreateStatus

        Membership.CreateUser( _
            "Macoratti", _
            "mac2007@", _
            "macoratti@yahoo.com", _
            "Nome do meu papagaio", _
            "kuen", _
            True, _
            status)

MsgBox(status.ToString())

Este método usa o método CreateUser da classe MemberShip e inclui um novo usuário no banco de dados. Note que é preciso definir o nome, a senha , email, uma questão de segurança e sua resposta. Execute novamente o projeto e informe o usuário mac e a senha mac2007@ e você verá o resultado da figura abaixo onde temos que o usuário é validado e o acesso é concedido.

Funciona ! não é mesmo.  Mas como ??? Onde e como os dados do usuário foram persistidos ?

Na janela Solution Explorer clique no ícone Show All Files e abra a pasta bin.

Note que temos uma pasta chamada App_Data e dentro dela um arquivo ASPNETDB.MDF que foi criado de forma automática para dar suporte a persistência dos dados relacionados com o usuário suas credenciais e seus perfis.

Abrindo o arquivo ASPNETDB.MDF para visualização na janela DataBase Explorer iremos ver que foram criadas diversas tabelas iniciando com o prefixo aspnet_.

Vamos espiar a tabela aspnet_Users clicando com o botão direito do mouse sobre ela e selecionando a opção Show Table Data:

A tabela contém os dados do usuário que cadastramos : mac. (os demais dados referem-se a testes que eu realizei.)

Vamos abrir , da mesma forma,  a tabela aspnet_MemberShip:

Nesta tabela vemos que estão armazenados a senha cifrada do usuário e outras informações.

Pois é , a plataforma .NET criou toda essa estrutura por trás dos panos para permitir que possamos usar as funcionalidades das classes MemberShip e Roles.

Nota:  Para saber mais acompanhe o artigo : ASP.NET  2.0 - Usando Application Services

Então vamos melhorar a nossa interface e incluir um controle LabelLink no formulário login alterando sua propriedade Name para lnkNovoUsuario e sua propriedade Text para: Novo Usuário( Fig 1.0)

A seguir inclua um novo formulário no projeto com o nome de novoUsuario.vb e defina os controles no formulário conforme o leiaute abaixo: (Fig 2.0)

Fig 1.0 Fig 2.0

No evento Click do controle LinkLabel - lnkNovoUsuario - inclua o código abaixo que apenas abre o formulário novoUsuario.vb:

Private Sub lnkNovoUsuario_LinkClicked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.LinkLabelLinkClickedEventArgs) Handles lnkNovoUsuario.LinkClicked
      My.Forms.novoUsuario.ShowDialog()
End Sub

Agora no formulário novoUsuario declare o seguinte namespace : Imports System.Web.security

No evento Click do botão OK inclua o código abaixo que irá criar um novo usuário usando um código mais refinado (nem tanto...):

Private Sub OK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK.Click

' Cria um novo usuário
Dim status As MembershipCreateStatus

Membership.CreateUser(txtUsuario.Text, txtSenha.Text, txtEmail.Text, txtQuestao.Text, txtResposta.Text, True, status)

If status = MembershipCreateStatus.Success Then
    MsgBox("Usuario Criado Com sucesso !")
Else
If status = MembershipCreateStatus.InvalidUserName Then
   MsgBox("Nome do usuário inválido")
   txtUsuario.Focus()
ElseIf status = MembershipCreateStatus.InvalidPassword Then
   MsgBox("Senha do usuário inválida")
   txtSenha.Focus()
ElseIf status = MembershipCreateStatus.InvalidEmail Then
   MsgBox("Email inválido")
   txtEmail.Focus()
ElseIf status = MembershipCreateStatus.InvalidQuestion Then
   MsgBox("Questão inválida")
   txtQuestao.Focus()
ElseIf status = MembershipCreateStatus.InvalidAnswer Then
   MsgBox("Resposta inválida")
   txtResposta.Focus()
ElseIf status = MembershipCreateStatus.UserRejected Then
   MsgBox("Usuário rejeitado")
   txtUsuario.Focus()
ElseIf status = MembershipCreateStatus.DuplicateUserName Then
   MsgBox("Nome do usuário já existe.!")
   txtUsuario.Focus()
ElseIf status = MembershipCreateStatus.DuplicateEmail Then
   MsgBox("Email informado já existe.!")
   txtEmail.Focus()
Else
   MsgBox("Não foi possível criar o usuário para estes dados. Verifique => " & status)
End If
End If
End Sub

Já que estamos criando um novo usuário vamos também usar outro recurso desta vez da classe Roles. A classe Roles fornece métodos que você pode usar para modificar os perfis em sua aplicação, obter informação sobre quais usuário estão em um perfil , incluir usuário em um perfil e remover usuários de um perfil. Para criar ou deletar perfis você usa os métodos CreateRole e DeleteRole:

Roles.CreateRole(nome)
Roles.DeleteRole(nome)

Vamos incluir um controle LinkLabel no formulário novoUsuario.vb alterando sua propriedade Name para lnkCriaPerfil e sua propriedade Text para Criar Perfil.

Em seguida vamos incluir um novo formulário chamado criaPerfil.vb incluindo um controle ListBox , dois botões de comando e um controle LinkLabel conforme figura abaixo:

Eu já defini alguns itens no controle ListBox : Administrador, Operador, Usuário e Gerente

Inclua neste formulário novamente a declaração : Imports System.Web.Security

No evento Click do botão de comando Criar Perfil digite o seguinte código:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCriaPerfil.Click

'verifica se foi selecionado um item da lista

If lstPerfil.SelectedIndex <> -1 Then
Try
     Roles.CreateRole(lstPerfil.SelectedItem)
Catch ex As Exception
     MsgBox(ex.Message)
End Try
Else
    MsgBox("Selecione um perfil a ser criado.!")
End If
End Sub

O código acima cria um perfil com um dos nomes selecionados na ListBox(lstPerfil) pelo usuário usando o método CreateRole() da classe Roles.

Que tal poder atribuir um usuário a um perfil definido ? Com isso podermos restringir o acesso a partes da aplicação verificando o perfil do usuário logado.

Inclua um novo formulário na aplicação chamado incluiPerfilUsuario.vb e a seguir inclua os controles TextBox, Label, ListBox e Button conforme o leiaute abaixo:

NO evento Load deste formulário vamos incluir o código abaixo que apenas atribui o nome do usuário ativo a caixa de texto e obtêm os perfis já cadastrados usando o método GetAllRoles preenchendo o controle ListBox(lstPerfis):

Private Sub incluiUsuarioPerfil_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load


Dim
perfil As Array =
Nothing

 

txtUsuarioAtivo.Text = Login.txtUsuario.Text  'aqui você pode melhorar o código pegando o usuário ativo da classe Roles


perfil = Roles.GetAllRoles


For
i As Integer = 0 To perfil.Length - 1

    lstPerfis.Items.Add(perfil(i))

Next
 

End Sub

No evento Click do botão - Incluir usuário no Perfil - usaremos o código a seguir que verifica se um perfil foi selecionado e se existe um usuário ativo para em seguida incluir o usuário no perfil usando o método AddUserToRole;

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click


If
lstPerfis.SelectedIndex <> -1 And txtUsuarioAtivo.Text <> String.Empty
Then

  Try

      Roles.AddUserToRole(txtUsuarioAtivo.Text, lstPerfis.SelectedItem)

      MsgBox("Usuario incluido no perfil com sucesso.")

  Catch ex As Exception

      MsgBox(ex.Message)

  End Try

Else

  MsgBox("Selecione o usuário e o perfil.!")

End If

End Sub

Finalmente podemos incluir o código no evento Load do formulário Categorias.vb para verificar se o usuário logado pertence ao perfil Administrador. Se isto for verdade então os dados serão exibidos no DataGridView , caso contrário a mensagem "Usuário não administrador, acesso restrito" irá indicar que o usuário não tem acesso a estes dados. A verificação é feita pelo método IsUserInRole da classe Roles:

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

'verifica se o usuário esta no perfil de Administrador

If Roles.IsUserInRole(My.Forms.Login.nomeUsuario, "Administrador") Then
     MsgBox("Usuário administrador.")
     'TODO: This line of code loads data into the 'NORTHWNDDataSet.Categories' table. You can move, or remove it, as needed.
      Me.CategoriesTableAdapter.Fill(Me.NORTHWNDDataSet.Categories)
Else
    MsgBox("Usuário não Administrador, acesso restrito")
End If

End Sub

A sequência de utilização dos formulários é mostrada na figura abaixo:

Existem mais recursos que não abordamos neste artigo que você pode explorar fica o registro de como você pode incrementar suas aplicações com funcionalidades já existentes na Plataforma .NET.

Pegue o projeto completo aqui:   segurancaNet.zip (sem a base de dados ASPNETDB.MDF)

Até o próximo artigo .NET ...


José Carlos Macoratti