Criação do esquema de associação no SQL Server (VB)

por Scott Mitchell

Observação

Desde que este artigo foi escrito, os provedores de associação de ASP.NET foram substituídos por 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 sobre o 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 ASP.Net Core

Baixar código ou baixar PDF

Este tutorial começa examinando técnicas para adicionar o esquema necessário ao banco de dados para usar o SqlMembershipProvider. Depois disso, examinaremos as tabelas-chave no esquema e discutiremos sua finalidade e importância. Este tutorial termina com uma olhada em como informar a um aplicativo ASP.NET qual provedor a estrutura de Associação deve usar.

Introdução

Os dois tutoriais anteriores examinados usando a autenticação de formulários para identificar os visitantes do site. A estrutura de autenticação de formulários facilita que os desenvolvedores registrem um usuário em um site e lembrem-se deles em visitas de página por meio do uso de tíquetes de autenticação. A FormsAuthentication classe inclui métodos para gerar o tíquete e adicioná-lo aos cookies do visitante. O FormsAuthenticationModule examina todas as solicitações de entrada e, para aqueles com um tíquete de autenticação válido, cria e associa um GenericPrincipal objeto e a uma FormsIdentity solicitação atual. A autenticação de formulários é apenas um mecanismo para conceder um tíquete de autenticação a um visitante ao fazer logon e, em solicitações subsequentes, analisar esse tíquete para determinar a identidade do usuário. Para que um aplicativo Web dê suporte a contas de usuário, ainda precisamos implementar um repositório de usuários e adicionar funcionalidades para validar credenciais, registrar novos usuários e a miríade de outras tarefas relacionadas à conta de usuário.

Antes do ASP.NET 2.0, os desenvolvedores estavam no gancho para implementar todas essas tarefas relacionadas à conta de usuário. Felizmente, a equipe de ASP.NET reconheceu essa deficiência e introduziu a estrutura de associação com o ASP.NET 2.0. A estrutura Associação é um conjunto de classes no .NET Framework que fornecem uma interface programática para realizar tarefas principais relacionadas à conta de usuário. Essa estrutura é criada no topo do modelo de provedor, o que permite que os desenvolvedores conectem uma implementação personalizada a uma API padronizada.

Conforme discutido no tutorial Noções básicas de segurança e suporte ASP.NET, o .NET Framework é fornecido com dois provedores de Associação internos: ActiveDirectoryMembershipProvider e SqlMembershipProvider. Como o nome indica, o SqlMembershipProvider usa um banco de dados do Microsoft SQL Server como o repositório de usuários. Para usar esse provedor em um aplicativo, precisamos informar ao provedor qual banco de dados usar como repositório. Como você pode imaginar, o SqlMembershipProvider espera que o banco de dados do repositório de usuários tenha determinadas tabelas de banco de dados, exibições e procedimentos armazenados. Precisamos adicionar esse esquema esperado ao banco de dados selecionado.

Este tutorial começa examinando técnicas para adicionar o esquema necessário ao banco de dados para usar o SqlMembershipProvider. Depois disso, examinaremos as tabelas-chave no esquema e discutiremos sua finalidade e importância. Este tutorial termina com uma olhada em como informar a um aplicativo ASP.NET qual provedor a estrutura de Associação deve usar.

Vamos começar!

Etapa 1: Decidir onde colocar o repositório de usuários

Um ASP.NET dados do aplicativo geralmente é armazenado em várias tabelas em um banco de dados. Ao implementar o esquema de SqlMembershipProvider banco de dados, devemos decidir se deseja colocar o esquema De associação no mesmo banco de dados que os dados do aplicativo ou em um banco de dados alternativo.

É recomendável localizar o esquema De associação no mesmo banco de dados que os dados do aplicativo pelos seguintes motivos:

  • Manutenção de um aplicativo cujos dados são encapsulados em um banco de dados é mais fácil de entender, manter e implantar do que um aplicativo que tem dois bancos de dados separados.
  • Integridade relacional localizando as tabelas relacionadas à associação no mesmo banco de dados que as tabelas de aplicativos, é possível estabelecer restrições de chave estrangeira entre as chaves primárias nas tabelas relacionadas à associação e tabelas de aplicativos relacionadas.

A desacoplamento dos dados do repositório de usuários e do aplicativo em bancos de dados separados só faz sentido se você tiver vários aplicativos que usam bancos de dados separados, mas precisam compartilhar um repositório de usuários comum.

Criar um banco de dados

O aplicativo que criamos desde o segundo tutorial ainda não precisou de um banco de dados. No entanto, precisamos de um agora para o repositório de usuários. Vamos criar um e, em seguida, adicionar a ele o esquema exigido pelo SqlMembershipProvider provedor (consulte Etapa 2).

Observação

Ao longo desta série de tutoriais, usaremos um banco de dados do Microsoft SQL Server 2005 Express Edition para armazenar nossas tabelas de aplicativos e o SqlMembershipProvider esquema. Essa decisão foi tomada por dois motivos: primeiro, devido ao seu custo - gratuito - o Express Edition é a versão mais legível acessível do SQL Server 2005; segundo, SQL Server 2005 Express Edition bancos de dados podem ser colocados diretamente no aplicativo App_Data Web pasta, tornando-o um cinch para empacotar o banco de dados e o aplicativo Web juntos em um arquivo ZIP e reimplantá-lo sem nenhuma instrução de instalação especial ou opções de configuração. Se você preferir acompanhar usando uma versão não Express Edition de SQL Server, fique à vontade. As etapas são praticamente idênticas. O SqlMembershipProvider esquema funcionará com qualquer versão do Microsoft SQL Server 2000 ou posterior.

