Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
por Scott Mitchell
Observação
Desde que este artigo foi escrito, os provedores de associação ASP.NET foram substituídos por ASP.NET Identity. É altamente recomendável atualizar os 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 uma série de vantagens em relação ao sistema de Associações do ASP.NET, incluindo:
- Melhor desempenho
- Extensibilidade e testabilidade melhoradas
- Suporte para OAuth, OpenID Connect e autenticação de dois fatores
- Suporte de identidade baseada em declarações
- Melhor interoperabilidade com o ASP.Net Core
Descarregar Código ou Descarregar PDF
Neste tutorial, vamos explorar a utilização do framework de Membros (através do SqlMembershipProvider) para criar novas contas de utilizador. Vamos ver como criar novos utilizadores programaticamente e através do controlo CreateUserWizard incorporado do ASP.NET.
Introduction
No tutorial anterior , instalámos o esquema de serviços de aplicação numa base de dados, que adicionou as tabelas, vistas e procedimentos armazenados necessários para o SqlMembershipProvider e SqlRoleProvider. Isto criou a infraestrutura de que precisaremos para o restante dos tutoriais desta série. Neste tutorial, vamos explorar a utilização do framework de Membros (através do SqlMembershipProvider) para criar novas contas de utilizador. Vamos ver como criar novos utilizadores programaticamente e através do controlo CreateUserWizard incorporado do ASP.NET.
Para além de aprendermos a criar novas contas de utilizador, também teremos de atualizar o site de demonstração que criámos inicialmente no tutorial Uma Visão Geral da Autenticação de Formulários e depois melhorado no tutorial de Configuração de Autenticação de Formulários e Tópicos Avançados . A nossa aplicação web de demonstração tem uma página de login que valida as credenciais dos utilizadores contra pares de nome de utilizador/palavra-passe codificados fixamente. Além disso, Global.asax inclui código que cria objetos personalizados IPrincipalIIdentity para utilizadores autenticados. Iremos atualizar a página de login para validar as credenciais dos utilizadores contra o Membership Framework e remover a lógica personalizada de principal e identidade.
Vamos começar!
A Lista de Verificação de Autenticação e Adesão de Formulários
Antes de começarmos a trabalhar com o quadro de Adesão, vamos dedicar um momento para rever os passos importantes que demos para chegar a este ponto. Ao utilizar o framework de Membership num cenário de autenticação baseado em formulários com o SqlMembershipProvider, os seguintes passos devem ser realizados antes de implementar a funcionalidade de Membership na sua aplicação web:
- Ativar 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 é ativada ao editar
Web.confige definir o<authentication>atributomodedo elemento paraForms. Com a autenticação de formulários ativada, cada pedido recebido é examinado para um pedido de autenticação de formulários, que, se presente, identifica o solicitante. - Adicione o esquema de serviços de aplicação à base de dados apropriada. Quando usamos o
SqlMembershipProvider, precisamos de instalar o esquema de serviços de aplicação numa base de dados. Normalmente, este esquema é adicionado à mesma base de dados que contém o modelo de dados da aplicação. O tutorial Creating the Membership Schema in SQL Server analisou a utilização daaspnet_regsql.exeferramenta para isso. - Personalize as Definições da Aplicação Web para referenciar a base de dados a partir do passo 2. O tutorial Creating the Membership Schema in SQL Server mostrou duas formas de configurar a aplicação web para que usasse
SqlMembershipProvidera base de dados selecionada no passo 2: modificando o nome daLocalSqlServerstring de ligação; ou adicionando um novo fornecedor registado à lista de fornecedores do framework de membros e personalizando esse novo fornecedor para usar a base de dados a partir do passo 2.
Ao construir uma aplicação web que utiliza autenticação SqlMembershipProvider baseada em formulários, terá de realizar estes três passos antes de usar a classe Membership ou os controlos ASP.NET Login Web. Como já realizámos estes passos em tutoriais anteriores, estamos prontos para começar a usar o framework de Membros!
Passo 1: Adicionar Novas Páginas ASP.NET
Neste tutorial e nos próximos três, iremos analisar várias funções e capacidades relacionadas com a Afiliação. Vamos precisar de uma série de páginas ASP.NET para implementar os temas abordados nestes tutoriais. Vamos criar essas páginas e depois um ficheiro (Web.sitemap)de mapa do site.
Comece criando uma nova pasta no projeto chamado Membership. De seguida, adicione cinco novas páginas ASP.NET à Membership pasta, ligando cada página à Site.master página-mestre. Nomeie as páginas:
CreatingUserAccounts.aspxUserBasedAuthorization.aspxEnhancedCreateUserWizard.aspxAdditionalUserInfo.aspxGuestbook.aspx
Neste ponto, o Explorador de Soluções do seu projeto deverá parecer semelhante à captura de ecrã mostrada na Figura 1.
Figura 1: Cinco novas páginas foram adicionadas à Membership pasta (clique para ver a imagem em tamanho real)
Cada página deve, neste ponto, ter os dois controlos de Conteúdo, um para cada um dos ContentPlaceHolders da página principal: 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 que a LoginContent marcação padrão do ContentPlaceHolder mostra um link para iniciar sessão ou sair do site, dependendo se o utilizador está autenticado. A presença do controlo Content2 de Conteúdo, no entanto, sobrepõe-se à marcação padrão da página-mestre. Como discutimos no tutorial An Overview of Forms Authentication , isto é útil em páginas onde não queremos mostrar opções relacionadas com o login na coluna da esquerda.
Para estas cinco páginas, no entanto, queremos mostrar a marcação padrão da página mestra para o LoginContent ContentPlaceHolder. Por isso, remova a marcação declarativa para o Content2 controle de conteúdo. Depois disso, cada uma das marcações das cinco páginas deverá conter apenas um controlo de Conteúdo.
Passo 2: Criação do Mapa do Sítio
Todos, exceto os sites mais triviais, precisam de implementar algum tipo de interface de navegação. A interface de navegação pode ser uma simples lista de ligações para as várias secções do site. Alternativamente, estes links podem ser organizados em menus ou vistas em árvore. Como programadores de páginas, criar a interface de navegação é apenas metade da história. Também precisamos de alguns meios para definir a estrutura lógica do site de forma sustentável e atualizável. À medida que novas páginas são adicionadas ou páginas existentes removidas, queremos poder atualizar uma única fonte – o mapa do site – e ter essas modificações refletidas na interface de navegação do site.
Estas duas tarefas – definir o mapa do site e implementar uma interface de navegação baseada no mapa do site – são fáceis de realizar graças à estrutura Site Map e aos controlos Navigation Web adicionados na versão 2.0 ASP.NET. O framework Site Map permite a um programador definir um mapa de site e depois aceder a ele através de uma API programática (a SiteMap classe). Os controlos integrados da Web de Navegação incluem um controlo de Menu, o controlo TreeView e o controlo SiteMapPath.
Tal como os frameworks de Membership e Roles, o framework Site Map é construído sobre o modelo do fornecedor. A função da classe fornecedora Site Map é gerar a estrutura em memória usada pela SiteMap classe a partir de um armazenamento de dados persistente, como um ficheiro XML ou uma tabela de base de dados. O .NET Framework vem com um fornecedor de Site Map por defeito que lê os dados do site map a partir de um ficheiro XML (XmlSiteMapProvider), e este é o fornecedor que iremos usar neste tutorial. Para algumas implementações alternativas de fornecedores de Mapas de Sítios, consulte a secção Leituras Adicionais no final deste tutorial.
Para o diretório raiz, o fornecedor padrão do Site Map espera que exista um ficheiro XML devidamente formatado, denominado Web.sitemap. Como estamos a usar este fornecedor predefinido, precisamos de adicionar tal ficheiro e definir a estrutura do mapa do site no formato XML apropriado. Para adicionar o ficheiro, clique com o botão direito no nome do projeto no Explorador de Soluções e escolha Adicionar Novo Item. Na caixa de diálogo, opte por adicionar um ficheiro do tipo Site Map chamado Web.sitemap.
Figura 2: Adicionar um ficheiro nomeado Web.sitemap ao diretório raiz do projeto (Clique para ver a imagem em tamanho real)
O ficheiro XML de mapa do site define a estrutura do site como uma hierarquia. Esta relação hierárquica é modelada no ficheiro XML através da ancestralidade dos <siteMapNode> elementos. O Web.sitemap deve começar com um <siteMap> nó pai que tenha exatamente um <siteMapNode> filho. Este elemento de topo <siteMapNode> 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 pode, opcionalmente, incluir url atributos e description , entre outros; cada atributo não vazio url deve ser único.
Introduza o seguinte XML no Web.sitemap ficheiro:
<?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 do mapa do local acima define a hierarquia mostrada na Figura 3.
Figura 3: O mapa do local representa uma estrutura de navegação hierárquica (clique para ver a imagem em tamanho real)
Passo 3: Atualizar a Página Mestre para incluir uma Interface de Utilizador Navegacional
ASP.NET inclui vários controlos Web relacionados com navegação para desenhar uma interface de utilizador. Estes incluem os controlos Menu, TreeView e SiteMapPath. Os controlos Menu e TreeView renderizam a estrutura do mapa do site num menu ou numa árvore, respetivamente, enquanto o SiteMapPath apresenta uma breadcrumb que mostra o nó atual visitado, bem como os seus antecessores. Os dados do mapa do local podem ser atribuídos a outros controlos Web usando o SiteMapDataSource e podem ser acedidos programaticamente através da SiteMap classe.
Como uma discussão aprofundada sobre o framework do Site Map e os controlos de navegação não está dentro do escopo desta série de tutoriais, em vez de despendermos tempo a criar a nossa própria interface de navegação, vamos antes usar a que emprego na minha série de tutoriais Trabalhar com Dados em ASP.NET 2.0, que utiliza um controlo Repetidor para mostrar uma lista hierárquica de navegação com dois níveis, em formato de tópicos, como mostrado na Figura 4.
Adicionar uma lista de links de dois níveis na coluna da esquerda
Para criar esta interface, adicione a seguinte marcação declarativa na Site.master coluna esquerda da página mestre, onde o texto "TODO: Menu irá 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="<%#
((SiteMapNode) Container.DataItem).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 controlo Repetidor nomeado menu a um SiteMapDataSource, que devolve a hierarquia do mapa do site definida em Web.sitemap. Como a propriedade ShowStartingNode do controlo SiteMapDataSource está definida como Falso, começa a devolver a hierarquia do mapa do site, iniciando pelos descendentes do nó "Home". O Repetidor mostra cada um destes nós (atualmente apenas "Membros") num <li> elemento. Outro Repetidor interno exibe então os filhos do nó atual numa lista aninhada e não ordenada.
A Figura 4 mostra a saída renderizada da marcação acima com a estrutura do mapa do site que criámos no Passo 2. O Repeater renderiza a marcação padrão de lista não ordenada; as regras da folha de estilo em cascata definidas em Styles.css são responsáveis pelo layout esteticamente agradável. Para uma descrição mais detalhada de como funciona a marcação acima, consulte o tutorial de Páginas Mestres e Navegação do Site .
Figura 4: A Interface de Utilizador Navegacional é Renderizada Usando Listas Não Ordenadas Aninhadas (Clique para ver a imagem em tamanho real)
Adicionar navegação por migalhas de pão
Para além da lista de links na coluna da esquerda, vamos também mostrar uma migalha de pão em cada página. Uma breadcrumb é um elemento de interface de navegação que mostra rapidamente aos utilizadores a sua posição atual dentro da hierarquia do site. O controlo SiteMapPath utiliza a estrutura Site Map para determinar a localização da página atual no mapa do site e depois apresenta uma breadcrumb com base nessa informação.
Especificamente, adicione um <span> elemento ao cabeçalho <div> da página principal e defina o atributo <span> do novo class elemento como "breadcrumb". (A classe Styles.css contém uma regra para uma classe de "breadcrumb".) De seguida, adicione um SiteMapPath a este novo elemento <span>.
<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.
Figura 5: A migalha de pão mostra a página atual e os seus antepassados no mapa do local (Clique para ver a imagem em tamanho real)
Passo 4: Remoção da Lógica Principal e de Identidade Personalizada
Objetos principais e identidade personalizados podem ser associados ao utilizador autenticado. Conseguimos isto criando um gestor Global.asax de eventos para o evento PostAuthenticateRequest da aplicação, que é ativado depois de FormsAuthenticationModule ter autenticado o utilizador. Neste gestor de eventos, substituímos os objetos GenericPrincipal e FormsIdentity que foram adicionados pelo FormsAuthenticationModule pelos objetos CustomPrincipal e CustomIdentity que criámos nesse tutorial.
Na maioria dos casos, os objetos GenericPrincipal e FormsIdentity são suficientes, embora os objetos principal e identidade personalizados sejam úteis em certos cenários. Consequentemente, penso que valeria a pena voltar ao comportamento padrão. Faça esta alteração removendo ou comentando o PostAuthenticateRequest gestor de eventos ou eliminando completamente o Global.asax ficheiro.
Passo 5: Criação Programática de um Novo Utilizador
Para criar uma nova conta de utilizador através do framework Membership, utilize o método CreateUser da classe Membership. Este método tem parâmetros de entrada para o nome de utilizador, palavra-passe e outros campos relacionados com o utilizador. Na invocação, delega a criação da nova conta de utilizador ao fornecedor de Membros configurado e depois devolve um MembershipUser objeto que representa a conta de utilizador recém-criada.
O CreateUser método tem quatro sobrecargas, cada uma aceitando um número diferente de parâmetros de entrada:
CreateUser(username, password)CreateUser(username, password, email)CreateUser(username, password, email, passwordQuestion, passwordAnswer, isApproved, MembershipCreateStatus)CreateUser(username, password, email, passwordQuestion, passwordAnswer, isApproved, providerUserKey, MembershipCreateStatus)
Estas quatro sobrecargas diferem na quantidade de informação recolhida. A primeira sobrecarga, por exemplo, requer apenas o nome de utilizador e a palavra-passe da nova conta de utilizador, enquanto a segunda também requer o endereço de email do utilizador.
Estas sobrecargas existem porque a informação necessária para criar uma nova conta de utilizador depende das definições de configuração do fornecedor de membros. No tutorial Creating the Membership Schema in SQL Server, analisámos a especificação das definições de configuração do provedor de adesão em Web.config. A Tabela 2 incluía uma lista completa das definições de configuração.
Uma dessas definições de configuração do fornecedor de associação que impacta as sobrecargas que podem ser usadas é a definição requiresQuestionAndAnswer. Se requiresQuestionAndAnswer estiver definido como true (o predefinido), então ao criar uma nova conta de utilizador devemos especificar uma pergunta e resposta de segurança. Esta informação é posteriormente usada caso o utilizador precise de redefinir ou alterar a sua palavra-passe. Especificamente, nessa altura é mostrada a pergunta de segurança e têm de introduzir a resposta correta para poder redefinir ou alterar a palavra-passe. Consequentemente, se o requiresQuestionAndAnswer for definido como true, então chamar qualquer uma das duas primeiras CreateUser sobrecargas resulta em uma exceção porque a pergunta e a resposta de segurança estão ausentes. Como a nossa aplicação está atualmente configurada para exigir uma pergunta e resposta de segurança, teremos de usar uma das duas últimas sobrecargas ao criar programáticamente os utilizadores.
Para ilustrar o uso do CreateUser método, vamos criar uma interface de utilizador onde pedimos ao utilizador o seu nome, palavra-passe, email e uma resposta a uma questão de segurança pré-definida. Abra a CreatingUserAccounts.aspx página na Membership pasta e adicione os seguintes controlos Web ao controlo de Conteúdo:
- Uma Caixa de Texto chamada
Username - Uma TextBox chamada
Password, cujaTextModepropriedade é definida comoPassword - Uma Caixa de Texto chamada
Email - Um rótulo chamado
SecurityQuestioncom a sua propriedadeTextapagada - Uma Caixa de Texto chamada
SecurityAnswer - Um botão chamado
CreateAccountButtoncuja propriedade de Texto está definida como "Criar a Conta do Utilizador" - Um controlo de etiqueta nomeado
CreateAccountResultscom a sua propriedadeTextapagada
Neste ponto, o seu ecrã deverá parecer semelhante à captura de ecrã mostrada na Figura 6.
Figura 6: Adicionar os vários controlos web à CreatingUserAccounts.aspx página (Clique para ver a imagem em tamanho real)
A SecurityQuestion Etiqueta e SecurityAnswer a Caixa de Texto destinam-se a mostrar uma pergunta de segurança pré-definida e a recolher a resposta do utilizador. Note-se que tanto a pergunta como a resposta de segurança são armazenadas utilizador a utilizador, pelo que é possível permitir que cada utilizador defina a sua própria questão de segurança. No entanto, para este exemplo decidi usar uma pergunta universal de segurança, nomeadamente: "Qual é a sua cor favorita?"
Para implementar esta questão de segurança pré-definida, adicione uma constante à classe code-behind da página chamada passwordQuestion, atribuindo-lhe a pergunta de segurança. Depois, no Page_Load handler de eventos, atribua esta constante à SecurityQuestion propriedade do Text Rótulo:
const string passwordQuestion = "What is your favorite color";
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
SecurityQuestion.Text = passwordQuestion;
}
De seguida, crie um handler de evento para o evento Click do CreateAccountButton e adicione o seguinte código:
protected void CreateAccountButton_Click(object sender, EventArgs e)
{
MembershipCreateStatus createStatus;
MembershipUser newUser = Membership.CreateUser(Username.Text, Password.Text, Email.Text, passwordQuestion, SecurityAnswer.Text, true, out createStatus);
switch (createStatus)
{
case MembershipCreateStatus.Success:
CreateAccountResults.Text = "The user account was successfully created!";
break;
case MembershipCreateStatus.DuplicateUserName:
CreateAccountResults.Text = "There already exists a user with this username.";
break;
case MembershipCreateStatus.DuplicateEmail:
CreateAccountResults.Text = "There already exists a user with this email address.";
break;
case MembershipCreateStatus.InvalidEmail:
CreateAccountResults.Text = "There email address you provided in invalid.";
break;
case MembershipCreateStatus.InvalidAnswer:
CreateAccountResults.Text = "There security answer was invalid.";
break;
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.";
break;
default:
CreateAccountResults.Text = "There was an unknown error; the user account was NOT created.";
break;
}
}
O Click gestor de eventos começa por definir uma variável chamada createStatus de tipo MembershipCreateStatus.
MembershipCreateStatus é uma enumeração que indica o estado da CreateUser operação. Por exemplo, se a conta de utilizador for criada com sucesso, a instância resultante MembershipCreateStatus será definida para um valor de Success; por outro lado, se a operação falhar porque já existe um utilizador com o mesmo nome de utilizador, será definida para um valor de DuplicateUserName. No CreateUser overload que usamos, precisamos passar como parâmetro out uma instância MembershipCreateStatus para o método. Este parâmetro é definido para o valor apropriado dentro do CreateUser método, e podemos examinar o seu valor após a chamada do método para determinar se a conta de utilizador foi criada com sucesso.
Após chamar CreateUser, passando em createStatus, uma instrução switch é usada para emitir uma mensagem apropriada dependendo do valor atribuído a createStatus. A Figura 7 mostra a saída quando um novo utilizador foi criado com sucesso. As figuras 8 e 9 mostram a saída quando a conta de utilizador não é criada. Na Figura 8, o visitante introduziu uma palavra-passe de cinco letras, que não cumpre os requisitos de força de palavra-passe especificados nas definições de configuração do fornecedor de membros. Na Figura 9, o visitante está a tentar criar uma conta de utilizador com um nome de utilizador já existente (aquele criado na Figura 7).
Figura 7: Uma Nova Conta de Utilizador Criada com Sucesso (Clique para ver a imagem em tamanho real)
Figura 8: A Conta de Utilizador Não É Criada Porque a Palavra-passe Fornecida é Demasiado Fraca (Clique para ver a imagem em tamanho real)
Figura 9: A conta de utilizador não é criada porque o nome de utilizador já está em uso (Clique para ver a imagem em tamanho real)
Observação
Pode estar a perguntar-se como determinar o sucesso ou o fracasso ao usar uma das duas CreateUser primeiras sobrecargas de métodos, nenhuma das quais tem um parâmetro do tipo MembershipCreateStatus. Estas duas primeiras sobrecargas lançam uma MembershipCreateUserException exceção perante uma falha, que inclui uma StatusCode propriedade do tipo MembershipCreateStatus.
Depois de criar algumas contas de utilizador, verifique se as contas foram criadas listando o conteúdo das aspnet_Users tabelas e aspnet_Membership na SecurityTutorials.mdf base de dados. Como mostra a Figura 10, adicionei dois utilizadores através da CreatingUserAccounts.aspx página: Tito e Bruce.
Figura 10: Existem dois utilizadores na Loja de Utilizadores de Membros: Tito e Bruce (Clique para ver a imagem em tamanho real)
Embora a loja de utilizadores de membros inclua agora a informação das contas do Bruce e do Tito, ainda não implementámos funcionalidades que permitam ao Bruce ou ao Tito aceder ao site. Atualmente, Login.aspx valida as credenciais do utilizador contra um conjunto codificado de pares nome de utilizador/palavra-passe – não valida as credenciais fornecidas contra o framework de Membros. Por agora, ver as novas contas de utilizador nas tabelas aspnet_Users e aspnet_Membership terá de ser suficiente. No próximo tutorial, Validar Credenciais de Utilizador contra a Loja de Utilizadores de Membros, vamos atualizar a página de login para validar contra a Loja de Membros.
Observação
Se não vir utilizadores na sua SecurityTutorials.mdf base de dados, pode ser porque a sua aplicação web está a usar o fornecedor de membro por defeito, AspNetSqlMembershipProvider, que utiliza a ASPNETDB.mdf base de dados para armazenar utilizadores. Para determinar se este é o problema, clique no botão Atualizar no Explorador de Soluções. Se uma base de dados nomeada ASPNETDB.mdf foi adicionada à App_Data pasta, esse é o problema. Volte ao Passo 4 do tutorial Criar o Esquema de Membros no SQL Server para instruções sobre como configurar corretamente o fornecedor de Membros.
Na maioria dos cenários de criação de conta de utilizador, o visitante recebe uma interface para introduzir o seu nome de utilizador, palavra-passe, email e outras informações essenciais, momento em que é criada uma nova conta. Neste passo, analisámos a construção manual de tal interface e depois vimos como usar o Membership.CreateUser método para adicionar programaticamente a nova conta de utilizador com base nas entradas do utilizador. O nosso código, no entanto, apenas criou a nova conta de utilizador. Não realizou quaisquer ações de seguimento, como iniciar sessão do utilizador no site através da conta recém-criada, ou enviar um email de confirmação ao utilizador. Estes passos adicionais exigiriam código adicional no handler de eventos do Click Botão.
ASP.NET vem com o controlo CreateUserWizard, que foi concebido para gerir o processo de criação da conta de utilizador, desde a visualização de uma interface para criar novas contas, até à criação da conta no framework de Membros e à realização de tarefas pós-criação da conta, como enviar um email de confirmação e iniciar sessão de login do utilizador recém-criado no site. Usar o controlo CreateUserWizard é tão simples como arrastar o controlo CreateUserWizard da Toolbox para uma página e depois definir algumas propriedades. Na maioria dos casos, não precisará de escrever uma única linha de código. Vamos explorar este controlo prático em detalhe no Passo 6.
Se novas contas de utilizador forem criadas apenas através de uma página típica de Criar Conta, é pouco provável que alguma vez precise de escrever código que utilize o CreateUser método, pois o controlo CreateUserWizard provavelmente irá satisfazer as suas necessidades. No entanto, o método CreateUser é útil em cenários onde precisa de uma experiência de utilizador de Criar Conta altamente personalizada ou quando necessita programar a criação de novas contas de utilizador através de uma interface alternativa. Por exemplo, pode ter uma página que permite a um utilizador carregar um ficheiro XML que contenha informações do utilizador de outra aplicação. A página pode analisar o conteúdo do ficheiro XML carregado e criar uma nova conta para cada utilizador representado no XML ao chamar o CreateUser método.
Passo 6: Criar um Novo Utilizador com o Controlo CreateUserWizard
ASP.NET inclui vários controlos Web de Login. Estes controlos ajudam em muitos cenários comuns relacionados com contas de utilizador e login. O control CreateUserWizard é um desses controles concebidos para apresentar uma interface de utilizador para adicionar uma nova conta de utilizador à estrutura de Filiação.
Tal como muitos outros controlos Web relacionados com Login, o CreateUserWizard pode ser usado sem escrever uma única linha de código. Fornece intuitivamente uma interface do utilizador baseada nas definições de configuração do provedor de associação e chama internamente o método CreateUser da classe Membership depois de o utilizador inserir a informação necessária e clicar no botão "Criar Utilizador". O controlo CreateUserWizard é extremamente personalizável. Existem uma série de eventos que acontecem em várias fases do processo de criação da conta. Podemos criar gestores de eventos, conforme necessário, para injetar lógica personalizada no fluxo de trabalho de criação de contas. Além disso, a aparência do CreateUserWizard é muito flexível. Existem várias propriedades que definem a aparência da interface padrão; Se necessário, o controlo pode ser convertido num modelo ou podem ser adicionados "passos" adicionais de registo de utilizadores.
Vamos começar por analisar a utilização da interface e comportamento padrão do controlo CreateUserWizard. Depois exploraremos como personalizar a aparência através das propriedades e eventos do controlo.
Examinar a Interface e o Comportamento Padrão do CreateUserWizard
Volte à CreatingUserAccounts.aspx página na Membership pasta, mude para o modo Design ou Split, e depois adicione um controlo CreateUserWizard no topo da página. O controlo CreateUserWizard está arquivado na secção de controlos de login do Toolbox. Depois de adicionar o controlo, defina a sua ID propriedade para RegisterUser. Como mostra a captura de ecrã na Figura 11, o CreateUserWizard renderiza uma interface com caixas de texto para o nome de utilizador, palavra-passe, endereço de email e perguntas e respostas de segurança do novo utilizador.
Figura 11: O controlo CreateUserWizard renderiza uma interface genérica Create User (Clique para ver imagem em tamanho real)
Vamos parar um momento para comparar a interface de utilizador padrão gerada pelo controlo CreateUserWizard com a interface que criámos no Passo 5. Para começar, o controlo CreateUserWizard permite ao visitante especificar tanto a pergunta de segurança como a resposta, enquanto a nossa interface criada manualmente usava uma pergunta de segurança pré-definida. A interface do controlo do CreateUserWizard também inclui controlos de validação, enquanto ainda não tínhamos implementado validação nos campos de formulário da nossa interface. E a interface de controlo do CreateUserWizard inclui uma caixa de texto "Confirmar Palavra-Passe" (juntamente com um CompareValidator para garantir que o texto introduzido nas caixas de texto "Palavra-Passe" e "Confirmar Palavra-Passe" seja igual).
O que é interessante é que o controlo CreateUserWizard consulta as configurações do fornecedor de associação ao renderizar a sua interface de utilizador. Por exemplo, as caixas de texto de perguntas e respostas de segurança só são exibidas se requiresQuestionAndAnswer estiver definido como Verdadeiro. Da mesma forma, o CreateUserWizard adiciona automaticamente um controlo RegularExpressionValidator para garantir que os requisitos de força da palavra-passe são cumpridos, e define as suas propriedades ErrorMessage e ValidationExpression com base nas definições de configuração minRequiredPasswordLength, minRequiredNonalphanumericCharacters e passwordStrengthRegularExpression.
O controlo CreateUserWizard, como o nome indica, deriva do controlo Wizard. Os controlos do assistente são concebidos para fornecer uma interface para completar tarefas em vários passos. Um controlo Wizard pode ter um número arbitrário de WizardSteps, sendo cada um deles um modelo que define os controlos HTML e Web para essa etapa. O controlo do Assistente apresenta inicialmente o primeiro WizardStep, juntamente com controlos de navegação que permitem ao utilizador avançar de um passo para o seguinte, ou regressar aos passos anteriores.
Como mostra a marcação declarativa na Figura 11, a interface padrão do controlo CreateUserWizard inclui dois WizardSteps:
-
CreateUserWizardStep– renderiza a interface para recolher informações para criar a nova conta de utilizador. Este é o passo mostrado na Figura 11. -
CompleteWizardStep– apresenta uma mensagem indicando que a conta foi criada com sucesso.
A aparência e o comportamento do CreateUserWizard podem ser modificados convertendo qualquer um destes passos em templates, ou adicionando o seu próprio WizardSteps. Vamos analisar a adição de um WizardStep à interface de registo no tutorial Armazenar Informação Adicional do Utilizador.
Vamos ver o controlo CreateUserWizard em ação. Visite a CreatingUserAccounts.aspx página através de um navegador. Comece por introduzir alguns valores inválidos na interface do CreateUserWizard. Tente inserir uma palavra-passe que não cumpra os requisitos de força, ou deixar a caixa de texto "Nome de Utilizador" vazia. O CreateUserWizard irá mostrar uma mensagem de erro apropriada. A Figura 12 mostra a saída ao tentar criar um utilizador com uma palavra-passe insuficientemente forte.
Figura 12: O CreateUserWizard injeta automaticamente controlos de validação (Clique para ver imagem em tamanho real)
De seguida, introduza os valores apropriados no CreateUserWizard e clique no botão "Criar Utilizador". Assumindo que os campos necessários foram introduzidos e que a força da palavra-passe é suficiente, o CreateUserWizard criará uma nova conta de utilizador através do framework de Membership e depois exibirá a interface do CompleteWizardStep (ver Figura 13). Nos bastidores, o CreateUserWizard chama o Membership.CreateUser método, tal como fizemos no Passo 5.
Figura 13: Uma Nova Conta de Utilizador Foi Criada com Sucesso (Clique para ver a imagem em tamanho real)
Observação
Como mostra a Figura 13, a interface do CompleteWizardStep inclui um botão Continuar. No entanto, neste momento, clicar apenas envia os dados novamente, deixando o visitante na mesma página. Na secção "Personalizar a Aparência e Comportamento do CreateUserWizard através das suas propriedades", vamos ver como pode fazer com que este botão envie o visitante para Default.aspx (ou para outra página).
Depois de criar uma nova conta de utilizador, volte 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 sucesso.
Personalização do comportamento e aparência do CreateUserWizard através das suas propriedades
O CreateUserWizard pode ser personalizado de várias formas, por meio de propriedades, WizardSteps, e manipuladores de eventos. Nesta secção, vamos ver como personalizar a aparência do controlo através das suas propriedades; A secção seguinte analisa a extensão do comportamento do controlo através de gestores de eventos.
Praticamente todo o texto exibido na interface padrão do controlo CreateUserWizard pode ser personalizado através da sua vasta gama de propriedades. Por exemplo, os rótulos "Nome de Utilizador", "Palavra-passe", "Confirmar Palavra-passe", "E-mail", "Pergunta de Segurança" e "Resposta de Segurança" exibidos à esquerda das caixas de texto podem ser personalizados pelas propriedades, respetivamenteUserNameLabelTextPasswordLabelTextConfirmPasswordLabelTextEmailLabelText. QuestionLabelTextAnswerLabelText Da mesma forma, existem propriedades para especificar o texto dos botões "Criar Utilizador" e "Continuar" nos CreateUserWizardStep e CompleteWizardStep, bem como se estes botões forem renderizados como Botões, LinkBotões ou BotõesImagem.
As cores, bordas, fontes e outros elementos visuais são configuráveis através de uma série de propriedades de estilo. O próprio controlo CreateUserWizard tem as propriedades comuns de estilo de controlo Web – BackColor, BorderStyle, CssClass, Font, e assim por diante – e existem várias propriedades de estilo para definir a aparência de secções específicas da interface do CreateUserWizard. A TextBoxStyle propriedade, por exemplo, define os estilos das caixas de texto no CreateUserWizardStep, enquanto a TitleTextStyle propriedade define o estilo do título ("Inscreve-se para a Sua Nova Conta").
Para além das propriedades relacionadas com a aparência, existem várias propriedades que afetam o comportamento do controlo CreateUserWizard. A DisplayCancelButton propriedade, se definida como Verdadeiro, mostra um botão Cancelar ao lado do botão "Criar Utilizador" (o valor padrão é Falso). Se mostrar o botão Cancelar, certifique-se também de definir a CancelDestinationPageUrl propriedade, que especifica a página para onde o utilizador é enviado após clicar em Cancelar. Conforme mencionado na secção anterior, o botão Continuar na interface de CompleteWizardStep provoca um postback, mas mantém o visitante na mesma página. Para enviar o visitante para outra página após clicar no botão Continuar, basta especificar a URL na ContinueDestinationPageUrl propriedade.
Vamos atualizar o RegisterUser controlo CreateUserWizard para mostrar um botão Cancelar e enviar o visitante para Default.aspx quando os botões Cancelar ou Continuar estiverem clicados. Para conseguir isto, defina a DisplayCancelButton propriedade como True e ambas as CancelDestinationPageUrl propriedades e ContinueDestinationPageUrl como "~/Default.aspx". A Figura 14 mostra o atualizado CreateUserWizard quando visualizado através de um navegador.
Figura 14: Inclui CreateUserWizardStep um botão de cancelar (Clique para ver a imagem em tamanho real)
Quando um visitante insere um nome de utilizador, palavra-passe, endereço de email e uma pergunta e resposta de segurança e clica em "Criar Utilizador", é criada uma nova conta de utilizador e o visitante inicia sessão como esse novo utilizador. Assumindo que a pessoa que visita a página está a criar uma nova conta para si, este é provavelmente o comportamento desejado. No entanto, pode querer permitir que os Administradores adicionem novas contas de utilizador. Ao fazê-lo, a conta de utilizador seria criada, mas o Administrador permaneceria ligado como Administrador (e não como a conta recém-criada). Este comportamento pode ser modificado através da propriedade booleanaLoginCreatedUser.
As contas de utilizador no framework de Associação contêm um sinalizador aprovado; os utilizadores que não são aprovados não podem iniciar sessão no site. Por defeito, uma conta recém-criada é marcada como aprovada, permitindo ao utilizador iniciar sessão no site imediatamente. No entanto, é possível que novas contas de utilizador sejam marcadas como não aprovadas. Talvez queira que um Administrador aprove manualmente os novos utilizadores antes de poderem iniciar sessão; Ou talvez queiras verificar se o endereço de email introduzido na inscrição é válido antes de permitir que um utilizador faça login. Seja qual for o caso, pode marcar a conta de utilizador recém-criada como não aprovada definindo a propriedade do DisableCreatedUser controlo CreateUserWizard para True (o padrão é False).
Outras propriedades relacionadas com o comportamento a destacar incluem AutoGeneratePassword e MailDefinition. Se a AutoGeneratePassword propriedade estiver definida como Verdadeiro, as caixas de texto "palavra-passe" e "confirmar palavra-passe" não serão exibidas; em vez disso, a palavra-passe do utilizador recém-criado é gerada automaticamente usando o método GeneratePassword da classe Membership. O GeneratePassword método constrói uma palavra-passe com um comprimento especificado e com um número suficiente de caracteres não alfanuméricos para satisfazer os requisitos de força de palavra-passe configurados.
A MailDefinition propriedade é útil se quiser enviar um email para o endereço especificado durante o processo de criação da conta. A MailDefinition propriedade inclui uma série de subpropriedades para definir informação sobre a mensagem de email construída. Estas subpropriedades incluem opções como Subject, Priority, IsBodyHtml, From, CC, e BodyFileName. A BodyFileName propriedade aponta para um ficheiro de texto ou HTML que contém o corpo da mensagem de email. O corpo suporta dois placeholders pré-definidos: <%UserName%> e <%Password%>. Estes marcadores de lugar, se estiverem presentes no BodyFileName ficheiro, serão substituídos pelo nome e palavra-passe do utilizador recém-criados.
Observação
A CreateUserWizard propriedade do MailDefinition controlo especifica apenas detalhes sobre a mensagem de email enviada quando uma nova conta é criada. Não inclui quaisquer detalhes sobre como a mensagem de email é realmente enviada (ou seja, se é usado um servidor SMTP ou diretório de email drop, qualquer informação de autenticação, e assim por diante). Estes detalhes de baixo nível precisam de ser definidos na <system.net> secção em Web.config. Para mais informações sobre estas definições de configuração e sobre o envio de emails da ASP.NET 2.0 em geral, consulte as Perguntas Frequentes em SystemNetMail.com e o meu artigo, Enviar Email em ASP.NET 2.0.
Extensão do Comportamento do CreateUserWizard usando Gestores de Eventos
O controlo CreateUserWizard gera vários eventos durante o seu fluxo de trabalho. Por exemplo, depois de um visitante introduzir o seu nome de utilizador, palavra-passe e outras informações pertinentes e clicar no botão "Criar Utilizador", o controlo CreateUserWizard levanta o seuCreatingUser evento. Se houver um problema durante o processo de criação, o CreateUserError evento é disparado; no entanto, se o utilizador for criado com sucesso, o CreatedUser evento é levantado. Existem eventos adicionais de controlo do CreateUserWizard que surgem, mas estes são os três mais relevantes.
Em certos cenários, podemos querer aceder ao fluxo de trabalho CreateUserWizard, o que podemos fazer criando um gestor de eventos para o evento apropriado. Para ilustrar isto, vamos melhorar o RegisterUser controlo CreateUserWizard para incluir alguma validação personalizada no nome de utilizador e na palavra-passe. Em particular, vamos melhorar o nosso CreateUserWizard para que os nomes de utilizador não possam conter espaços iniciais ou finais e que o nome de utilizador não apareça em lado nenhum da palavra-passe. Resumindo, queremos impedir que alguém crie um nome de utilizador como "Scott", ou que tenha uma combinação de nome de utilizador/palavra-passe como "Scott" e "Scott.1234".
Para isso, criaremos um gestor de eventos para o CreatingUser evento realizar as nossas verificações extra de validação. Se os dados fornecidos não forem válidos, precisamos de cancelar o processo de criação. Também precisamos de adicionar um controlo Label Web à página para mostrar uma mensagem a explicar que o nome de utilizador ou palavra-passe é inválido. Comece por adicionar um controlo de Rótulo por baixo do controlo CreateUserWizard, definindo a sua ID propriedade para InvalidUserNameOrPasswordMessage e a sua ForeColor propriedade para Red. Limpe a propriedade Text e defina as propriedades EnableViewState e Visible como Falso.
<asp:Label runat="server" id="InvalidUserNameOrPasswordMessage"
Visible="false" ForeColor="Red" EnableViewState="false">
</asp:Label>
De seguida, crie um gestor de eventos para o evento do CreatingUser controlo do CreateUserWizard. Para criar um gestor de eventos, selecione o controlo no Designer e depois vá à janela de Propriedades. A partir daí, clica no ícone do raio e depois faz duplo clique no evento apropriado para criar o handler de eventos.
Adicione o seguinte código ao manipulador de CreatingUser eventos:
protected void RegisterUser_CreatingUser(object sender, LoginCancelEventArgs e)
{
string trimmedUserName = RegisterUser.UserName.Trim();
if (RegisterUser.UserName.Length != trimmedUserName.Length)
{
// 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)
{
// 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;
}
}
}
Note que o nome de utilizador e a palavra-passe introduzidos no controlo CreateUserWizard estão disponíveis através das propriedades UserName e Password, respetivamente. Usamos estas propriedades no handler de eventos acima para determinar se o nome de utilizador fornecido contém espaços iniciais ou finais e se o nome de utilizador se encontra dentro da palavra-passe. Se alguma destas condições for cumprida, uma mensagem de erro é exibida na InvalidUserNameOrPasswordMessage Etiqueta e a propriedade do e.Cancel gestor de eventos é definida para true. Se e.Cancel for definido para true, o CreateUserWizard interrompe o seu fluxo de trabalho, cancelando efetivamente o processo de criação da conta de utilizador.
A Figura 15 mostra uma captura de ecrã de CreatingUserAccounts.aspx quando o utilizador insere um nome de utilizador com espaços iniciais.
Figura 15: Nomes de utilizador com espaços iniciais ou finais não são permitidos (Clique para ver a imagem em tamanho real)
Observação
Veremos um exemplo de utilização do evento do controlo CreatedUser CreateUserWizard no tutorial de Armazenamento de Informação Adicional do Utilizador.
Resumo
O método CreateUser da classe Membership cria uma nova conta de utilizador no Framework de Associação. Faz-no delegando a chamada ao fornecedor de Membros configurado. No caso do SqlMembershipProvider, o CreateUser método adiciona um registo às aspnet_Users tabelas da base de dados e aspnet_Membership .
Embora novas contas de utilizador possam ser criadas programaticamente (como vimos no Passo 5), uma abordagem mais rápida e fácil é usar o controlo CreateUserWizard. Este controlo gera uma interface de utilizador em vários passos para recolher informações do utilizador e criar um novo utilizador no framework de Membros. Por baixo das coberturas, este controlo usa o mesmo Membership.CreateUser método analisado no Passo 5, mas o controlo cria a interface do utilizador, os controlos de validação e responde a erros de criação de contas de utilizador sem precisar de escrever um único pedaço de código.
Neste momento, já temos a funcionalidade para criar novas contas de utilizador. No entanto, a página de login continua a validar contra essas credenciais codificadas que especificámos no segundo tutorial. No próximo tutorial iremos atualizar Login.aspx para validar as credenciais fornecidas pelo utilizador contra o framework de Membros.
Feliz Programação!
Leitura adicional
Para obter mais informações sobre os tópicos discutidos neste tutorial, consulte os seguintes recursos:
-
CreateUserDocumentação Técnica - Visão geral do Controlo do CreateUserWizard
- Criação de um Provedor de Mapa do Site Baseado em Sistema de Arquivos
- Criação de uma Interface de Utilizador de Passo a Passo com o Controlo Assistente do ASP.NET 2.0
- Examinando a navegação no site do ASP.NET 2.0
- Páginas Mestras e Navegação do Site
- O fornecedor de mapas de sites SQL que você estava à espera
Sobre o Autor
Scott Mitchell, autor de vários livros sobre ASP/ASP.NET e fundador da 4GuysFromRolla.com, trabalha com tecnologias Web da Microsoft desde 1998. Scott trabalha como consultor, formador e escritor independente. Seu último livro é Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Scott pode ser contatado em mitchell@4guysfromrolla.com ou através de seu blog em http://ScottOnWriting.NET.
Um agradecimento especial a...
Esta série de tutoriais foi revisada por muitos revisores úteis. A revisor principal deste tutorial foi Teresa Murphy. Interessado em rever meus próximos artigos do MSDN? Se for o caso, envie-me uma mensagem para mitchell@4GuysFromRolla.com.