Criação de contas de usuário (VB)

por Scott Mitchell

Observação

Desde que este artigo foi escrito, os provedores de associação ASP.NET foram substituídos pelo ASP.NET Identity. É altamente recomendável atualizar aplicativos para usar a plataforma ASP.NET Identity em vez dos provedores de associação apresentados no momento em que este artigo foi escrito. ASP.NET Identity tem várias vantagens em relação ao sistema de associação ASP.NET, incluindo :

  • Melhor desempenho
  • Extensibilidade e testabilidade aprimoradas
  • Suporte para OAuth, OpenID Connect e autenticação de dois fatores
  • Suporte à identidade baseada em declarações
  • Melhor interoperabilidade com o ASP.Net Core

Baixar código ou baixar PDF

Neste tutorial, exploraremos o uso da estrutura associação (por meio do SqlMembershipProvider) para criar novas contas de usuário. Veremos como criar novos usuários programaticamente e por meio do ASP. Controle CreateUserWizard interno do NET.

Introdução

No tutorial anterior, instalamos o esquema de serviços de aplicativos em um banco de dados, que adicionou as tabelas, exibições e procedimentos armazenados necessários para o SqlMembershipProvider e SqlRoleProvidero . Isso criou a infraestrutura de que precisaremos para o restante dos tutoriais desta série. Neste tutorial, exploraremos o uso da estrutura associação (por meio do SqlMembershipProvider) para criar novas contas de usuário. Veremos como criar novos usuários programaticamente e por meio do ASP. Controle CreateUserWizard interno do NET.

Além de aprender a criar novas contas de usuário, também precisaremos atualizar o site de demonstração que criamos primeiro no tutorial Uma Visão Geral da Autenticação de Formulários. Nosso aplicativo Web de demonstração tem uma página de logon que valida as credenciais dos usuários em relação a pares de nome de usuário/senha embutidos em código. Além disso, Global.asax inclui código que cria objetos personalizados IPrincipal e IIdentity para usuários autenticados. Atualizaremos a página de logon para validar as credenciais dos usuários em relação à estrutura de associação e remover a entidade de segurança personalizada e a lógica de identidade.

Vamos começar!

A lista de verificação de autenticação e associação de formulários

Antes de começarmos a trabalhar com a estrutura de Associação, vamos dar um momento para examinar as etapas importantes que tomamos para chegar a esse ponto. Ao usar a estrutura Associação com o SqlMembershipProvider em um cenário de autenticação baseada em formulários, as seguintes etapas precisam ser executadas antes de implementar a funcionalidade associação em seu aplicativo Web:

  1. Habilite a autenticação baseada em formulários. Como discutimos em Uma Visão geral da Autenticação de Formulários, a autenticação de formulários é habilitada editando e definindo Web.config o <authentication> atributo Formsdo mode elemento como . Com a autenticação de formulários habilitada, cada solicitação de entrada é examinada para um tíquete de autenticação de formulários, que, se presente, identifica o solicitante.
  2. Adicione o esquema de serviços de aplicativo ao banco de dados apropriado. Ao usar o SqlMembershipProvider , precisamos instalar o esquema de serviços de aplicativo em um banco de dados. Normalmente, esse esquema é adicionado ao mesmo banco de dados que contém o modelo de dados do aplicativo. O tutorial Criando o esquema de associação no SQL Server analisou o uso da aspnet_regsql.exe ferramenta para fazer isso.
  3. Personalize as Configurações do Aplicativo Web para fazer referência ao banco de dados da etapa 2. O tutorial Criando o esquema de associação no SQL Server mostrou duas maneiras de configurar o aplicativo Web para que o SqlMembershipProvider use o banco de dados selecionado na etapa 2: modificando o LocalSqlServer nome da cadeia de conexão ou adicionando um novo provedor registrado à lista de provedores de estrutura de associação e personalizando esse novo provedor para usar o banco de dados da etapa 2.

Ao criar um aplicativo Web que usa a SqlMembershipProvider autenticação baseada em formulários e , você precisará executar essas três etapas antes de usar a Membership classe ou os controles da Web de logon do ASP.NET. Como já executamos essas etapas em tutoriais anteriores, estamos prontos para começar a usar a estrutura Associação!

Etapa 1: adicionando novas páginas de ASP.NET

Neste tutorial e nos próximos três, examinaremos várias funções e funcionalidades relacionadas à associação. Precisaremos de uma série de páginas ASP.NET para implementar os tópicos examinados ao longo desses tutoriais. Vamos criar essas páginas e, em seguida, um arquivo (Web.sitemap)de mapa do site .

Comece criando uma nova pasta no projeto chamado Membership. Em seguida, adicione cinco novas páginas ASP.NET à Membership pasta, vinculando cada página à Site.master página master. Nomeie as páginas:

  • CreatingUserAccounts.aspx
  • UserBasedAuthorization.aspx
  • EnhancedCreateUserWizard.aspx
  • AdditionalUserInfo.aspx
  • Guestbook.aspx

Neste ponto, a Gerenciador de Soluções do projeto deve ser semelhante à captura de tela mostrada na Figura 1.

Cinco novas páginas foram adicionadas à pasta de associação

Figura 1: Cinco novas páginas foram adicionadas à Membership pasta (clique para exibir a imagem em tamanho real)

Cada página deve, neste ponto, ter os dois controles content, um para cada um dos ContentPlaceHolders da página master: MainContent e LoginContent.

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent"
Runat="Server"> 
</asp:Content> 
<asp:Content ID="Content2" ContentPlaceHolderID="LoginContent"
Runat="Server"> 
</asp:Content>

Lembre-se de que a LoginContent marcação padrão do ContentPlaceHolder exibe um link para fazer logon ou fazer logoff do site, dependendo se o usuário está autenticado. No entanto, a presença do Content2 controle Conteúdo substitui a marcação padrão da página master. Como discutimos em Um tutorial de Visão geral da Autenticação de Formulários , isso é útil em páginas em que não queremos exibir opções relacionadas ao logon na coluna à esquerda.