No Gerenciador de Soluções, clique com o botão direito do App_Data mouse na pasta e escolha Adicionar Novo Item. (Se você não vir uma App_Data pasta no projeto, clique com o botão direito do mouse no projeto em Gerenciador de Soluções, selecione Adicionar ASP.NET Pasta e escolha App_Data.) Na caixa de diálogo Adicionar Novo Item, escolha adicionar um novo Banco de Dados SQL chamado SecurityTutorials.mdf. Neste tutorial, adicionaremos o SqlMembershipProvider esquema a esse banco de dados; nos tutoriais subsequentes, criaremos tabelas adicionais para capturar nossos dados do aplicativo.

Adicionar um novo banco de dados SecurityTutorials.mdf nomeado Banco de Dados SQL à pasta App_Data

Figura 1: Adicionar um novo banco de dados nomeado SecurityTutorials.mdf Banco de Dados SQL à App_Data pasta (clique para exibir a imagem em tamanho real)

Adicionar um banco de dados à pasta o App_Data inclui automaticamente na exibição Explorer banco de dados. (Na versão não Express Edition do Visual Studio, a Explorer de Banco de Dados é chamada de Explorer do Servidor.) Vá para o banco de dados Explorer e expanda o banco de dados just-addedSecurityTutorials. Se você não vir o banco de dados Explorer na tela, vá para o menu Exibir e escolha Banco de Dados Explorer ou clique em Ctrl+Alt+S. Como mostra a Figura 2, o SecurityTutorials banco de dados está vazio – ele não contém tabelas, nenhuma exibição e nenhum procedimento armazenado.

O banco de dados SecurityTutorials está vazio no momento

Figura 2: O SecurityTutorials banco de dados está vazio no momento (clique para exibir a imagem em tamanho real)

Etapa 2: Adicionar oSqlMembershipProvideresquema ao banco de dados

O SqlMembershipProvider requer um conjunto específico de tabelas, exibições e procedimentos armazenados a serem instalados no banco de dados do repositório de usuários. Esses objetos de banco de dados necessários podem ser adicionados usando a aspnet_regsql.exe ferramenta . Esse arquivo está localizado na %WINDIR%\Microsoft.Net\Framework\v2.0.50727\ pasta .

Observação

A aspnet_regsql.exe ferramenta oferece funcionalidade de linha de comando e uma interface gráfica do usuário. A interface gráfica é mais amigável e é o que examinaremos neste tutorial. A interface de linha de comando é útil quando a SqlMembershipProvider adição do esquema precisa ser automatizada, como em scripts de build ou cenários de teste automatizados.

A aspnet_regsql.exe ferramenta é usada para adicionar ou remover ASP.NET serviços de aplicativo a um banco de dados SQL Server especificado. Os serviços de aplicativo ASP.NET abrangem os esquemas para e SqlMembershipProviderSqlRoleProvider, juntamente com os esquemas para os provedores baseados em SQL para outras estruturas ASP.NET 2.0. Precisamos fornecer dois bits de informações para a aspnet_regsql.exe ferramenta:

  • Quer queiramos adicionar ou remover serviços de aplicativos e
  • O banco de dados do qual adicionar ou remover o esquema dos serviços de aplicativo

Ao solicitar o uso do banco de dados, a aspnet_regsql.exe ferramenta solicita que forneçamos o nome do servidor no qual o banco de dados reside, as credenciais de segurança para se conectar ao banco de dados e o nome do banco de dados. Se você estiver usando a Edição não Expressa do SQL Server, já deve saber essas informações, pois são as mesmas informações que você deve fornecer por meio de um cadeia de conexão ao trabalhar com o banco de dados por meio de uma página da Web ASP.NET. No entanto, determinar o nome do servidor e do banco de dados ao usar um banco de dados SQL Server 2005 Express Edition na App_Data pasta é um pouco mais envolvido.

A seção a seguir examina uma maneira simples de especificar o nome do servidor e do banco de dados para um banco de dados SQL Server 2005 Express Edition na App_Data pasta. Se você não estiver usando SQL Server 2005 Express Edition fique à vontade para ir para a seção Instalando os Serviços de Aplicativo.

Determinando o nome do servidor e do banco de dados para um banco de dados SQL Server 2005 Express Edition naApp_Datapasta

Para usar a aspnet_regsql.exe ferramenta, precisamos saber os nomes do servidor e do banco de dados. O nome do servidor é localhost\InstanceName. Provavelmente, o InstanceName é SQLExpress. No entanto, se você instalou SQL Server 2005 Express Edition manualmente (ou seja, não o instalou automaticamente durante a instalação do Visual Studio), é possível que você tenha selecionado um nome de instância diferente.

O nome do banco de dados é um pouco mais complicado de determinar. Normalmente, os bancos de dados na App_Data pasta têm um nome de banco de dados que inclui um identificador global exclusivo, juntamente com o caminho para o arquivo de banco de dados. Precisamos determinar esse nome de banco de dados para adicionar o esquema de serviços de aplicativo por meio aspnet_regsql.exede .

