Skip Navigation Links



Translate this page now :



»Programação
»Programação.NET
»Banco de Dados
»Webdesign
»Office
» Certificações Microsoft 4
»Treinamentos4
»Programação 4
»Webdesign«
»Office & User Tips«
»Grupos de Usuários
»Células Acadêmicas«
intcontpiada : 118
Suporte Técnico
Você já está cadastrado e participa do grupo de usuários de sua cidade ? Se não, comente o porque.
 
 
Faça um pequeno teste com 10 questões de VB
.:.
Teste seus conhecimentos em Visual Basic, SQL Server e ASP 3.0 com nossas provas on-line
.:.
Aprimore seus conhecimentos em programação com nosso treinamento on-line de lógica de programação
.:.
Veja nosso calendário de treinamentos
Gostou da Página?
Então

para um amigo!

Pesquisa personalizada
Pesquisar Dicas:

 







Truques com autenticação parte 2 : Forçando a troca da senha

Neste 2o artigo da série vamos ver um exemplo em que o administrador faz o cadastramento de um usuário e obriga o usuário, no primeiro login, a realizar a troca da senha de acesso.

Para quem não acompanhou a primeira parte (http://www.bufaloinfo.com.br/artigos/artigo02012007.asp), basta saber que estamos lidando com formsAuthentication e memberShipProvider, os dois artigos da série são independentes um do outro.

Vejam as necessidades para que possamos realizar esta tarefa que desejamos :

- Precisamos de um local para registrar que o usuário é obrigado a trocar de senha

- Sempre que um novo usuário for criado, precisamos registrar a necessidade de trocar a senha

- Sempre que a senha for trocada, precisamos liberar o usuário da obrigatoriedade de trocar a senha

- Sempre que um usuário tentar chamar uma página, se estiver marcado para trocar de senha deve ser desviado para a página de troca de senha

O objeto MembershipUser, que representa o usuário, possui um campo Comment que podemos utilizar para registrar a necessidade de troca de senha.

Para podermos registrar essa necessidade sem termos que programar de forma repetitiva em todos os nossos projetos, podemos criar uma sub-classe do SQLMembershipProvider que faça esse registro automaticamente quando o usuário for criado e desfaça quando a senha for trocada.

Já para garantir que o usuário apenas poderá acessar a página de troca de senha precisaremos de um httpModule que intercepte o momento logo após a autenticação e verifique o campo Comment, desviando o usuário para a página de troca de senha se necessário.

O primeiro passo é montarmos um site básico com autenticação, para a partir dai implementarmos nosso novo recurso.

1) Crie um novo webSite

2) Na página default.aspx insira um novo sqlDataSource apontando para a tabela customers do banco northwind (customerid, companyName, contactName, country)

3) Insira uma gridview e configure-a

4) Crie uma página login.aspx

5) Na página login.aspx insira um webcontrol de Login e faça um autoformat

6) Crie uma pasta Admins (só os administradores acessarão)

7) Na pasta Admins crie uma página chamada Cadastro.aspx (só administradores irão cadastrar usuários)

8) Na página cadastro.aspx insira um CreateUserWizard

9) Configure a propriedade ContinueDestinationURL apontando para a página default (depois do cadastro, voltaremos para a página default)

10) Configure a propriedade LoginCreatedUser para false - o administrador criou o usuário, não quer se logar com ele de imediato.

 

Voltando para a página default.aspx, vamos incluir mais alguns pequenos detalhes :

11) Inclua um LoginView

12) Na smartTag do LoginView, clique em "Edit Role Groups"

13) Clique em Add e na propriedade Roles digite "Admins" (apenas os administradores verão o link para a página de cadastro)

14) Utilizando a smartTag, selecione o novo RoleGroup criado.

15) Crie um hyperlink neste novo RoleGroup e aponte para a página Cadastro.aspx

16) Fora do loginView, insira os webControls LoginName e LoginStatus

 

17) Abra a página de configuração em WebSite->ASP.NET Configuration

18) Utilize o Wizard de segurança para configurar a segurança como FormsAuthentication, cadastrar duas roles ("Admins","Users") e cadastrar 2 usuários "Fulano" e "Beltrano".

19) Ainda no Wizard, configure na raiz a negação de acesso aos usuários anônimos.

20) Ainda no Wizard, configure a pasta Admins para ser acessada apenas pelos administradores