Para essas cinco páginas, no entanto, queremos mostrar a marcação padrão da página master para ContentPlaceHolderLoginContent. Portanto, remova a marcação declarativa para o Content2 controle Conteúdo. Depois de fazer isso, cada marcação de cinco páginas deve conter apenas um Controle de conteúdo.

Etapa 2: Criando o mapa do site

Todos, exceto os sites mais triviais, precisam implementar alguma forma de uma interface do usuário de navegação. A interface do usuário de navegação pode ser uma lista simples de links para as várias seções do site. Como alternativa, esses links podem ser organizados em menus ou modos de exibição de árvore. Como desenvolvedores de página, a criação da interface do usuário de navegação é apenas metade da história. Também precisamos de alguns meios para definir a estrutura lógica do site de maneira mantenedível e atualizável. À medida que novas páginas são adicionadas ou páginas existentes removidas, queremos ser capazes de atualizar uma única fonte - o mapa do site - e ter essas modificações refletidas na interface do usuário de navegação do site.

Essas duas tarefas – definir o mapa do site e implementar uma interface do usuário de navegação com base no mapa do site – são fáceis de realizar graças à estrutura mapa do site e aos controles da Web de navegação adicionados no ASP.NET versão 2.0. A estrutura mapa do site permite que um desenvolvedor defina um mapa do site e, em seguida, acesse-o por meio de uma API programática (a SiteMap classe ). Os controles internos da Web de navegação incluem um controle Menu, o controle TreeView e o controle SiteMapPath.

Assim como as estruturas Associação e Funções, a estrutura mapa do site é criada em cima do modelo de provedor. O trabalho da classe de provedor Mapa do Site é gerar a estrutura na memória usada pela SiteMap classe de um armazenamento de dados persistente, como um arquivo XML ou uma tabela de banco de dados. O .NET Framework é fornecido com um provedor padrão de Mapa do Site que lê os dados do mapa do site de um arquivo XML (XmlSiteMapProvider) e esse é o provedor que usaremos neste tutorial. Para algumas implementações alternativas do provedor de Mapa do Site, consulte a seção Leituras Adicionais no final deste tutorial.

O provedor padrão do Mapa do Site espera que um arquivo XML formatado corretamente chamado Web.sitemap exista no diretório raiz. Como estamos usando esse provedor padrão, precisamos adicionar esse arquivo e definir a estrutura do mapa do site no formato XML apropriado. Para adicionar o arquivo, clique com o botão direito do mouse no nome do projeto em Gerenciador de Soluções e escolha Adicionar Novo Item. Na caixa de diálogo, opte por adicionar um arquivo do tipo Mapa do Site chamado Web.sitemap.

Adicionar um arquivo chamado Web.sitemap ao diretório raiz do projeto

Figura 2: Adicionar um arquivo chamado Web.sitemap ao diretório raiz do projeto (clique para exibir a imagem em tamanho real)

O arquivo de mapa do site XML define a estrutura do site como uma hierarquia. Essa relação hierárquica é modelada no arquivo XML por meio da ancestralidade dos <siteMapNode> elementos. O Web.sitemap deve começar com um <siteMap> nó pai que tenha precisamente um <siteMapNode> filho. Esse elemento de nível <siteMapNode> superior representa a raiz da hierarquia e pode ter um número arbitrário de nós descendentes. Cada <siteMapNode> elemento deve incluir um title atributo e, opcionalmente, incluir url atributos e description , entre outros; cada atributo não vazio url deve ser exclusivo.

Insira o seguinte XML no Web.sitemap arquivo :

<?xml version="1.0" encoding="utf-8" ?> 
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0"> 
 <siteMapNode url="~/Default.aspx" title="Home"> 
 <siteMapNode title="Membership">
 <siteMapNode url="~/Membership/CreatingUserAccounts.aspx" title="Creating User Accounts" /> 
 <siteMapNode url="~/Membership/UserBasedAuthorization.aspx" title="User-Based Authorization" /> 
 <siteMapNode url="~/Membership/Guestbook.aspx" title="Storing Additional User Information" /> 
 </siteMapNode> 
 </siteMapNode> 
</siteMap>

A marcação de mapa do site acima define a hierarquia mostrada na Figura 3.

O mapa do site representa uma estrutura de navegação hierárquica

Figura 3: o mapa do site representa uma estrutura de navegação hierárquica (clique para exibir a imagem em tamanho real)

Etapa 3: Atualizando a página mestra para incluir uma interface do usuário de navegação

ASP.NET inclui vários controles da Web relacionados à navegação para criar uma interface do usuário. Isso inclui os controles Menu, TreeView e SiteMapPath. Os controles Menu e TreeView renderizam a estrutura do mapa do site em um menu ou em uma árvore, respectivamente, enquanto o SiteMapPath exibe uma trilha que mostra o nó atual sendo visitado, bem como seus ancestrais. Os dados do mapa do site podem ser associados a outros controles da Web de dados usando o SiteMapDataSource e podem ser acessados programaticamente por meio da SiteMap classe .

Como uma discussão completa sobre a estrutura do Mapa do Site e os controles de Navegação está além do escopo desta série de tutoriais, em vez de gastar tempo criando nossa própria interface de usuário de navegação, vamos em vez disso emprestar a usada em minha série de tutoriais Trabalhando com Dados no ASP.NET 2.0 , que usa um controle Repeater para exibir uma lista com marcadores de duas profundidades de links de navegação, conforme mostrado na Figura 4.

Para criar essa interface, adicione a seguinte marcação declarativa à Site.master coluna esquerda da página master em que o texto TODO: Menu irá para aqui... atualmente reside.