A maneira mais fácil de verificar o nome do banco de dados é examiná-lo por meio de SQL Server Management Studio. SQL Server Management Studio fornece uma interface gráfica para gerenciar bancos de dados SQL Server 2005, mas não é fornecido com o Express Edition do SQL Server 2005. A boa notícia é que você pode baixar o Express Edition gratuito de SQL Server Management Studio.

Observação

Se você também tiver uma versão não Express Edition do SQL Server 2005 instalada em sua área de trabalho, a versão completa do Management Studio provavelmente estará instalada. Você pode usar a versão completa para determinar o nome do banco de dados, seguindo as mesmas etapas descritas abaixo para o Express Edition.

Comece fechando o Visual Studio para garantir que todos os bloqueios impostos pelo Visual Studio no arquivo de banco de dados sejam fechados. Em seguida, inicie SQL Server Management Studio e conecte-se ao localhost\InstanceName banco de dados para SQL Server 2005 Express Edition. Conforme observado anteriormente, as chances são de que o nome da instância seja SQLExpress. Para a opção Autenticação, selecione Autenticação do Windows.

Conectar-se à Instância SQL Server 2005 Express Edition

Figura 3: Conectar-se à Instância SQL Server 2005 Express Edition (Clique para exibir a imagem em tamanho real)

Depois de se conectar à instância SQL Server 2005 Express Edition, o Management Studio exibe pastas para os Bancos de Dados, as configurações de segurança, os Objetos do Servidor e assim por diante. Se você expandir a guia Bancos de Dados, verá que o SecurityTutorials.mdf banco de dados não está registrado na instância do banco de dados – precisamos anexar o banco de dados primeiro.

Clique com o botão direito do mouse na pasta Bancos de Dados e escolha Anexar no menu de contexto. Isso exibirá a caixa de diálogo Anexar Bancos de Dados. A partir daqui, clique no botão Adicionar, navegue até o SecurityTutorials.mdf banco de dados e clique em OK. A Figura 4 mostra a caixa de diálogo Anexar Bancos de Dados após a seleção do SecurityTutorials.mdf banco de dados. A Figura 5 mostra o Pesquisador de Objetos do Management Studio depois que o banco de dados foi anexado com êxito.

Anexar o banco de dados SecurityTutorials.mdf

Figura 4: Anexar o SecurityTutorials.mdf banco de dados (clique para exibir a imagem em tamanho real)

O banco de dados SecurityTutorials.mdf aparece na pasta Bancos de Dados

Figura 5: o SecurityTutorials.mdf banco de dados aparece na pasta Bancos de Dados (clique para exibir a imagem em tamanho real)

Como mostra a Figura 5, o SecurityTutorials.mdf banco de dados tem um nome bastante abstruso. Vamos alterá-lo para um nome mais memorável (e mais fácil de digitar). Clique com o botão direito do mouse no banco de dados, escolha Renomear no menu de contexto e renomeie-o SecurityTutorialsDatabase. Isso não altera o nome do arquivo, apenas o nome que o banco de dados usa para se identificar para SQL Server.

Renomear o banco de dados para SecurityTutorialsDatabase

Figura 6: renomeie o banco de dados para SecurityTutorialsDatabase(Clique para exibir a imagem em tamanho real)

Neste ponto, sabemos os nomes do servidor e do banco de dados para o SecurityTutorials.mdf arquivo de banco de dados: localhost\InstanceName e SecurityTutorialsDatabase, respectivamente. Agora estamos prontos para instalar os serviços de aplicativos por meio da aspnet_regsql.exe ferramenta.

Instalando os Serviços de Aplicativos

Para iniciar a aspnet_regsql.exe ferramenta, vá para o menu Iniciar e escolha Executar. Insira %WINDIR%\Microsoft.Net\Framework\v2.0.50727\aspnet_regsql.exe na caixa de texto e clique em OK. Como alternativa, você pode usar o Windows Explorer para fazer drill down para a pasta apropriada e clicar duas vezes no aspnet_regsql.exe arquivo. Qualquer abordagem obterá os mesmos resultados.

Executar a aspnet_regsql.exe ferramenta sem argumentos de linha de comando inicia a interface gráfica do usuário do Assistente de Instalação do ASP.NET SQL Server. O assistente facilita a adição ou a remoção dos serviços de aplicativo ASP.NET em um banco de dados especificado. A primeira tela do assistente, mostrada na Figura 7, descreve a finalidade da ferramenta.

Usar o assistente de instalação de ASP.NET SQL Server faz para adicionar o esquema de associação

Figura 7: Usar o assistente de instalação de ASP.NET SQL Server faz para adicionar o esquema de associação (clique para exibir a imagem em tamanho real)

A segunda etapa do assistente nos pergunta se queremos adicionar os serviços de aplicativo ou removê-los. Como queremos adicionar as tabelas, exibições e procedimentos armazenados necessários para o SqlMembershipProvider, escolha a opção Configurar SQL Server para serviços de aplicativos. Posteriormente, se você quiser remover esse esquema do banco de dados, execute novamente esse assistente, mas escolha a opção Remover informações dos serviços de aplicativo de um banco de dados existente.

Escolha a opção Configurar SQL Server para Serviços de Aplicativo

Figura 8: escolha a opção Configurar SQL Server para Serviços de Aplicativos (clique para exibir a imagem em tamanho real)