Para isso adicione um allow roles Admins e Deny Users *

21) Teste a aplicação. Login, LogOff e o link apenas para os administradores já devem estar funcionando, não precisa testar o cadastramento.

Agora que nós montamos uma aplicação básica com autenticação, vamos partir para a nossa personalização, forçar o usuário criado a fazer a troca da senha.

1) Utilize File->Add->New Project para adicionar um novo projeto do tipo Class Library a nossa solução. Vamos chamar de clNovoMembership.

2) Clique com o botão direito no projeto e utilize Add References para adicionar referência para System.Web e System.Configuration, vamos precisar.

3) Troque o nome da class1.vb para MembershipTrocaSenha.vb

4) Neste único arquivo .vb, troque o nome da classe para MembershipTrocaSenha

5) Faça os seguintes imports :

Imports System.Web

Imports System.Web.Security

6) Defina a herança da classe para SQLMembershipProvider

    Inherits System.Web.Security.SqlMembershipProvider

7) Faça overrides no método CreateUser para marcar o usuário para a troca de senha :

    Public Overrides Function CreateUser(ByVal username _

As String, ByVal password As String, ByVal email As String, _

ByVal passwordQuestion As String, ByVal passwordAnswer As String, _

ByVal isApproved As Boolean, ByVal providerUserKey As Object, _

ByRef status As System.Web.Security.MembershipCreateStatus) As _ System.Web.Security.MembershipUser

 

 

        Dim user As MembershipUser

        user = MyBase.CreateUser(username, password, email, passwordQuestion,_ passwordAnswer, isApproved, providerUserKey, status)

 

 

        user.Comment = "Trocar"

        UpdateUser(user)

        Return (user)

    End Function

Observe que utilizamos o createUser original, sem mudanças. Ele nos devolve um objeto membershipUser, então atualizamos o campo Comment e pedimos um Update. UpdateUser é um método do próprio MembershipProvider.

8) Precisamos fazer um overrides da function ChangePassword para liberar o usuário da obrigação de mudar a senha. Ocorre que existem 2 overloads da ChangePassword, precisaremos lidar com os dois

Na change password não temos um objeto MembershipUser, então temos que obte-lo através do método GetUser

    Public Overrides Function ChangePassword(ByVal username As String, _
 ByVal oldPassword As String, ByVal newPassword As String) As Boolean
 
        Dim b As Boolean
        Dim user As MembershipUser
        b = MyBase.ChangePassword(username, oldPassword, newPassword)
 
        user = GetUser(username, True)
        user.Comment = String.Empty
        UpdateUser(user)
        Return (b)
    End Function
 
    Public Overrides Function ChangePasswordQuestionAndAnswer(ByVal username _
 As String, _
ByVal password As String, ByVal newPasswordQuestion As String, _ ByVal newPasswordAnswer As String) As Boolean
 
        Dim b As Boolean
        Dim user As MembershipUser
        b = MyBase.ChangePasswordQuestionAndAnswer(username, password, _
                  newPasswordQuestion, newPasswordAnswer)
 
        user = GetUser(username, True)
        user.Comment = String.Empty
        UpdateUser(user)
        Return (b)
    End Function

Para quem é adepto das técnicas de refactoring, também poderia ficar assim :


    Public Overrides Function ChangePassword(ByVal username As String, _
ByVal oldPassword As String, ByVal newPassword As String) As Boolean
 
        Dim b As Boolean
        b = MyBase.ChangePassword(username, oldPassword, newPassword)
 
        LiberarUsuario(username)
        Return (b)
    End Function
 
    Private Sub LiberarUsuario(ByVal username As String)
        Dim user As MembershipUser
        user = GetUser(username, True)
        user.Comment = String.Empty
        UpdateUser(user)
    End Sub
 
    Public Overrides Function ChangePasswordQuestionAndAnswer(ByVal username _
 As String, _
 ByVal password As String, ByVal newPasswordQuestion As String, _
 ByVal newPasswordAnswer As String) As Boolean
 
        Dim b As Boolean
        b = MyBase.ChangePasswordQuestionAndAnswer(username, password, _
                   newPasswordQuestion, newPasswordAnswer)
 
        LiberarUsuario(username)
        Return (b)
    End Function

 