<ul> 
 <li> 
 <asp:HyperLink runat="server" ID="lnkHome" NavigateUrl="~/Default.aspx">Home</asp:HyperLink>
 </li> 
 <asp:Repeater runat="server" ID="menu" DataSourceID="SiteMapDataSource1"> 
 <ItemTemplate>
 <li> 
 <asp:HyperLink ID="lnkMenuItem" runat="server" 
 NavigateUrl='<%# Eval("Url") %>'><%# Eval("Title") %></asp:HyperLink>
 <asp:Repeater ID="submenu" runat="server" DataSource="<%# 
 CType(Container.DataItem, SiteMapNode).ChildNodes %>"> 
 <HeaderTemplate> 
 <ul> 
 </HeaderTemplate> 
 <ItemTemplate>
 <li> 
 <asp:HyperLink ID="lnkMenuItem" 
 runat="server" NavigateUrl='<%#  Eval("Url") %>'><%# Eval("Title") %></asp:HyperLink> 
 </li>
 </ItemTemplate> 
 <FooterTemplate> 
 </ul> 
 </FooterTemplate>
 </asp:Repeater> 
 </li> 
 </ItemTemplate> 
 </asp:Repeater> 
</ul>
<asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" ShowStartingNode="false"/>

A marcação acima associa um controle Repeater chamado menu a um SiteMapDataSource, que retorna a hierarquia de mapa do site definida em Web.sitemap. Como a propriedade do ShowStartingNode controle SiteMapDataSource está definida como False, ela começa a retornar a hierarquia do mapa do site começando com os descendentes do nó Página Inicial. O Repeater exibe cada um desses nós (atualmente apenas Associação ) em um <li> elemento . Outro Repetidor interno exibe os filhos do nó atual em uma lista aninhada não ordenada.

A Figura 4 mostra a saída renderizada da marcação acima com a estrutura de mapa do site que criamos na Etapa 2. O Repetidor renderiza a marcação de lista não ordenada de baunilha; as regras de folha de estilos em cascata definidas em Styles.css são responsáveis pelo layout esteticamente agradável. Para obter uma descrição mais detalhada de como funciona a marcação acima, consulte o tutorial Páginas Mestras e Navegação no Site .

A interface do usuário de navegação é renderizada usando listas não ordenadas aninhadas

Figura 4: a interface do usuário de navegação é renderizada usando listas não ordenadas aninhadas (clique para exibir a imagem em tamanho real)

Adicionando navegação breadcrumb

Além da lista de links na coluna esquerda, vamos também fazer com que cada página exiba uma trilha. Uma trilha é um elemento de interface do usuário de navegação que mostra rapidamente aos usuários sua posição atual dentro da hierarquia do site. O controle SiteMapPath usa a estrutura Mapa do Site para determinar a localização da página atual no mapa do site e exibe uma trilha com base nessas informações.

Especificamente, adicione um <span> elemento ao elemento de cabeçalho <div> da página master e defina o atributo do class novo <span> elemento como breadcrumb. (A Styles.css classe contém uma regra para uma classe breadcrumb.) Em seguida, adicione um SiteMapPath a esse novo <span> elemento.

<div id="header"> 
 <span class="title">User Account Tutorials</span><br /> 
 <span class="breadcrumb"> 
 <asp:SiteMapPath ID="SiteMapPath1" runat="server"> 
 </asp:SiteMapPath> 
 </span> 
</div>

A Figura 5 mostra a saída do SiteMapPath ao visitar ~/Membership/CreatingUserAccounts.aspx.

A trilha de pão exibe a página atual e seus ancestrais no mapa do site

Figura 5: a trilha exibe a página atual e seus ancestrais no Mapa do Site (clique para exibir a imagem em tamanho real)

Etapa 4: Removendo a entidade de segurança personalizada e a lógica de identidade

Objetos de entidade de segurança e identidade personalizados podem ser associados ao usuário autenticado. Conseguimos isso criando um manipulador de eventos no Global.asax para o evento do PostAuthenticateRequest aplicativo, que é acionado após a FormsAuthenticationModule autenticação do usuário. Nesse manipulador de eventos, substituímos os GenericPrincipal objetos e FormsIdentity adicionados pelo FormsAuthenticationModule pelos CustomPrincipal objetos e CustomIdentity que criamos nesse tutorial.

Embora objetos de entidade de segurança e identidade personalizados sejam úteis em determinados cenários, na maioria dos casos os GenericPrincipal objetos e FormsIdentity são suficientes. Consequentemente, acho que vale a pena retornar ao comportamento padrão. Faça essa alteração removendo ou comentando o PostAuthenticateRequest manipulador de eventos ou excluindo totalmente o Global.asax arquivo.

Observação

Depois de comentar ou remover o código no , você precisará comentar o código na Default.aspx's classe code-behind que converte a User.Identity propriedade em Global.asaxuma CustomIdentity instância.

Etapa 5: Criar programaticamente um novo usuário

Para criar uma nova conta de usuário por meio da estrutura De associação, use o Membership método da CreateUserclasse. Esse método tem parâmetros de entrada para o nome de usuário, senha e outros campos relacionados ao usuário. Na invocação, ela delega a criação da nova conta de usuário para o provedor de Associação configurado e retorna um MembershipUser objeto que representa a conta de usuário recém-criada.

O CreateUser método tem quatro sobrecargas, cada uma aceitando um número diferente de parâmetros de entrada:

Essas quatro sobrecargas diferem na quantidade de informações coletadas. A primeira sobrecarga, por exemplo, requer apenas o nome de usuário e a senha da nova conta de usuário, enquanto a segunda também requer o endereço de email do usuário.

Essas sobrecargas existem porque as informações necessárias para criar uma nova conta de usuário dependem das configurações do provedor de associação. No tutorial Criando o esquema de associação no SQL Server examinamos a especificação das configurações do provedor de associação no .Web.config A Tabela 2 incluiu uma lista completa das configurações.