A terceira etapa solicita as informações do banco de dados: o nome do servidor, as informações de autenticação e o nome do banco de dados. Se você estiver acompanhando este tutorial e tiver adicionado o SecurityTutorials.mdf banco de dados a App_Data, anexado a localhost\InstanceNamee renomeado como SecurityTutorialsDatabase, use os seguintes valores:

  • Servidor: localhost\InstanceName
  • Autenticação do Windows
  • Banco de dados: SecurityTutorialsDatabase

Insira as Informações do Banco de Dados

Figura 9: Insira as Informações do Banco de Dados (Clique para exibir a imagem em tamanho real)

Depois de inserir as informações do banco de dados, clique em Avançar. A etapa final resume as etapas que serão executadas. Clique em Avançar para instalar os serviços de aplicativo e, em seguida, Concluir para concluir o assistente.

Observação

Se você usou o Management Studio para anexar o banco de dados e renomear o arquivo de banco de dados, desanexe o banco de dados e feche o Management Studio antes de reabrir o Visual Studio. Para desanexar o SecurityTutorialsDatabase banco de dados, clique com o botão direito do mouse no nome do banco de dados e, no menu Tarefas, escolha Desanexar.

Após a conclusão do assistente, retorne ao Visual Studio e navegue até o banco de dados Explorer. Expanda a pasta Tabelas. Você deve ver uma série de tabelas cujos nomes começam com o prefixo aspnet_. Da mesma forma, uma variedade de exibições e procedimentos armazenados podem ser encontrados nas pastas Exibições e Procedimentos Armazenados. Esses objetos de banco de dados compõem o esquema dos serviços de aplicativo. Examinaremos os objetos de banco de dados específicos de associação e função na Etapa 3.

Uma variedade de tabelas, exibições e procedimentos armazenados foram adicionados ao banco de dados

Figura 10: Uma variedade de tabelas, exibições e procedimentos armazenados foram adicionados ao banco de dados (clique para exibir a imagem em tamanho real)

Observação

A aspnet_regsql.exe interface gráfica do usuário da ferramenta instala todo o esquema dos serviços de aplicativo. No entanto, ao executar aspnet_regsql.exe a partir da linha de comando, você pode especificar quais componentes de serviços de aplicativo específicos instalar (ou remover). Portanto, se você quiser adicionar apenas as tabelas, exibições e procedimentos armazenados necessários para os SqlMembershipProvider provedores e SqlRoleProvider , execute aspnet_regsql.exe na linha de comando. Como alternativa, você pode executar manualmente o subconjunto apropriado de scripts de criação de T-SQL usados pelo aspnet_regsql.exe. Esses scripts estão localizados na WINDIR%\Microsoft.Net\Framework\v2.0.50727\ pasta com nomes como InstallCommon.sql, InstallMembership.sql, InstallRoles.sql, InstallProfile.sql, InstallSqlState.sqle assim por diante.

Neste ponto, criamos os objetos de banco de dados necessários para o SqlMembershipProvider. No entanto, ainda precisamos instruir a estrutura de Associação de que ela deve usar o SqlMembershipProvider (versus, digamos, o ActiveDirectoryMembershipProvider) e que o SqlMembershipProvider deve usar o SecurityTutorials banco de dados. Examinaremos como especificar qual provedor usar e como personalizar as configurações do provedor selecionado na Etapa 4. Mas primeiro, vamos dar uma olhada mais profunda nos objetos de banco de dados que acabaram de ser criados.

Etapa 3: Uma olhada nas tabelas principais do esquema

Ao trabalhar com as estruturas Associação e Funções em um aplicativo ASP.NET, os detalhes da implementação são encapsulados pelo provedor. Em tutoriais futuros, vamos fazer a interface com essas estruturas por meio das classes e Roles do Membership .NET Framework. Ao usar essas APIs de alto nível, não precisamos nos preocupar com os detalhes de baixo nível, como quais consultas são executadas ou quais tabelas são modificadas pelo SqlMembershipProvider e SqlRoleProvider.

Considerando isso, poderíamos usar com confiança as estruturas Associação e Funções sem ter explorado o esquema de banco de dados criado na Etapa 2. No entanto, ao criar as tabelas para armazenar dados do aplicativo, talvez seja necessário criar entidades relacionadas a usuários ou funções. Ele ajuda a ter uma familiaridade com os SqlMembershipProvider esquemas e SqlRoleProvider ao estabelecer restrições de chave estrangeira entre as tabelas de dados do aplicativo e as tabelas criadas na Etapa 2. Além disso, em determinadas circunstâncias raras, talvez seja necessário fazer a interface com o usuário e os repositórios de função diretamente no nível do banco de dados (em vez de por meio das Membership classes ou Roles ).

Particionando o repositório de usuários em aplicativos

As estruturas de Associação e Funções foram projetadas para que um único usuário e um repositório de funções possam ser compartilhados entre muitos aplicativos diferentes. Um aplicativo ASP.NET que usa as estruturas Associação ou Funções deve especificar qual partição de aplicativo usar. Em suma, vários aplicativos Web podem usar os mesmos armazenamentos de função e usuário. A Figura 11 ilustra os repositórios de usuários e funções particionados em três aplicativos: HRSite, CustomerSite e SalesSite. Cada um desses três aplicativos Web tem seus próprios usuários e funções exclusivos, mas todos eles armazenam fisicamente suas informações de conta de usuário e função nas mesmas tabelas de banco de dados.

Contas de usuário podem ser particionadas em vários aplicativos

