ASP.NET - Usando segurança baseada em formulários


O ASP.NET realiza muitas tarefas que antes , usando ASP, ficavam por conta do programador. O Controle de Login com ASP.NET ficou muito simples de ser realizado.

Vamos então mostrar como ficou o processo de proteger páginas dinâmicas com ASP.NET. Ele não faz tudo sozinho (ainda) temos que fazer algumas configurações e criar algumas páginas mas se você já precisou fazer esta tarefa em ASP vai concordar que agora é mais fácil.

Vou desenhar o cenário onde iremos trabalhar:

Suponha que você tenha uma aplicação Web e que vai precisar proteger algumas páginas da sua aplicação do acesso anônimo. Para tornar o processo compreensível e não poluir o código vou trabalhar com duas páginas:

- Login.aspx  - página que irá realizar o login do usuário.
- Login-protegido.aspx - página que desejamos proteger do acesso anônimo. Somente usuários autenticados terão acesso a esta página.

Estas duas páginas estarão no mesmo diretório da aplicação web ; o diretório Login2. Vamos criar então um diretório de trabalho da nossa aplicação web subordinado a inetpub\wwwroot com a seguinte estrutura :

Até agora eu não falei nele mas você notou que na pasta login2 da nossa aplicação existe um arquivo com o nome de web. Pois ele é o personagem principal do nosso artigo. Vamos então falar mais sobre ele.

O arquivo web.config é um arquivo no formato XML que possui informações sobre todo o projeto Web. O elemento-raiz de um Web.config é a tag <configuration> . A princípio o arquivo Web.config não é um arquivo exigido para que a aplicação funcione. Se não houver necessidade de nenhuma configuração especial o arquivo nem precisa existir. Se ele não existir será usado um arquivo chamado Machine.config padrão que possui configurações padrões definidas.

Abaixo temos as configurações possíveis para serem usadas no arquivo Web.config :

Seção Descrição
<appSettings> Utilizada para armazenar suas próprias configurações personalizadas de Aplicativo.
<authentication> Configura como o ASP.NET autentica seus usuários.
<authorization> Configura a autorização de recursos no ASP.NET.
<browsercaps> Responsável por controlar as configurações do componente de capacidades do navegador.
<compilation> Responsável por todas as configurações de compilação.
<customErrors> Indica como exibir erros no navegador.
<globalization> Responsável por configurar as opções de globalização.
<httpHandlers> Responsável pelo mapeamento de URLs de entrada em classes IHttpHandler.
<httpModules> Responsável por configurar Módulos de HTTP dentro de um aplicativo.
<identity> Controla como o ASP.NET acessa seus recursos.
<location> Controla como as configurações se aplicam a um diretório.
<pages> Controla configurações de páginas.
<processModel> Configura as configurações de modelo de processo do ASP.NET em Sistemas de Servidor da Web do IIS.
<sessionState> Configura o Estado de Sessão.
<trace> Configura o Trace (Rastreamento).
<webServices> Controla as configurações dos Serviços da Web.

Podemos colocar o arquivo Web.config em qualquer diretório da aplicação Web , mas como geralmente ele contém configurações a nível de site que devem ser válidas a partir do diretório onde ele se encontra e nos demais subdiretórios ele é colocado no diretório raiz da aplicação web.

Nota: Se você receber o erro :

Parser Error Message: It is an error to use a section registered as allowDefinition='MachineToApplication' beyond application level. This error can be caused by a virtual directory not being configured as an application in IIS.  

ao acessar a aplicação veja como corrigir o problema acessando o site : IIS Insider

Provavelmente seu diretório virtual não foi configurado como uma aplicação no IIS e por isto não esta sendo reconhecido.

Vamos usar então o arquivo Web.config para informar ao ASP.NET que desejamos realizar a autenticação baseada em formulários e quais as páginas que desejamos proteger. Vamos então fornecer as seguintes informações ao Web.config:

- Que desejamos realizar a autenticação baseada em formulários
- Qual a página que desejamos proteger
- Qual será a nossa página de Login
- Quais usuários poderão acessar as páginas.

Se você não nem idéia de como criar um arquivo Web.Config você pode criar uma aplicação ASP.NET no Visual Studio.NET que ele será criado com as configurações padrões. Se você abrir o arquivo Web.config criado assim verá muitas tags por isto eu já vou mostrar a abaixo a estrutura do arquivo Web.Config que estarei usando na aplicação:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
	<!-- habilita a autenticacao -->
	<system.web>
		<authentication mode="Forms">
			<forms name="Exemplo" loginUrl="login.aspx" />
		</authentication>
	</system.web>
	<!-- define a pagina protegida para rejeitar usuarios anonimos -->
	<location path="login-protegido.aspx">
		<system.web>
			<authorization>
				<deny users="?" />
			</authorization>
		</system.web>
	</location>