Uma dessas configurações de provedor de associação que afeta quais CreateUser sobrecargas podem ser usadas é a requiresQuestionAndAnswer configuração. Se requiresQuestionAndAnswer for definido como true (o padrão), ao criar uma nova conta de usuário, precisaremos especificar uma pergunta e resposta de segurança. Essas informações serão usadas posteriormente se o usuário precisar redefinir ou alterar sua senha. Especificamente, nesse momento, eles recebem a pergunta de segurança e devem inserir a resposta correta para redefinir ou alterar a senha. Consequentemente, se o requiresQuestionAndAnswer estiver definido como true , chamar uma das duas CreateUser primeiras sobrecargas resultará em uma exceção porque a pergunta e a resposta de segurança estão ausentes. Como nosso aplicativo está configurado no momento para exigir uma pergunta e resposta de segurança, precisaremos usar uma das duas últimas sobrecargas ao criar a do usuário programaticamente.

Para ilustrar o uso do CreateUser método , vamos criar uma interface do usuário em que solicitamos ao usuário seu nome, senha, email e uma resposta para uma pergunta de segurança predefinida. Abra a CreatingUserAccounts.aspx página na Membership pasta e adicione os seguintes controles da Web ao controle Conteúdo:

  • Uma Caixa de Texto chamada Username
  • Um TextBox chamado Password, cuja TextMode propriedade está definida como Password
  • Uma Caixa de Texto chamada Email
  • Um Rótulo chamado SecurityQuestion com sua Text propriedade desmarcada
  • Uma Caixa de Texto chamada SecurityAnswer
  • Um Botão chamado CreateAccountButton cuja Text propriedade está definida como Criar a Conta de Usuário
  • Um controle Label nomeado CreateAccountResults com sua Text propriedade desmarcada

Neste ponto, sua tela deve ser semelhante à captura de tela mostrada na Figura 6.

Adicionar os vários controles web à página CreatingUserAccounts.aspx

Figura 6: Adicionar os vários controles da Web ao CreatingUserAccounts.aspx Page (Clique para exibir a imagem em tamanho real)

O SecurityQuestion Rótulo e SecurityAnswer o TextBox destinam-se a exibir uma pergunta de segurança predefinida e coletar a resposta do usuário. Observe que as perguntas e respostas de segurança são armazenadas de acordo com o usuário, portanto, é possível permitir que cada usuário defina sua própria pergunta de segurança. No entanto, para este exemplo, decidi usar uma pergunta de segurança universal, ou seja: Qual é sua cor favorita?

Para implementar essa pergunta de segurança predefinida, adicione uma constante à classe code-behind da página chamada passwordQuestion, atribuindo-lhe a pergunta de segurança. Em seguida, no manipulador de eventos, atribua Page_Load essa constante à SecurityQuestion propriedade do Text Rótulo:

Const passwordQuestion As String = "What is your favorite color"
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 
 If Not Page.IsPostBack Then 
 SecurityQuestion.Text = passwordQuestion 
 End If 
End Sub

Em seguida, crie um manipulador de eventos para o CreateAccountButton' evento s Click e adicione o seguinte código:

Protected Sub CreateAccountButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles CreateAccountButton.Click 
 Dim createStatus As MembershipCreateStatus 
 Dim newUser As MembershipUser = _ 
 Membership.CreateUser(Username.Text, Password.Text, _ 
 Email.Text, passwordQuestion, _ 
 SecurityAnswer.Text, True, _ 
 createStatus)
 Select Case createStatus 
 Case MembershipCreateStatus.Success 
 CreateAccountResults.Text = "The user account was successfully created!" 
 Case MembershipCreateStatus.DuplicateUserName 
 CreateAccountResults.Text = "There already exists a user with this username." 
 Case MembershipCreateStatus.DuplicateEmail 
 CreateAccountResults.Text = "There already exists a user with this email address." 
 Case MembershipCreateStatus.InvalidEmail
 CreateAccountResults.Text = "There email address you provided in invalid." 
 Case MembershipCreateStatus.InvalidAnswer 
 CreateAccountResults.Text = "There security answer was invalid." 
 Case MembershipCreateStatus.InvalidPassword 
 CreateAccountResults.Text = "The password you provided is invalid. It must be seven characters long and have at least one non-alphanumeric character." 
 Case Else 
 CreateAccountResults.Text = "There was an unknown error; the user account was NOT created."
 End Select 
End Sub

O Click manipulador de eventos começa definindo uma variável chamada createStatus do tipo MembershipCreateStatus. MembershipCreateStatusé uma enumeração que indica o status da CreateUser operação. Por exemplo, se a conta de usuário for criada com êxito, a instância resultante MembershipCreateStatus será definida como um valor de Success; , por outro lado, se a operação falhar porque já existe um usuário com o mesmo nome de usuário, ela será definida como um valor de DuplicateUserName. CreateUser Na sobrecarga que usamos, precisamos passar uma MembershipCreateStatus instância para o método . Esse parâmetro é definido como o valor apropriado dentro do CreateUser método e podemos examinar seu valor após a chamada de método para determinar se a conta de usuário foi criada com êxito.

Depois de chamar CreateUser, passando createStatus, uma Select Case instrução é usada para gerar uma mensagem apropriada dependendo do valor atribuído a createStatus. Os números 7 mostram a saída quando um novo usuário foi criado com êxito. Os números 8 e 9 mostram a saída quando a conta de usuário não é criada. Na Figura 8, o visitante inseriu uma senha de cinco letras, que não atende aos requisitos de força de senha escritos nas configurações do provedor de associação. Na Figura 9, o visitante está tentando criar uma conta de usuário com um nome de usuário existente (aquele criado na Figura 7).

Uma nova conta de usuário foi criada com êxito

Figura 7: Uma nova conta de usuário foi criada com êxito (clique para exibir a imagem em tamanho real)

A conta de usuário não é criada porque a senha fornecida é muito fraca

Figura 8: a conta de usuário não é criada porque a senha fornecida é muito fraca (clique para exibir a imagem em tamanho real)

A conta de usuário não é criada porque o nome de usuário já está em uso

Figura 9: a conta de usuário não foi criada porque o nome de usuário já está em uso (clique para exibir a imagem em tamanho real)