Figura 11: Contas de usuário podem ser particionadas entre vários aplicativos (clique para exibir imagem em tamanho real)

A aspnet_Applications tabela é o que define essas partições. Cada aplicativo que usa o banco de dados para armazenar informações da conta de usuário é representado por uma linha nesta tabela. A aspnet_Applications tabela tem quatro colunas: ApplicationId, ApplicationName, LoweredApplicationNamee Description.ApplicationId é do tipo uniqueidentifier e é a chave primária da tabela; ApplicationName fornece um nome exclusivo e amigável para cada aplicativo.

As outras tabelas relacionadas à associação e à função são vinculadas novamente ao ApplicationId campo em aspnet_Applications. Por exemplo, a aspnet_Users tabela, que contém um registro para cada conta de usuário, tem um ApplicationId campo de chave estrangeira; ditto para a aspnet_Roles tabela. O ApplicationId campo nessas tabelas especifica a partição de aplicativo à qual a conta ou função de usuário pertence.

Armazenando informações da conta de usuário

As informações da conta de usuário são hospedadas em duas tabelas: aspnet_Users e aspnet_Membership. A aspnet_Users tabela contém campos que contêm as informações essenciais da conta de usuário. As três colunas mais pertinentes são:

  • UserId
  • UserName
  • ApplicationId

UserId é a chave primária (e do tipo uniqueidentifier). UserName é do tipo nvarchar(256) e, juntamente com a senha, compõe as credenciais do usuário. (A senha de um usuário é armazenada na aspnet_Membership tabela.) ApplicationId vincula a conta de usuário a um aplicativo específico no aspnet_Applications. Há uma restrição compostaUNIQUE nas UserName colunas e ApplicationId . Isso garante que, em um determinado aplicativo, cada UserName seja exclusivo, mas permite que o mesmo UserName seja usado em aplicativos diferentes.

A aspnet_Membership tabela inclui informações adicionais da conta de usuário, como a senha do usuário, o endereço de email, a data e a hora do último logon e assim por diante. Há uma correspondência um-para-um entre os registros nas aspnet_Users tabelas e aspnet_Membership . Essa relação é assegurada pelo UserId campo em aspnet_Membership, que serve como a chave primária da tabela. Assim como a aspnet_Users tabela, aspnet_Membership inclui um ApplicationId campo que vincula essas informações a uma partição de aplicativo específica.

Protegendo senhas

As informações de senha são armazenadas na aspnet_Membership tabela. O SqlMembershipProvider permite que as senhas sejam armazenadas no banco de dados usando uma das três técnicas a seguir:

  • Clear – a senha é armazenada no banco de dados como texto sem formatação. Eu desestimulei fortemente o uso desta opção. Se o banco de dados for comprometido - seja por um hacker que encontra uma porta dos fundos ou um funcionário descontente que tem acesso ao banco de dados - as credenciais de cada usuário estão lá para a tomada.
  • Hash – as senhas são hash usando um algoritmo de hash unidirecional e um valor de sal gerado aleatoriamente. Esse valor de hash (juntamente com o sal) é armazenado no banco de dados.
  • Criptografado – uma versão criptografada da senha é armazenada no banco de dados.

A técnica de armazenamento de senha usada depende das SqlMembershipProvider configurações especificadas em Web.config. Examinaremos a personalização das SqlMembershipProvider configurações na Etapa 4. O comportamento padrão é armazenar o hash da senha.

As colunas responsáveis por armazenar a senha são Password, PasswordFormate PasswordSalt. PasswordFormat é um campo do tipo int cujo valor indica a técnica usada para armazenar a senha: 0 para Clear; 1 para Hashed; 2 para Encrypted. PasswordSalt é atribuída uma cadeia de caracteres gerada aleatoriamente, independentemente da técnica de armazenamento de senha usada; o valor de PasswordSalt só é usado ao calcular o hash da senha. Por fim, a Password coluna contém os dados de senha reais, seja a senha de texto sem formatação, o hash da senha ou a senha criptografada.

A Tabela 1 ilustra como essas três colunas podem ser para as várias técnicas de armazenamento ao armazenar a senha MySecret! .

Técnica< de armazenamento_o3a_p/> Senha<_o3a_p/> PasswordFormat<_o3a_p/> PasswordSalt<_o3a_p/>
Limpar MySecret! 0 tTnkPlesqissc2y2SMEygA==
Com hash 2oXm6sZHWbTHFgjgkGQsc2Ec9ZM= 1 wFgjUfhdUFOCKQiI61vtiQ==
Criptografado 62RZgDvhxykkqsMchZ0Yly7HS6onhpaoCYaRxV8g0F4CW56OXU3e7Inza9j9BKp 2 LSRzhGS/aa/oqAXGLHJNBw==

Tabela 1: Valores de exemplo para os campos de Password-Related ao armazenar a senha MySecret!

Observação

O algoritmo de criptografia ou hash específico usado pelo SqlMembershipProvider é determinado pelas configurações no <machineKey> elemento .

Armazenando funções e associações de função

A estrutura Funções permite que os desenvolvedores definam um conjunto de funções e especifiquem quais usuários pertencem a quais funções. Essas informações são capturadas no banco de dados por meio de duas tabelas: aspnet_Roles e aspnet_UsersInRoles. Cada registro na aspnet_Roles tabela representa uma função para um aplicativo específico. Assim como a aspnet_Users tabela, a aspnet_Roles tabela tem três colunas pertinentes à nossa discussão:

  • RoleId
  • RoleName
  • ApplicationId

