.NET

19 ago, 2010

ASP .NET – Autenticação/Autorização via código com FormsAuthenticationTicket – Parte 02

Publicidade

No artigo anterior, recordamos os conceitos sobre
autenticação/autorização com ASP .NET, definimos o nosso
objetivo, criamos o projeto no Visual Web Developer 2010 Express
e configuramos o nosso arquivo web.config. Vamos continuar
criando as pastas, o código e as páginas para permitir o acesso
baseado no perfil do usuário.

Gostaria de dizer que
existe mais de uma forma de implementar toda essa funcionalidade
e vou mostrar uma delas, portanto você pode alcançar o mesmo
objetivo com algumas variações.

O arquivo web.config é o
coração da nossa aplicação, pois é ele que vai decidir quem
pode ou não acessar determinado recurso; com ajuda de
outros recursos podemos por nosso projeto para funcionar.

Vamos criar duas pastas no
nosso projeto. Clique com o botão direito sobre o nome do
projeto e selecione a opção Add -> New Folder
e crie as pastas Admin e Aluno.

Obs:
A criação das pastas para os outros perfis (funci e mestre) é
feita da mesma forma e possui o mesmo funcionamento aplicados às
pastas Admin e Aluno.

Vamos incluir, em cada uma
dessas pastas, um formulário Web. Clique com o botão direito
sobre a pasta Admin e selecione Add -> New Item
e escolha o template Web Form e informe o nome admin.aspx. Repita o processo e inclua na pasta Aluno a página aluno.aspx.

Obs:
Poderia ter usado uma master page para herdar o cabeçalho, fica
a seu critério usar esse recurso.

O conteúdo das páginas
admin.aspx e aluno.aspx será muito simples, apenas um cabeçalho
e uma linha de texto para identificar a página. Veja abaixo como
deve ficar o leiaute das páginas alunos.aspx e
admin.aspx
e a estrutura da solução AutenticacaoWEB
exibida na janela Solution Explorer.

Figura 1.0 – Página
alunos.aspx da pasta Alunos


Figura 2.0 – Página
admin.aspx da pasta Admin

Estrutura da solução AutenticacaoWEB

Vamos a seguir criar a
página de login da aplicação que será usada para autenticar o
usuário solicitando seu login e sua senha. A página será bem
simples contendo um cabeçalho, dois controles TextBox (ID=txtUsuario e
ID=txtSenha ), um
controle Button (ID=btnLogin) e um controle Label (ID=lblError) definidos conforme o leiaute
abaixo:

Página login.aspx

Precisamos criar também
mais duas páginas, uma para realizar o logout e a página padrão,
para a qual o usuário deverá ser direcionado após fazer o
login com sucesso.

Para criar a página logout.aspx, clique com o botão direito do mouse sobre o nome do projeto e
selecione Add-> New Item, escolha o template
Web Form e informe o nome logout.aspx. A seguir inclua os
controles:

  • Label
    – Text = Você foi desconectado;
  • Hyperlink
    – ID – NavigateURL = Default.aspx Text= Logar Novamente;

Página
logout.aspx

A página padrão receberá
o nome de default.aspx, contendo os seguintes
controles:

  • LoginName
    – ID= loginName1 – Vai exibir o nome do usuário logado;
  • Hyperlink
    – ID = hplPerfil – vai exibir o link para a página
    conforme o perfil do usuário;
  • Hyperlink
    – ID = lnLogout – NavigateURL = logout.aspx Text=logout

Página default.aspx

O fluxo de acesso
envolvendo as 5 páginas criadas deverá ser o seguinte:

Nesse momento, a estrutura
da nossa solução exibida na janela Solution Explorer deverá
ser a seguinte:

Vamos agora analisar o
arquivo web.config e verificar qual a lógica de acesso e
permissão implementadas:

Obs:
Como não definimos o atributo
defaultUrl, a página default.aspx será a página para a qual o usuário
será direcionado após efetuar o login com sucesso.