Observação

Você pode estar se perguntando como determinar o êxito ou a falha ao usar uma das duas CreateUser primeiras sobrecargas de método, nenhuma das quais tem um parâmetro do tipo MembershipCreateStatus. Essas duas primeiras sobrecargas geram uma MembershipCreateUserException exceção em face de uma falha, que inclui uma StatusCode propriedade do tipo MembershipCreateStatus.

Depois de criar algumas contas de usuário, verifique se as contas foram criadas listando o conteúdo das aspnet_Users tabelas e aspnet_Membership no SecurityTutorials.mdf banco de dados. Como mostra a Figura 10, adicionei dois usuários por meio da CreatingUserAccounts.aspx página: Tito e Bruce.

Há dois usuários no Repositório de Usuários de Associação: Tito e Bruce

Figura 10: Há dois usuários no Repositório de Usuários de Associação: Tito e Bruce (Clique para exibir a imagem em tamanho real)

Embora o repositório de usuários associação agora inclua as informações da conta de Bruce e Tito, ainda não implementamos a funcionalidade que permite que Bruce ou Tito façam logon no site. Atualmente, Login.aspx valida as credenciais do usuário em relação a um conjunto embutido em código de pares de nome de usuário/senha – ele não valida as credenciais fornecidas na estrutura De associação. Por enquanto, ver as novas contas de usuário nas aspnet_Users tabelas e aspnet_Membership terá que ser suficiente. No próximo tutorial, Validando credenciais de usuário no Repositório de Usuários de Associação, atualizaremos a página de logon para validar no repositório de associações.

Observação

Se você não vir nenhum usuário em seu SecurityTutorials.mdf banco de dados, pode ser porque seu aplicativo Web está usando o provedor de associação padrão, AspNetSqlMembershipProvider, que usa o ASPNETDB.mdf banco de dados como seu repositório de usuários. Para determinar se esse é o problema, clique no botão Atualizar no Gerenciador de Soluções. Se um banco de dados chamado ASPNETDB.mdf tiver sido adicionado à App_Data pasta, esse será o problema. Retorne à Etapa 4 do tutorial Criando o esquema de associação no SQL Server para obter instruções sobre como configurar corretamente o provedor de associação.

Na maioria dos cenários de criação de conta de usuário, o visitante recebe uma interface para inserir seu nome de usuário, senha, email e outras informações essenciais, momento em que uma nova conta é criada. Nesta etapa, analisamos a criação de tal interface manualmente e, em seguida, vimos como usar o Membership.CreateUser método para adicionar programaticamente a nova conta de usuário com base nas entradas do usuário. No entanto, nosso código acabou de criar a nova conta de usuário. Ele não realizou nenhuma ação de acompanhamento, como fazer logon no usuário no site na conta de usuário criada ou enviar um email de confirmação para o usuário. Essas etapas adicionais exigiriam código adicional no manipulador de eventos do Click Botão.

ASP.NET é fornecido com o controle CreateUserWizard, que foi projetado para lidar com o processo de criação da conta de usuário, desde a renderização de uma interface do usuário para a criação de novas contas de usuário, até a criação da conta na estrutura Associação e a execução de tarefas de criação pós-conta, como enviar um email de confirmação e registrar o usuário recém-criado no site. Usar o controle CreateUserWizard é tão simples quanto arrastar o controle CreateUserWizard da Caixa de Ferramentas para uma página e, em seguida, definir algumas propriedades. Na maioria dos casos, você não precisará escrever uma única linha de código. Exploraremos esse controle bacana em detalhes na Etapa 6.

Se novas contas de usuário forem criadas apenas por meio de uma página da Web Create Account típica, é improvável que você precise escrever um código que use o CreateUser método , pois o controle CreateUserWizard provavelmente atenderá às suas necessidades. No entanto, o CreateUser método é útil em cenários em que você precisa de uma experiência de usuário criar conta altamente personalizada ou quando você precisa criar programaticamente novas contas de usuário por meio de uma interface alternativa. Por exemplo, você pode ter uma página que permite que um usuário carregue um arquivo XML que contém informações do usuário de algum outro aplicativo. A página pode analisar o conteúdo do arquivo XML carregado e criar uma nova conta para cada usuário representado no XML chamando o CreateUser método .

Etapa 6: Criando um novo usuário com o controle CreateUserWizard

ASP.NET é fornecido com vários controles da Web de logon. Esses controles auxiliam em muitos cenários comuns relacionados à conta de usuário e ao logon. O controle CreateUserWizard é um desses controles projetado para apresentar uma interface do usuário para adicionar uma nova conta de usuário à estrutura associação.

Como muitos dos outros controles da Web relacionados ao logon, o CreateUserWizard pode ser usado sem escrever uma única linha de código. Ele fornece intuitivamente uma interface do usuário com base nas definições de configuração do provedor de associação e chama internamente o Membership método da CreateUser classe depois que o usuário insere as informações necessárias e clica no botão Criar Usuário. O controle CreateUserWizard é extremamente personalizável. Há uma série de eventos que são acionados durante vários estágios do processo de criação da conta. Podemos criar manipuladores de eventos, conforme necessário, para injetar lógica personalizada no fluxo de trabalho de criação de conta. Além disso, a aparência de CreateUserWizard é muito flexível. Há várias propriedades que definem a aparência da interface padrão; se necessário, o controle pode ser convertido em um modelo ou etapas de registro de usuário adicionais podem ser adicionadas.

Vamos começar com uma olhada no uso da interface e do comportamento padrão do controle CreateUserWizard. Em seguida, exploraremos como personalizar a aparência por meio das propriedades e eventos do controle.

Examinando a interface e o comportamento padrão do CreateUserWizard