Observe que esta é apenas uma implementação básica. Cabe a você melhorar esta implementação impedindo que o usuário mantenha a mesma senha que antes e mantendo um histórico de senhas que o usuário já utilizou, deixando o histórico configurável com relação a quantas senhas irá lembrar e bloquear. As possibilidades são muitas.

Agora que temos nosso novo membershipProvider criado, é hora de criar nosso httpModule. Para quem não conhece o httpModule nos permite interceptar eventos da aplicação de forma identica ao que o global.asax permite, porém o httpModule é compilado em um assembly .dll e pode ser adicionado com poucas tags no web.config, facilitando sua reutilização.

Como citamos anteriormente, o objetivo deste httpModule é desviar o usuário para uma página de troca de senha caso o usuário esteja marcado para fazer a troca de senha.

9) Crie uma nova classe no projeto chamada mdTrocaSenha

10) Adicione os seguintes imports :

Imports System.Web
Imports System.Web.Security
Imports System.Web.HttpContext

11) Faça a implementação da interface IHTTPModule

    Implements IHttpModule

Esta interface traz 2 métodos, Init e Dispose. No método Init devemos interceptar os eventos da aplicação que desejamos tratar, utilizando o AddHandler para adicionar uma sub de nossa classe para tratar o evento.

No nosso caso devemos tratar o evento PostAuthenticateRequest. Isso porque só nos interessam os usuários já autenticados, nesses iremos verificar se tem ou não a obrigação de trocar a senha.

Veja como ficam o Init e Dispose :

    Public Sub Dispose() Implements System.Web.IHttpModule.Dispose

 

    End Sub

 

    Public Sub Init(ByVal context As System.Web.HttpApplication) _

      Implements System.Web.IHttpModule.Init

 

        AddHandler context.PostAuthenticateRequest, AddressOf autenticou

 

    End Sub

A sub autenticou precisa ter a seguinte assinatura :

    Sub autenticou(ByVal sender As Object, ByVal e As EventArgs)

 

    End Sub

12) Codificar o desvio para a página de troca de senha

    Sub autenticou(ByVal sender As Object, ByVal e As EventArgs)

        With Current

            If .User.Identity.IsAuthenticated Then

                Dim user As MembershipUser

                user = Membership.GetUser()

                If user.Comment = "Trocar" Then

                    If .Request.Url.ToString.IndexOf("TrocarSenha") = -1 Then

                        .Response.Redirect("TrocarSenha.aspx?URL=" & _
                           .Server.UrlEncode(.Request.Url.ToString))

 

                        .Response.End()

                    End If

                End If

            End If

        End With

    End Sub

Vamos analisar este código :

Dentro do HTTPModule estamos acessando os objetos Response, Request, Server e User, todos parte do httpcontext atual. O httpContext já encontra-se no imports, utilizando a clausula With evitamos ter que repetir o "Current" em todo o código

            If .User.Identity.IsAuthenticated Then

Só vamos fazer algo se o usuário estiver autenticado

                Dim user As MembershipUser

                user = Membership.GetUser()

                If user.Comment = "Trocar" Then

Precisamos obter o membershipUser e verificar se está marcado

                    If .Request.Url.ToString.IndexOf("TrocarSenha") = -1 Then

Existe a possibilidade do usuário já estar na página de troca de senha e estar efetuando um postback para trocar a senha. Neste caso não iremos interromper o processo. Apenas se o usuário estiver chamando outra página qualquer do site é que iremos desvia-lo para a página de troca de senha.

                        .Response.Redirect("TrocarSenha.aspx?URL=" & .Server.UrlEncode(.Request.Url.ToString))

 

                        .Response.End()

Iremos redirecionar para a página de troca de senhas. Após o usuário trocar a senha ele deverá retornar para a página que tentou visualizar inicialmente. Então precisaremos transmitir o endereço da página que o usuário tentou visualizar originalmente para a página de troca de senha. Como a transmissão será via URL, precisamos fazer um UrlEncode para garantir que todos os caracteres serão válidos ou serão devidamente codificados para a transmissão.

Por fim, o response.end finaliza o processamento, interrompendo qualquer sequencia de processamento da página.

Observe a forma como o nome da página de troca de senha "TrocarSenha.aspx" ficou fixo no código. Isso não é bom, a aplicação fica amarrada com essa característica. Você poderia utilizar os conceitos mostrados no artigo em http://www.bufaloinfo.com.br/artigos/artigo04102006.asp para criar uma chave de configuração personalizada no web.config para manter esta informação.