Dessa forma, pelo que
definimos no arquivo web.config, somente os usuários com os
perfis criados terão acesso ao site, e, após efetuarem o login
deveremos identificar o perfil do usuário redirecionando-o para
o respectivo recurso.

Definindo
o código do projeto

Vamos agora definir o
código usado em cada página do nosso projeto começando com a
página login.aspx.

No evento Click
do botão Login, vamos colocar o código para
validar o usuário e definir o seu perfil. No arquivo login.aspx.vb, inclua o seguinte código:

  • Declaração do
    namespace: Imports
    System.Web.Security

O namespace
System.Web.Security contém classes que são usadas para
implementar a segurança do ASP.NET em aplicativos web.

  • Código do evento Click
    do botão Login
Protected Sub btnLogin_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnLogin.Click
If ValidaUsuario(txtUsuario.Text, txtSenha.Text) Then
FormsAuthentication.Initialize()
Dim strPerfil As String = AtribuiPerfil(txtUsuario.Text)

'Definimos quanto tempo o usuário irá permanecer logado após deixar o site sem efetuar o logout
Dim fat As FormsAuthenticationTicket = New FormsAuthenticationTicket(1, _
txtUsuario.Text, DateTime.Now, _
DateTime.Now.AddMinutes(30), False, strPerfil, _
FormsAuthentication.FormsCookiePath)
Response.Cookies.Add(New HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(fat)))
Response.Redirect(FormsAuthentication.GetRedirectUrl(txtUsuario.Text, False))
Else
'exibe a mensagem de erro
lblError.Visible = True
End If
End Sub

O código acima efetua a
validação do usuário verificando o login e a senha. A
validação que usei nesse exemplo é bem simples e apenas
verifica se o nome do usuário é igual a admin, aluno, funci ou
mestre, e a senha é 123456.

Obs: Essa rotina pode
ser construída usando a verificação das credenciais com os valores armazenados
em um banco de dados, mas por questão de simplicidade eu vou usar apenas uma
definição de valores com strings.

 Private Function ValidaUsuario(ByVal strNomeUsuario As String, ByVal strPassword As String) As Boolean
'Retorna True se o nome e senha do usuário for válido

Return CBool(strNomeUsuario = "admin" Or strNomeUsuario = "aluno" Or
strNomeUsuario = "funci" Or strNomeUsuario = "mestre" AndAlso
strPassword = "123456")
End Function

Se o usuário for válido,
primeiro atribuímos o perfil conforme o seu nome (no nosso
exemplo o nome é igual ao perfil por pura preguiça…),
conforme
o código abaixo:

Private Function AtribuiPerfil(ByVal strNomeUsuario As String) As String
'Retorna uma lista do perfil para o usuário
If txtUsuario.Text = "admin" Then
Return strNomeUsuario
ElseIf txtUsuario.Text = "aluno" Then
Return strNomeUsuario
ElseIf txtUsuario.Text = "funci" Then
Return strNomeUsuario
ElseIf txtUsuario.Text = "mestre" Then
Return strNomeUsuario
Else
Return String.Empty
End If
End Function

Em seguida, criamos um ticket
chamado fat usando a classe FormsAuthenticationTicket().

Criamos um ticket com os dados do
usuário e também os perfis carregados, e esse ticket será a
base da nossa autenticação.

A classe FormsAuthenticationTicket
é usada para criar um objeto que representa o ticket de
autenticação, que é usado pela autenticação de formulários
para identificar um usuário autenticado. As propriedades e
os valores de um ticket de autenticação de formulários são
convertidos para uma cadeia de caracteres criptografada
armazenada em um cookie ou na URL.

Os valores de FormsAuthenticationTicket
para o usuário atual autenticado podem ser acessados usando a
propriedade Ticket da classe FormsIdentity. Você
pode acessar o objeto FormsIdentity atual
convertendo a propriedade Identity do usuário atual
para o tipo FormsIdentity.