Retorne à CreatingUserAccounts.aspx página na Membership pasta, alterne para o modo Design ou Divisão e adicione um controle CreateUserWizard à parte superior da página. O controle CreateUserWizard é arquivado na seção Controles de logon da Caixa de Ferramentas. Depois de adicionar o controle, defina sua ID propriedade como RegisterUser. Como mostra a captura de tela na Figura 11, o CreateUserWizard renderiza uma interface com caixas de texto para o nome de usuário, senha, endereço de email e resposta de segurança do novo usuário.

O controle CreateUserWizard renderiza uma interface de usuário de criação genérica

Figura 11: o controle CreateUserWizard renderiza uma interface de usuário de criação genérica (clique para exibir a imagem em tamanho real)

Vamos demorar um pouco para comparar a interface do usuário padrão gerada pelo controle CreateUserWizard com a interface que criamos na Etapa 5. Para começar, o controle CreateUserWizard permite que o visitante especifique a pergunta e a resposta de segurança, enquanto nossa interface criada manualmente usou uma pergunta de segurança predefinida. A interface do controle CreateUserWizard também inclui controles de validação, enquanto que ainda não tínhamos implementado a validação nos campos de formulário da interface. E a interface de controle CreateUserWizard inclui uma caixa de texto Confirmar Senha (juntamente com um CompareValidator para garantir que o texto inserido nas caixas de texto Senha e Comparar Senha seja igual).

O interessante é que o controle CreateUserWizard consulta as definições de configuração do provedor de associação ao renderizar sua interface do usuário. Por exemplo, as caixas de texto de perguntas e respostas de segurança só serão exibidas se requiresQuestionAndAnswer estiver definida como True. Da mesma forma, CreateUserWizard adiciona automaticamente um controle RegularExpressionValidator para garantir que os requisitos de força de senha sejam atendidos e define suas ErrorMessage propriedades e ValidationExpression com base nas minRequiredPasswordLengthdefinições de configuração , minRequiredNonalphanumericCharacterse passwordStrengthRegularExpression .

O controle CreateUserWizard, como o nome indica, é derivado do controle Assistente. Os controles do assistente foram projetados para fornecer uma interface para concluir tarefas de várias etapas. Um controle do Assistente pode ter um número arbitrário de WizardSteps, cada um deles é um modelo que define os controles HTML e Web para essa etapa. Inicialmente, o controle assistente exibe o primeiro WizardStep, juntamente com controles de navegação que permitem que o usuário prossiga de uma etapa para a outra ou retorne às etapas anteriores.

Como mostra a marcação declarativa na Figura 11, a interface padrão do controle CreateUserWizard inclui dois WizardStep s:

  • CreateUserWizardStep ? renderiza a interface para coletar informações para criar a nova conta de usuário. Esta é a etapa mostrada na Figura 11.
  • CompleteWizardStep ? renderiza uma mensagem indicando que a conta foi criada com êxito.

A aparência e o comportamento do CreateUserWizard podem ser modificados convertendo uma dessas etapas em modelos ou adicionando seus próprios WizardStep s. Examinaremos a adição de um WizardStep à interface de registro no tutorial Armazenando informações adicionais do usuário .

Vamos ver o controle CreateUserWizard em ação. Visite a CreatingUserAccounts.aspx página por meio de um navegador. Comece inserindo alguns valores inválidos na interface de CreateUserWizard. Tente inserir uma senha que não esteja em conformidade com os requisitos de força da senha ou deixe a caixa de texto Nome de Usuário vazia. O CreateUserWizard exibirá uma mensagem de erro apropriada. A Figura 12 mostra a saída ao tentar criar um usuário com uma senha insuficientemente forte.

O CreateUserWizard injeta automaticamente controles de validação

Figura 12: o CreateUserWizard injeta automaticamente controles de validação (clique para exibir a imagem em tamanho real)

Em seguida, insira os valores apropriados no CreateUserWizard e clique no botão Criar Usuário. Supondo que os campos necessários tenham sido inseridos e a força da senha seja suficiente, o CreateUserWizard criará uma nova conta de usuário por meio da estrutura Associação e exibirá a CompleteWizardStepinterface do (consulte a Figura 13). Nos bastidores, CreateUserWizard chama o Membership.CreateUser método , assim como fizemos na Etapa 5.

Uma nova conta de usuário foi criada com êxito

Figura 13: Uma nova conta de usuário foi criada com êxito (clique para exibir a imagem em tamanho real)

Observação

Como mostra a Figura 13, a CompleteWizardStepinterface do inclui um botão Continuar. No entanto, neste ponto, clicar nele apenas executa um postback, deixando o visitante na mesma página. Na seção Personalizando a aparência e o comportamento do CreateUserWizard por meio de suas propriedades, veremos como você pode fazer com que esse botão envie o visitante para Default.aspx (ou alguma outra página).

Depois de criar uma nova conta de usuário, retorne ao Visual Studio e examine as aspnet_Users tabelas e aspnet_Membership como fizemos na Figura 10 para verificar se a conta foi criada com êxito.

Personalizando o comportamento e a aparência do CreateUserWizard por meio de suas propriedades

O CreateUserWizard pode ser personalizado de várias maneiras, por meio de propriedades, WizardStep s e manipuladores de eventos. Nesta seção, veremos como personalizar a aparência do controle por meio de suas propriedades; a próxima seção analisa a extensão do comportamento do controle por meio de manipuladores de eventos.

Praticamente todo o texto exibido na interface do usuário padrão do controle CreateUserWizard pode ser personalizado por meio de sua infinidade de propriedades. Por exemplo, os rótulos Nome de Usuário, Senha, Confirmar Senha, Email, Pergunta de Segurança e Resposta de Segurança exibidos à esquerda das caixas de texto podem ser personalizados pelas UserNameLabelTextpropriedades , PasswordLabelText, ConfirmPasswordLabelTextEmailLabelText, QuestionLabelText, e AnswerLabelText , respectivamente. Da mesma forma, há propriedades para especificar o texto para os botões Criar Usuário e Continuar no CreateUserWizardStep e CompleteWizardStep, bem como se esses botões forem renderizados como Botões, LinkButtons ou ImageButtons.