Pronto, temos nossa class Library pronta. Agora é hora de utiliza-la.

1) Crie uma página chamada TrocarSenha.aspx

2) Insira o webControl ChangePassword e faça um autoformat

3) No page_load, vamos configurar a propriedade ContinueDestinationURL

Esta propriedade determina para qual página o usuário deve ser levado após concluir a troca de senha. Vamos verificar se o parâmetro URL foi informado e se foi vamos inseri-lo nesta propriedade.

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

        If Not IsNothing(Request.QueryString("url")) Then

            ChangePassword1.ContinueDestinationPageUrl = Request.QueryString("url")

        End If

    End Sub

Uma outra opção seria criar um novo componente herdando do componente ChangePassword que fizesse a recuperação da URL da querystring automaticamente, exatamente como fizemos em alguns casos do artigo anterior.

4) Adicione no projeto web uma referência para a class library

5) No web.config, configure o httpModule

    <httpModules>

      <add name="formssecure" type="clNovoMembership.mdTrocaSenha"></add>

    </httpModules>

6) No web.config, configure o MembershipProvider. A configuração pode ser copiada do machine.config (<windows>\microsoft.net\Framework\<versão>\config) com pequenas alterações :

    <membership defaultProvider ="MeuProvider">

      <providers>

        <add name="MeuProvider"

        type="clNovoMembership.MembershipTrocaSenha"

          connectionStringName="LocalSqlServer"

          enablePasswordRetrieval="false"

          enablePasswordReset="true"

          requiresQuestionAndAnswer="true"

          applicationName="/"

          requiresUniqueEmail="false"         

          passwordFormat="Hashed"

          maxInvalidPasswordAttempts="5"

          minRequiredPasswordLength="7"

          minRequiredNonalphanumericCharacters="1"

          passwordAttemptWindow="10"

          passwordStrengthRegularExpression=""/>

      </providers>

    </membership>

Pronto, com isso você pode fazer os testes da aplicação. O administrador terá permissão de cadastrar novos usuários e estes usuários serão automaticamente marcados com a exigência de troca de senha.

As funcionalidades deste artigo podem ser combinadas com as funcionalidades do artigo anterior, exigindo login único na aplicação. Você deve apenas tomar cuidado na hora de escrever ou ler do campo Comment, para que uma funcionalidade não atrapalhe a outra.

 

Dennes Torres
MCAD,MCSD,MCSE,MCDBA,MCT





Envie seus comentários sobre este artigo

Nome :

E-mail :

Comentários :


Avise-me quando houverem novos comentários nesta página

Veja abaixo os comentários já enviados :

Nome : yslanne fontes E-Mail : yslanneagostosonayahoo.com.br
eu quero descobrir a senhs do meu orkut
Nome : Vinicius E-Mail : viniciussgama@msn.com
Tudo bem Dennis,

Estou implementando essa dica que voce esta dando, que por sinal é otima, porem estou com um pequeno problema ao criar usuarios com o metodo CreateUser().

Nao sei o que esta acontecendo mas as vezes ele geraca excessao na linha onde voce coloca: user.comment = "Trocar"

Voce poderia me ajudar?

Agradecido
Nome : 6s6SIUtWaib E-Mail : agky6uad@gmail.com
htmlentities: HTML entity corrteupant (from what i understand this means writing out say < as &lt ?)mysql_real_escape_string: not too sure about this but from what i gather, it removes harmful data much like the htmlentities and strip_tags function.So the question is, which one should i use? or should i use all of them?
Nome : 1 E-Mail : 1
-1'
Nome : -1' E-Mail : 1
1
Nome : 1 E-Mail : -1'
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : -1' E-Mail : 1
1
Nome : 1 E-Mail : -1'
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : -1' E-Mail : 1
1
Nome : 1 E-Mail : -1'
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Conheça mais sobre o nosso site :

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::



Quer saber mais?
Faça um curso na Búfalo Informática, Treinamento e Consultoria e
Prepare-se para o Mercado!
Veja o que a Búfalo tem para você.

� Búfalo Informática, Treinamento e Consultoria - Rua Álvaro Alvim, 37 Sala 920 - Cinelândia - Rio de Janeiro / RJ
Tel.: (21)2262-1368 (21) 9240-5134 (21) 9240-7281 e-Mail:
contato@bufaloinfo.com.br