Agora temos que criar um arquivo Global.asax, e no evento AuthenticateRequest, que ocorre quando um usuário tenta se autenticar, temos que
definir uma rotina para carregar os perfis dos usuários para que
o ASP .NET os reconheça.

Inclua um arquivo Global.asax
no projeto e, no evento AuthenticateRequest, defina o seguinte
código:

 Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As EventArgs)
''Fires upon attempting to authenticate the use
If Not (HttpContext.Current.User Is Nothing) Then
'Usando as classes de identidade vamos obter o perfil e carregar na aplicação
If HttpContext.Current.User.Identity.IsAuthenticated Then
If TypeOf HttpContext.Current.User.Identity Is FormsIdentity Then
Dim fi As FormsIdentity = CType(HttpContext.Current.User.Identity, FormsIdentity)
'obtém o ticket de autenticação
Dim fat As FormsAuthenticationTicket = fi.Ticket
Dim astrPerfis As String() = fat.UserData.Split("|"c)
HttpContext.Current.User = New GenericPrincipal(fi, astrPerfis)
End If
End If
End If
End Sub

Se o usuário for válido e
for autenticado com sucesso, será direcionado para a página default.aspx.
Nessa página, exibimos o nome do usuário usando o controle LoginName
e, no controle Hyperlink, vamos definir de forma
dinâmica as seguintes propriedades do controle:

  • NavigateUrl
    -> o link para a página relacionada com o perfil do
    usuário;
  • Text
    – o texto adequado ao perfil;
  • Visible
    – exibimos ou não o link verificando se o usuário
    pertence ao um perfil através do código :Pager.User.IsInRole(“nome_do_perfil”)

A seguir temos o código no
evento Load, que vai tomar essas decisões,
definindo essas propriedades conforme o perfil carregado do
usuário atual.

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

lblAviso.Text = "Benvindo : "
If Page.User.IsInRole("admin") Then
hplPerfil.NavigateUrl = "~/Admin/admin.aspx"
hplPerfil.Text = "Acesso a página de Administração"
hplPerfil.Visible = Page.User.IsInRole("admin")
ElseIf Page.User.IsInRole("aluno") Then
hplPerfil.NavigateUrl = "~/Aluno/aluno.aspx"
hplPerfil.Text = "Acesso a página de Notas"
hplPerfil.Visible = Page.User.IsInRole("aluno")
ElseIf Page.User.IsInRole("funci") Then
hplPerfil.NavigateUrl = "funci.aspx"
hplPerfil.Text = "Acesso a página de Cadastro de Alunos"
hplPerfil.Visible = Page.User.IsInRole("funci")
ElseIf Page.User.IsInRole("mestre") Then
hplPerfil.NavigateUrl = "mestre.aspx"
hplPerfil.Text = "Acesso a página de Planejamento de Cursos"
hplPerfil.Visible = Page.User.IsInRole("mestre")
End If
End Sub

Agora só falta definir o
código da página logout.aspx para que a
sessão seja encerrada e o ticket de autenticação de
formulários seja removido do navegador.

Fazemos isso incluindo o
código abaixo no evento Load da página:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Session.Abandon()
'remove o tickect de autenticação
FormsAuthentication.SignOut()
End Sub

Agora só falta testar

Executando o projeto será
apresentada a página login.aspx (pois
negamos o acesso a todos os usuários ao raiz do site):

Após efetuar o login com o
perfil aluno, informando um login e senha
válidos, será apresentada a página default.aspx, exibindo
o nome do usuário logado, o texto e o link para acesso à página
/Aluno/aluno.aspx.

Ao clicar no link, o
usuário terá acesso a página aluno.aspx, conforme figura
abaixo:

Como eu já mencionei, existem outras
maneiras de obter o mesmo resultado, e em outro artigo irei
mostrar isso usando a linguagem C#.

Pegue o projeto completo
aqui: AutenticacaoWEB.zip

Eu sei, é apenas ASP .NET, mas eu gosto…

Simples, simples assim…