As cores, bordas, fontes e outros elementos visuais são configuráveis por meio de um host de propriedades de estilo. O próprio controle CreateUserWizard tem as propriedades comuns de estilo de controle da Web – BackColor, BorderStyle, CssClass, Fonte assim por diante – e há várias propriedades de estilo para definir a aparência de seções específicas da interface de CreateUserWizard. A TextBoxStyle propriedade, por exemplo, define os estilos para as caixas de texto no CreateUserWizardStep, enquanto a TitleTextStyle propriedade define o estilo para o título ( Inscrever-se para sua nova conta ).

Além das propriedades relacionadas à aparência, há várias propriedades que afetam o comportamento do controle CreateUserWizard. A DisplayCancelButton propriedade , se definida como True, exibe um botão Cancelar ao lado do botão Criar Usuário (o valor padrão é False). Se você exibir o botão Cancelar, certifique-se de também definir a CancelDestinationPageUrl propriedade , que especifica a página para a qual o usuário é enviado depois de clicar em Cancelar. Conforme observado na seção anterior, o botão Continuar na CompleteWizardStepinterface do causa um postback, mas deixa o visitante na mesma página. Para enviar o visitante para alguma outra página depois de clicar no botão Continuar, basta especificar a URL na ContinueDestinationPageUrl propriedade .

Vamos atualizar o RegisterUser controle CreateUserWizard para mostrar um botão Cancelar e enviar o visitante para Default.aspx quando os botões Cancelar ou Continuar forem clicados. Para fazer isso, defina a DisplayCancelButton propriedade como True e as CancelDestinationPageUrl propriedades e ContinueDestinationPageUrl como ~/Default.aspx. A Figura 14 mostra o CreateUserWizard atualizado quando exibido por meio de um navegador.

O botão CreateUserWizardStep inclui um botão Cancelar

Figura 14: o CreateUserWizardStep botão Incluir um Cancelamento (clique para exibir a imagem em tamanho real)

Quando um visitante insere um nome de usuário, senha, endereço de email e resposta e pergunta de segurança e clica em Criar Usuário, uma nova conta de usuário é criada e o visitante está conectado como aquele usuário recém-criado. Supondo que a pessoa que está visitando a página esteja criando uma nova conta para si mesma, esse é provavelmente o comportamento desejado. No entanto, talvez você queira permitir que os Administradores adicionem novas contas de usuário. Ao fazer isso, a conta de usuário seria criada, mas o Administrador permaneceria conectado como administrador (e não como a conta recém-criada). Esse comportamento pode ser modificado por meio da propriedade boolianaLoginCreatedUser.

As contas de usuário na estrutura Associação contêm um sinalizador aprovado; os usuários que não foram aprovados não podem fazer logon no site. Por padrão, uma conta recém-criada é marcada como aprovada, permitindo que o usuário faça logon no site imediatamente. No entanto, é possível ter novas contas de usuário marcadas como não aprovadas. Talvez você queira que um Administrador aprove manualmente novos usuários antes que eles possam fazer logon; ou talvez você queira verificar se o endereço de email inserido na inscrição é válido antes de permitir que um usuário faça logon. Seja qual for o caso, você pode ter a conta de usuário recém-criada marcada como não aprovada definindo a propriedade do DisableCreatedUser controle CreateUserWizard como True (o padrão é False).

Outras propriedades relacionadas ao comportamento da observação incluem AutoGeneratePassword e MailDefinition. Se a AutoGeneratePassword propriedade estiver definida como True, o CreateUserWizardStep não exibirá as caixas de texto Senha e Confirmar Senha; em vez disso, a senha do usuário recém-criada será gerada automaticamente usando o Membership método da GeneratePasswordclasse. O GeneratePassword método constrói uma senha de um comprimento especificado e com um número suficiente de caracteres não alfanuméricos para atender aos requisitos de força de senha configurados.

A MailDefinition propriedade será útil se você quiser enviar um email para o endereço de email especificado durante o processo de criação da conta. A MailDefinition propriedade inclui uma série de subpropriedades para definir informações sobre a mensagem de email construída. Essas subpropriedades incluem opções como Subject, Priority, IsBodyHtml, From, CCe BodyFileName. A BodyFileName propriedade aponta para um texto ou arquivo HTML que contém o corpo da mensagem de email. O corpo dá suporte a dois espaços reservados predefinidos: <%UserName%> e <%Password%>. Esses espaços reservados, se presentes no BodyFileName arquivo, serão substituídos pelo nome e senha do usuário criado recentemente.

Observação

A CreateUserWizard propriedade do MailDefinition controle apenas especifica detalhes sobre a mensagem de email que é enviada quando uma nova conta é criada. Ele não inclui detalhes sobre como a mensagem de email é realmente enviada (ou seja, se um servidor SMTP ou diretório de remoção de email é usado, quaisquer informações de autenticação e assim por diante). Esses detalhes de baixo nível precisam ser definidos na <system.net> seção em Web.config. Para obter mais informações sobre essas definições de configuração e sobre como enviar emails do ASP.NET 2.0 em geral, consulte as perguntas frequentes em SystemNetMail.com e meu artigo, Enviando Email no ASP.NET 2.0.

Estendendo o comportamento de CreateUserWizard usando manipuladores de eventos

O controle CreateUserWizard gera uma série de eventos durante seu fluxo de trabalho. Por exemplo, depois que um visitante insere seu nome de usuário, senha e outras informações pertinentes e clica no botão Criar Usuário, o controle CreateUserWizard aciona seu CreatingUser evento. Se houver um problema durante o processo de criação, o CreateUserError evento será acionado; no entanto, se o usuário for criado com êxito, o CreatedUser evento será acionado. Há eventos de controle CreateUserWizard adicionais que são gerados, mas estes são os três mais alemães.