</configuration>

Destacamos o código em cores para facilitar a visualização. Funciona assim:

1- Elemento authentication : Habilitando a autenticação e definindo a página de login

<authentication mode="Forms">
<forms name="Exemplo" loginUrl="login.aspx" />
</authentication>
Na tag <authentication> indicamos o modo Forms que implementa a segurança baseada em formulários.(Existem outros modos)

A seguir  no atributo LoginUrl especificamos qual será a nossa página de Login: login.aspx

2- Elemento authorization : Definindo quem terá acesso a página protegida e a página protegida.

<location path="login-protegido.aspx">
	<system.web>
		<authorization>
			<deny users="?" />
		</authorization>
	</system.web>
</location>
<location path="login-protegido.aspx"> define a página que desejamos proteger

<deny users="?" /> -A ? usada no elemento Deny indica que será negado o acesso a usuário não logado ou seja não autenticado.
 

 Vamos agora ao código da página login.aspx :(O destaque em cores diferentes do código HTML e do script VB.NET)

<%@ Page Language="VB" %>
<script runat="server">
    Sub btnLogin_OnClick(Src As Object, E As EventArgs)
    
        if txtUsuario.Text = "Macoratti" And txtSenha.Text = "123456"
            FormsAuthentication.RedirectFromLoginPage(txtUsuario.Text, True)
        Else
            lblInvalido.Text = "Senha/Usuário inválidos... tente novamente..."
        End If

    End Sub
</script>
<html>
<head>
    <title>ASP.NET - Exemplo de Login</title>
</head>
<body>
    <h2>Login 
    </h2>
    <p>
        <em>Dica: Usuario = "Macoratti"&nbsp; e&nbsp; Senha =&nbsp;"123456" </em>
    </p>
    <form runat="Server">
        <p>
            Usuário: 
            <asp:TextBox id="txtUsuario" runat="server" Width="138px"></asp:TextBox>
            <br />
            Senha&nbsp;&nbsp; : 
            <asp:TextBox id="txtSenha" runat="server" Width="137px" TextMode="Password"></asp:TextBox>
            <br />
            <br />
            <asp:Button id="btnLogin" onclick="btnLogin_OnClick" runat="server" text="Login"></asp:Button>
        </p>
        <p>
            A pagina que estamos protegendo é : <a href="login-protegido.aspx">login-protegido.aspx</a>. 
            <br />
            (Se voce&nbsp;&nbsp;NÃO estiver logado e clicar neste link voltará&nbsp;a esta&nbsp;página.
            ) 
        </p>
        <p>
            <asp:Label id="lblInvalido" runat="server" font-bold="True" forecolor="Red"></asp:Label>
        </p>
    </form>
</body>
</html>

O código com destaque na cor amarela é apenas código HTML onde temos dois controles TextBox , um controle Button e uma Label.

No código do script VB.NET na cor cinza a linha mais importante esta destacada :

FormsAuthentication.RedirectFromLoginPage(txtUsuario.Text, True)

Aqui estamos usando a classe FormsAuthenticacion que fornece métodos estáticos (shared) para manipular a autenticação. Esta classe não pode ser herdada.

O método RedirectFromLoginPage redireciona um usuário autenticado de volta a URL original da requisição. Os parâmetros usados no construtor do método usado são :

UserName - Nome do usuário para o cookie de autenticação. Representado aqui por txtUsuario.text.
CookiePersistente - Define se um cookie permanente será criado. Podemos ter dois valores False ou True.

Ao executar o arquivo login.aspx teremos o seguinte :

Se tentarmos acessar a página protegida login-protegido.aspx seremos redirecionados para a página login.aspx

Se o usuário não estiver autenticado quando clicar no botão Login ele retorna a página login.aspx.

Após se autenticar o usuário se autenticar (eu estou usando um usuário fixo no código mas você pode fazer o acesso a um banco de dados para verificar nome e senha) ele terá acesso a página login-protegido.aspx

Abaixo temos as telas que mostram este funcionamento:

Ao tentar a página login-protegido.aspx somos remetidos à página de login : login.aspx

Após fazer a autenticação temos acesso a página protegida : login-protegido.aspx

O código da página login-protegido.aspx é o seguinte :

<%@ Page Language="VB" %>
<script runat="server">
    Sub btnLogout_OnClick(Src As Object, E As EventArgs)
        FormsAuthentication.SignOut
    End Sub
</script>
<html>
<head>
    <title>ASP.NET - Exemplo de login</title>