RoleId é a chave primária (e do tipo uniqueidentifier). RoleName é do tipo nvarchar(256). E ApplicationId vincula a conta de usuário a um aplicativo específico no aspnet_Applications. Há uma restrição composta UNIQUE nas RoleName colunas e ApplicationId , garantindo que em um determinado aplicativo cada nome de função seja exclusivo.

A aspnet_UsersInRoles tabela serve como um mapeamento entre usuários e funções. Há apenas duas colunas - UserId e RoleId - e juntas elas compõem uma chave primária composta.

Etapa 4: Especificando o provedor e personalizando suas configurações

Todas as estruturas que dão suporte ao modelo de provedor , como as estruturas Associação e Funções, não têm detalhes de implementação e, em vez disso, delegam essa responsabilidade a uma classe de provedor. No caso da estrutura Associação, a Membership classe define a API para gerenciar contas de usuário, mas não interage diretamente com nenhum repositório de usuários. Em vez disso, os Membership métodos da classe entregam a solicitação para o provedor configurado – usaremos o SqlMembershipProvider. Quando invocamos um dos métodos na Membership classe , como a estrutura De associação sabe delegar a chamada para o SqlMembershipProvider?

A Membership classe tem uma Providers propriedade que contém uma referência a todas as classes de provedor registradas disponíveis para uso pela estrutura De associação. Cada provedor registrado tem um nome e um tipo associados. O nome oferece uma maneira amigável de referenciar um provedor específico na Providers coleção, enquanto o tipo identifica a classe de provedor. Além disso, cada provedor registrado pode incluir definições de configuração. As definições de configuração para a estrutura de associação incluem PasswordFormat e requiresUniqueEmail, entre muitas outras. Consulte a Tabela 2 para obter uma lista completa das definições de configuração usadas pelo SqlMembershipProvider.

O Providers conteúdo da propriedade é especificado por meio das definições de configuração do aplicativo Web. Por padrão, todos os aplicativos Web têm um provedor chamado AspNetSqlMembershipProvider do tipo SqlMembershipProvider. Esse provedor de associação padrão está registrado em (localizado em machine.config%WINDIR%\Microsoft.Net\Framework\v2.0.50727\CONFIG):

<membership> 
 <providers>
 <add name="AspNetSqlMembershipProvider"
 type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" 
 connectionStringName="LocalSqlServer"
 enablePasswordRetrieval="false"
 enablePasswordReset="true"
 requiresQuestionAndAnswer="true"
 applicationName="/"
 requiresUniqueEmail="false"
 passwordFormat="Hashed"
 maxInvalidPasswordAttempts="5"
 minRequiredPasswordLength="7"
 minRequiredNonalphanumericCharacters="1"
 passwordAttemptWindow="10"
 passwordStrengthRegularExpression=""/>
 </providers> 
</membership>

Como mostra a marcação acima, o <membership> elemento define as definições de configuração para a estrutura Membership enquanto o <providers> elemento filho especifica os provedores registrados. Os provedores podem ser adicionados ou removidos usando os <add> elementos ou <remove> ; use o <clear> elemento para remover todos os provedores registrados no momento. Como mostra a marcação acima, machine.config adiciona um provedor chamado AspNetSqlMembershipProvider do tipo SqlMembershipProvider.

Além dos name atributos e type , o <add> elemento contém atributos que definem os valores para várias configurações de configuração. A Tabela 2 lista as definições de configuração específicas disponíveis SqlMembershipProvider, juntamente com uma descrição de cada uma.

Observação

Todos os valores padrão anotados na Tabela 2 referem-se aos valores padrão definidos na SqlMembershipProvider classe . Observe que nem todas as definições de configuração em AspNetSqlMembershipProvider correspondem aos valores padrão da SqlMembershipProvider classe . Por exemplo, se não for especificado em um provedor de associação, a requiresUniqueEmail configuração usará como padrão true. No entanto, o AspNetSqlMembershipProvider substitui esse valor padrão especificando explicitamente um valor de false.

Configuração<_o3a_p /> Descrição<_o3a_p/>
ApplicationName Lembre-se de que a estrutura associação permite que um único repositório de usuários seja particionado em vários aplicativos. Essa configuração indica o nome da partição de aplicativo usada pelo provedor de associação. Se esse valor não for especificado explicitamente, ele será definido, em runtime, como o valor do caminho raiz virtual do aplicativo.
commandTimeout Especifica o valor de tempo limite do comando SQL (em segundos). O valor padrão é 30.
connectionStringName O nome do cadeia de conexão no <connectionStrings> elemento a ser usado para se conectar ao banco de dados do repositório de usuários. Esse valor é necessário.
description Fornece uma descrição amigável do provedor registrado.
enablePasswordRetrieval Especifica se os usuários podem recuperar sua senha esquecida. O valor padrão é false.
enablePasswordReset Indica se os usuários têm permissão para redefinir a senha. Assume o padrão de true.
maxInvalidPasswordAttempts O número máximo de tentativas de logon malsucedidas que podem ocorrer para um determinado usuário durante o especificado passwordAttemptWindow antes que o usuário seja bloqueado. O valor padrão é 5.
minRequiredNonalphanumericCharacters O número mínimo de caracteres não alfanuméricos que devem aparecer na senha de um usuário. Esse valor deve estar entre 0 e 128; o padrão é 1.
minRequiredPasswordLength O número mínimo de caracteres necessários em uma senha. Esse valor deve estar entre 0 e 128; o padrão é 7.
name O nome do provedor registrado. Esse valor é necessário.
passwordAttemptWindow O número de minutos durante os quais as tentativas de logon com falha são rastreadas. Se um usuário fornecer tempos de credenciais maxInvalidPasswordAttempts de logon inválidos nessa janela especificada, ele será bloqueado. O valor padrão é 10.
PasswordFormat O formato de armazenamento de senha: Clear, Hashedou Encrypted. O padrão é Hashed.
passwordStrengthRegularExpression Se fornecida, essa expressão regular será usada para avaliar a força da senha selecionada do usuário ao criar uma nova conta ou ao alterar sua senha. O valor padrão é uma cadeia de caracteres vazia.
requiresQuestionAndAnswer Especifica se um usuário deve responder a sua pergunta de segurança ao recuperar ou redefinir sua senha. O valor padrão é true.
requiresUniqueEmail Indica se todas as contas de usuário em uma determinada partição de aplicativo devem ter um endereço de email exclusivo. O valor padrão é true.
type Especifica o tipo do provedor. Esse valor é necessário.