Em determinados cenários, talvez queiramos tocar no fluxo de trabalho CreateUserWizard, o que podemos fazer criando um manipulador de eventos para o evento apropriado. Para ilustrar isso, vamos aprimorar o RegisterUser controle CreateUserWizard para incluir alguma validação personalizada no nome de usuário e na senha. Em particular, vamos aprimorar nosso CreateUserWizard para que os nomes de usuário não possam conter espaços à esquerda ou à direita e o nome de usuário não possa aparecer em nenhum lugar na senha. Em resumo, queremos impedir que alguém crie um nome de usuário como "Scott" ou tenha uma combinação de nome de usuário/senha como Scott e Scott.1234 .

Para fazer isso, criaremos um manipulador de eventos para que o CreatingUser evento execute nossas verificações de validação extras. Se os dados fornecidos não forem válidos, precisaremos cancelar o processo de criação. Também precisamos adicionar um controle Web Rótulo à página para exibir uma mensagem explicando que o nome de usuário ou senha é inválido. Comece adicionando um controle Label abaixo do controle CreateUserWizard, definindo sua ID propriedade como InvalidUserNameOrPasswordMessage e sua ForeColor propriedade como Red. Limpe sua Text propriedade e defina suas EnableViewState propriedades e Visible como False.

<asp:Label runat="server"" id="InvalidUserNameOrPasswordMessage"
 Visible="false" ForeColor="Red" EnableViewState="false"> 
</asp:Label>

Em seguida, crie um manipulador de eventos para o evento do CreatingUser controle CreateUserWizard. Para criar um manipulador de eventos, selecione o controle no Designer e vá para o janela Propriedades. A partir daí, clique no ícone de raio e clique duas vezes no evento apropriado para criar o manipulador de eventos.

Adicione o seguinte código ao manipulador de eventos do CreatingUser:

Protected Sub RegisterUser_CreatingUser(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.LoginCancelEventArgs) Handles RegisterUser.CreatingUser
 Dim trimmedUserName As String = RegisterUser.UserName.Trim() 
 If RegisterUser.UserName.Length <> trimmedUserName.Length Then 
 ' Show the error message 
 InvalidUserNameOrPasswordMessage.Text = "The username cannot contain leading or trailing spaces." 
 InvalidUserNameOrPasswordMessage.Visible = True 
 ' Cancel the create user workflow 
 e.Cancel = True 
 Else 
 ' Username is valid, make sure that the password does not contain the username 
 If RegisterUser.Password.IndexOf(RegisterUser.UserName, StringComparison.OrdinalIgnoreCase) >= 0 Then 
 ' Show the error message 
 InvalidUserNameOrPasswordMessage.Text = "The username may not appear anywhere in the password." 
 InvalidUserNameOrPasswordMessage.Visible = True 
 ' Cancel the create user workflow 
 e.Cancel = True 
 End If 
 End If 
End Sub

Observe que o nome de usuário e a senha inseridos no controle CreateUserWizard estão disponíveis por meio de suas UserName propriedades e Password, respectivamente. Usamos essas propriedades no manipulador de eventos acima para determinar se o nome de usuário fornecido contém espaços à esquerda ou à direita e se o nome de usuário é encontrado dentro da senha. Se uma dessas condições for atendida, uma mensagem de erro será exibida no InvalidUserNameOrPasswordMessage Rótulo e a propriedade do manipulador de e.Cancel eventos será definida como True. Se e.Cancel estiver definido como True, o CreateUserWizard curto-circuitos seu fluxo de trabalho, cancelando efetivamente o processo de criação da conta de usuário.

A Figura 15 mostra uma captura de tela de CreatingUserAccounts.aspx quando o usuário insere um nome de usuário com espaços à esquerda.

Nomes de usuário com espaços à esquerda ou à direita não são permitidos

Figura 15: Nomes de usuário com espaços à esquerda ou à direita não são permitidos (clique para exibir imagem em tamanho real)

Observação

Veremos um exemplo de como usar o evento do CreatedUser controle CreateUserWizard no tutorial Armazenando informações adicionais do usuário.

Resumo

O Membership método da classe cria uma nova conta de CreateUser usuário na estrutura Associação. Ele faz isso delegando a chamada para o provedor de Associação configurado. No caso do SqlMembershipProvider, o CreateUser método adiciona um registro às tabelas de aspnet_Users banco de dados e aspnet_Membership .

Embora novas contas de usuário possam ser criadas programaticamente (como vimos na Etapa 5), uma abordagem mais rápida e fácil é usar o controle CreateUserWizard. Esse controle renderiza uma interface do usuário de várias etapas para coletar informações do usuário e criar um novo usuário na estrutura Associação. Sob as capas, esse controle usa o mesmo Membership.CreateUser método examinado na Etapa 5, mas o controle cria a interface do usuário, os controles de validação e responde a erros de criação da conta de usuário sem precisar escrever uma lambida de código.

Neste ponto, temos a funcionalidade em vigor para criar novas contas de usuário. No entanto, a página de logon ainda está validando em relação às credenciais codificadas que especificamos no segundo tutorial. No próximo tutorial, atualizaremos Login.aspx para validar as credenciais fornecidas pelo usuário em relação à estrutura de associação.

Programação feliz!

Leitura Adicional

Para obter mais informações sobre os tópicos discutidos neste tutorial, consulte os seguintes recursos:

Sobre o autor

Scott Mitchell, autor de vários livros do ASP/ASP.NET e fundador da 4GuysFromRolla.com, trabalha com tecnologias da Microsoft Web desde 1998. Scott trabalha como consultor independente, treinador e escritor. Seu último livro é Sams Teach Yourself ASP.NET 2.0 em 24 Horas. Scott pode ser contatado em mitchell@4guysfromrolla.com ou através de seu blog em http://ScottOnWriting.NET.

Agradecimentos Especiais

Esta série de tutoriais foi revisada por muitos revisores úteis. A revisora principal deste tutorial foi Teresa Murphy. Interessado em revisar meus próximos artigos do MSDN? Nesse caso, solte-me uma linha em mitchell@4GuysFromRolla.com.