</head>
<body>
    <p>
        Este é o texto super secreto que somente os visitantes autorizados podem ver : 
    </p>
    <strong>"Mesmo a mais longa jornada começa com o primeiro passo."</strong> 
    <p>
    </p>
    <form runat="server">
        <asp:Button id="btnLogout" onclick="btnLogout_OnClick" runat="server" text="Log Out"></asp:Button>
    </form>
    <p>
        <font color="blue">Nota: Depois de clicar no botão "Log Out" você vai precisar dar um
        'Refresh' na página. </font>
    </p>
</body>
</html>

O botão Log Out a utiliza aciona o método SignOut da classe FormsAuthenticacion que remove a autenticação realizada.

Para terminar vou deixar aqui o código para uma página de login que utiliza o acesso a um base de dados Access chamada Acesso onde a tabela Usuarios  possui um campo Nome e outro Senha que serão verificados após o usuário preencher o formulário e clicar no botão Login.

<%@ Page Language="VB" %>
<%@ import Namespace="System.Data" %>
<%@ import Namespace="System.Data.OleDb" %>
<%@ import Namespace="System.Web.Security" %>
<script runat="server">
    Function ValidaUsuario(nome As string, senha As string) As Boolean
     Dim strSQL as string = "Select * from Usuarios Where Nome=@Nome AND Senha=@Senha"
     Dim MyConn as New OleDbConnection(ConfigurationSettings.AppSettings("strConn"))
     Dim objDR as OleDbDataReader
     Dim Cmd as New OleDbCommand(strSQL, MyConn)
     cmd.Parameters.Add(New OleDbParameter("@Nome", nome))
     cmd.Parameters.Add(New OleDbParameter("@Senha", senha))
     Try
       MyConn.Open()
       objDR=Cmd.ExecuteReader(CommandBehavior.CloseConnection)
       if objDR.Read() Then
              FormsAuthentication.RedirectFromLoginPage(objDR("Nome"), False )
       else
            saida.Visible="True"
            saida.text="Usuário/Senha Inválido(s) , tente novamente."
       End If
     Catch ex as Exception
          saida.visible="true"
          saida.text="Ocorreu um erro durante o Login : " &  "<p>" & ex.Message()
     Finally
           MyConn.Close()
     End Try
    End Function
    Sub Login(Source as Object, E as EventArgs)
       Validausuario(Nome.Text,Senha.Text)
    End Sub
</script>
<html>
<head>
</head>
<body>
    <h1>Login
    </h1>
    <hr />
    <form runat="server">
        <table cellpadding="8">
            <tbody>
                <tr>
                    <td>
                        Usuário :
                    </td>
                    <td>
                        <asp:TextBox id="Nome" RunAt="server"></asp:TextBox>
                    </td>
                </tr>
                <tr>
                    <td>
                        Senha&nbsp;&nbsp; :
                    </td>
                    <td>
                        <asp:TextBox id="Senha" RunAt="server"></asp:TextBox>
                    </td>
                </tr>
                <tr>
                    <td>
                    </td>
                    <td>
                        <p align="center">
                            <asp:Button id="Button1" onclick="Login" RunAt="server" Text="Enviar"></asp:Button>
                        </p>
                    </td>
                </tr>
            </tbody>
        </table>
    </form>
    <hr />
    <h3><asp:Label id="saida" runat="server" forecolor="Red"></asp:Label>
    </h3>
</body>
</html>

 

Neste código a string de conexão é obtida pela seguinte linha de código :

     Dim MyConn as New OleDbConnection(ConfigurationSettings.AppSettings("strConn"))

Mas onde esta a string de conexão ? Esta no arquivo Web.config. Usando a tag <appSettings> podemos definir como abaixo a string de conexão:

<appSettings>
     <add key="strConn" value= "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=d:\inetpub\wwwroot\dados\Acesso.mdb" />
 </appSettings>     

A tag appSettings pode declarar configurações específicas da aplicação.

Podemos também definir um arquivo de mensagem de erros personalizada usando a tag customErrors :

<customErrors defaultRedirect="\login\erro\erro.aspx" mode="On" />

qualquer erro não tratado irá exibir a mensagem do arquivo erro.aspx .

A propriedade Mode pode possuir três diferentes valores :

Agora vamos testar a aplicação:

1- Clique aqui para tentar acessar a página login-protegido.aspx (se você não estiver autenticado irá para a página de login)

2- Estando na página login.aspx você verá a dica para usuário/senha tente informar algo diferente e verá que é exibida uma mensagem de login inválido

3- Existe um link na página login.aspx para você tentar acessar a página login-protegido.aspx se você clicar no link será remetido de volta para página login.aspx

4- Quando você informa o usuário e senha correta irá para a página de login.aspx . Neste momento a autenticação esta feita e será gravada ; a partir deste ponto você poderá acessar a página protegida diretamente.

5- Para anular a autenticação clique em Log Out e atualize a página. Você irá para a página de login pois não estará mais autenticado e pode começar a brincadeira novamente.

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

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

  Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

Referências:


José Carlos Macoratti