Tabela 2: Configurações de Associação e SqlMembershipProvider Configuração

Além do AspNetSqlMembershipProvider, outros provedores de associação podem ser registrados por aplicativo adicionando marcação semelhante ao Web.config arquivo.

Observação

A estrutura Funções funciona da mesma maneira: há um provedor de função registrado padrão no machine.config e os provedores registrados podem ser personalizados por aplicativo em Web.config. Examinaremos a estrutura Funções e sua marcação de configuração em detalhes em um tutorial futuro.

Personalizando asSqlMembershipProviderConfigurações

O padrão SqlMembershipProvider () tem seu connectionStringName atributo definido como LocalSqlServerAspNetSqlMembershipProvider. Assim como o AspNetSqlMembershipProvider provedor, o nome LocalSqlServer cadeia de conexão é definido em machine.config.

<connectionStrings> 
 <add name="LocalSqlServer" 
 connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" 
 providerName="System.Data.SqlClient"/> 
</connectionStrings>

Como você pode ver, esse cadeia de conexão define um banco de dados do SQL 2005 Express Edition localizado em |DataDirectory|aspnetdb.mdf. A cadeia de caracteres |DataDirectory| é convertido em runtime para apontar para o ~/App_Data/ diretório, portanto, o caminho do banco de dados |DataDirectory|aspnetdb.mdf é convertido ~/App_Data/aspnet.mdfem .

Se não especificarmos nenhuma informação do provedor de associação no arquivo do Web.config aplicativo, o aplicativo usará o provedor de Associação registrado padrão, AspNetSqlMembershipProvider. Se o ~/App_Data/aspnet.mdf banco de dados não existir, o runtime do ASP.NET o criará automaticamente e adicionará o esquema dos serviços de aplicativo. No entanto, não queremos usar o aspnet.mdf banco de dados; em vez disso, queremos usar o SecurityTutorials.mdf banco de dados que criamos na Etapa 2. Essa modificação pode ser realizada de duas maneiras:

  • Especificar um valor para oLocalSqlServercadeia de conexão nome.Web.config Ao substituir o valor do LocalSqlServer nome cadeia de conexão no Web.config, podemos usar o provedor de Associação registrado padrão (AspNetSqlMembershipProvider) e fazer com que ele funcione corretamente com o SecurityTutorials.mdf banco de dados. Essa abordagem será boa se você estiver satisfeito com as configurações especificadas por AspNetSqlMembershipProvider. Para obter mais informações sobre essa técnica, consulte a postagem no blog de Scott Guthrie, Configurando ASP.NET 2.0 Application Services para usar SQL Server 2000 ou SQL Server 2005.
  • Adicionar um novo provedor registrado do tipoSqlMembershipProvidere configurar seuconnectionStringNameconfiguração para apontar para oSecurityTutorials.mdfDatabase. Essa abordagem é útil em cenários em que você deseja personalizar outras propriedades de configuração além do banco de dados cadeia de conexão. Em meus próprios projetos, sempre uso essa abordagem devido à sua flexibilidade e legibilidade.

Antes de adicionarmos um novo provedor registrado que referencie o SecurityTutorials.mdf banco de dados, primeiro precisamos adicionar um valor de cadeia de conexão apropriado na <connectionStrings> seção em Web.config. A marcação a seguir adiciona um novo cadeia de conexão chamado SecurityTutorialsConnectionString que faz referência ao banco de dados SQL Server 2005 Express Edition SecurityTutorials.mdf na App_Data pasta.

<configuration>
 <connectionStrings>
 <add name="SecurityTutorialsConnectionString" 
 connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\SecurityTutorials.mdf;Integrated Security=True;User Instance=True" 
 providerName="System.Data.SqlClient"/>
 </connectionStrings> 
 <system.web>
 ... Configuration markup removed for brevity ...  </system.web>
</configuration>

Observação

Se você estiver usando um arquivo de banco de dados alternativo, atualize o cadeia de conexão conforme necessário. Para obter mais informações sobre como formar o cadeia de conexão correto, consulte ConnectionStrings.com.

Em seguida, adicione a seguinte marcação de configuração de associação ao Web.config arquivo. Essa marcação registra um novo provedor chamado SecurityTutorialsSqlMembershipProvider.

<configuration>
 <connectionStrings>
 <add name="SecurityTutorialsConnectionString" 
 connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\SecurityTutorials.mdf;Integrated Security=True;User Instance=True" 
 providerName="System.Data.SqlClient"/>
 </connectionStrings> 
 <system.web>
 <membership defaultProvider="SecurityTutorialsSqlMembershipProvider">
 <providers>
 <!-- Add a customized SqlMembershipProvider --> 
 <add name="SecurityTutorialsSqlMembershipProvider" 
 type="System.Web.Security.SqlMembershipProvider"
 connectionStringName="SecurityTutorialsConnectionString"
 enablePasswordRetrieval="false"
 enablePasswordReset="true"
 requiresQuestionAndAnswer="true"
 applicationName="SecurityTutorials"
 requiresUniqueEmail="true"
 passwordFormat="Hashed"
 maxInvalidPasswordAttempts="5"
 minRequiredPasswordLength="7"
 minRequiredNonalphanumericCharacters="1"
 passwordAttemptWindow="10"
 passwordStrengthRegularExpression=""/>
 </providers>
 </membership>
 ... Configuration markup removed for brevity ... 
 </system.web>
</configuration>

Além de registrar o SecurityTutorialsSqlMembershipProvider provedor, a marcação acima define o SecurityTutorialsSqlMembershipProvider como o provedor padrão (por meio do defaultProvider atributo no <membership> elemento ). Lembre-se de que a estrutura associação pode ter vários provedores registrados. Como AspNetSqlMembershipProvider é registrado como o primeiro provedor no machine.config, ele serve como o provedor padrão, a menos que indiquemos o contrário.

Atualmente, nosso aplicativo tem dois provedores registrados: AspNetSqlMembershipProvider e SecurityTutorialsSqlMembershipProvider. No entanto, antes de registrar o SecurityTutorialsSqlMembershipProvider provedor, poderíamos ter limpado todos os provedores registrados anteriormente adicionando um <clear /> elemento imediatamente antes de nosso <add> elemento. Isso limparia o AspNetSqlMembershipProvider da lista de provedores registrados, o que significa que o SecurityTutorialsSqlMembershipProvider seria o único provedor de Associação registrado. Se usarmos essa abordagem, não precisaríamos marcar o SecurityTutorialsSqlMembershipProvider como o provedor padrão, pois ele seria o único provedor de Associação registrado. Para obter mais informações sobre como usar <clear />, consulte Usando <clear /> ao adicionar provedores.

Observe que a SecurityTutorialsSqlMembershipProviderconfiguração do connectionStringName faz referência ao nome de cadeia de conexão adicionado recentemente SecurityTutorialsConnectionString e que sua applicationName configuração foi definida como um valor de SecurityTutorials. Além disso, a requiresUniqueEmail configuração foi definida truecomo . Todas as outras opções de configuração são idênticas aos valores em AspNetSqlMembershipProvider. Fique à vontade para fazer modificações de configuração aqui, se desejar. Por exemplo, você pode apertar a força da senha exigindo dois caracteres não alfanuméricos em vez de um ou aumentando o comprimento da senha para oito caracteres em vez de sete.

Observação

Lembre-se de que a estrutura Associação permite que um único repositório de usuários seja particionado em vários aplicativos. A configuração do provedor de applicationName associação indica qual aplicativo o provedor usa ao trabalhar com o repositório de usuários. É importante que você defina explicitamente um valor para a applicationName configuração porque, se o applicationName não estiver definido explicitamente, ele será atribuído ao caminho raiz virtual do aplicativo Web em runtime. Isso funciona bem desde que o caminho raiz virtual do aplicativo não seja alterado, mas se você mover o aplicativo para um caminho diferente, a applicationName configuração também será alterada. Quando isso acontecer, o provedor de associação começará a trabalhar com uma partição de aplicativo diferente do que foi usado anteriormente. As contas de usuário criadas antes da movimentação residirão em uma partição de aplicativo diferente e esses usuários não poderão mais fazer logon no site. Para obter uma discussão mais detalhada sobre esse assunto, consulte Sempre definir a applicationName propriedade ao configurar ASP.NET associação 2.0 e outros provedores.

Resumo

Neste ponto, temos um banco de dados com os serviços de aplicativos configurados (SecurityTutorials.mdf) e configuramos nosso aplicativo Web para que a estrutura associação use o SecurityTutorialsSqlMembershipProvider provedor que acabamos de registrar. Esse provedor registrado é do tipo SqlMembershipProvider e tem seu connectionStringName conjunto como o cadeia de conexão apropriado (SecurityTutorialsConnectionString) e seu applicationName valor definido explicitamente.

Agora estamos prontos para usar a estrutura De associação de nosso aplicativo. No próximo tutorial, examinaremos como criar novas contas de usuário. A seguir, exploraremos a autenticação de usuários, a execução da autorização baseada no usuário e o armazenamento de informações adicionais relacionadas ao usuário no banco de dados.

Programação feliz!

Leitura Adicional

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

Treinamento em vídeo sobre tópicos contidos neste Tutorial

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. O revisor principal deste tutorial foi Alicja Maziarz. Interessado em revisar meus próximos artigos do MSDN? Nesse caso, solte-me uma linha em mitchell@4GuysFromRolla.com.