Compartilhar via


Criando o esquema de associação no SQL Server (C#)

por Scott Mitchell

Nota

Desde que este artigo foi escrito, os provedores de associação de 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 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 examinaram o uso da autenticação de formulários para identificar 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 classe FormsAuthentication 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 e um objeto 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 funcionalidade 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 eram responsáveis por implementar todas essas tarefas relacionadas a contas de usuário. Felizmente, a equipe de ASP.NET reconheceu essa deficiência e introduziu a estrutura de associação com ASP.NET 2.0. A estrutura de 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 em cima do modelo de provedor , que permite aos desenvolvedores conectar 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 vem 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 da loja de usuários tenha determinadas tabelas, visõ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

Os dados de um aplicativo ASP.NET são geralmente armazenados em várias tabelas em um banco de dados. Ao implementar o esquema de banco de dados SqlMembershipProvider, devemos decidir se o esquema de associação deve ser colocado no mesmo banco de dados que contém 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 ' 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 ' ao localizar as tabelas relacionadas à associação no mesmo banco de dados que as tabelas de aplicação, é possível estabelecer restrições de chave estrangeira entre as chaves primárias nas tabelas relacionadas à associação e as tabelas de aplicação relacionadas.

Desassociar os dados do armazenamento de usuário e do aplicativo em bancos de dados separados só fará sentido se você tiver vários aplicativos que usam bancos de dados separados, mas precisar compartilhar um repositório de usuários comum.

Criando 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 provedor de SqlMembershipProvider (consulte a Etapa 2).

Nota

Ao longo desta série de tutoriais, usaremos um banco de dados Microsoft SQL Server 2005 Express Edition para armazenar nossas tabelas de aplicativos e o esquema SqlMembershipProvider. Essa decisão foi tomada por dois motivos: primeiro, devido ao seu custo – gratuito – a Express Edition é a versão mais legível e acessível do SQL Server 2005; segundo, os bancos de dados do SQL Server 2005 Express Edition podem ser colocados diretamente na pasta App_Data do aplicativo Web, tornando-se 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 do SQL Server, fique à vontade. As etapas são praticamente idênticas. O esquema SqlMembershipProvider funcionará com qualquer versão do Microsoft SQL Server 2000 ou posterior.

No Gerenciador de Soluções, clique com o botão direito do mouse na pasta App_Data e escolha Adicionar Novo Item. (Se você não vir uma pasta App_Data em seu projeto, clique com o botão direito do mouse no projeto no 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 esquema SqlMembershipProvider a este banco de dados; nos tutoriais subsequentes, criaremos tabelas adicionais para capturar nossos dados do aplicativo.

Adicionar um novo banco de dados SQL chamado SecurityTutorials.mdf à pasta App_Data

Figura 1: Adicionar um Novo Banco de Dados SQL chamado SecurityTutorials.mdf à Pasta App_Data (Clique para exibir imagem em tamanho real)

Adicionar um banco de dados à pasta App_Data o inclui automaticamente na exibição do Gerenciador de Banco de Dados. (Na versão não Express Edition do Visual Studio, o Gerenciador de Banco de Dados é chamado de Gerenciador de Servidores.) Vá para o Gerenciador de Banco de Dados e expanda o banco de dados de SecurityTutorials adicionado. Se você não vir o Gerenciador de Banco de Dados na tela, vá para o menu Exibir e escolha o Gerenciador de Banco de Dados ou clique em Ctrl+Alt+S. Como mostra a Figura 2, o banco de dados SecurityTutorials 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 banco de dados SecurityTutorials está vazio no momento (Clique para exibir a imagem em tamanho real)

Etapa 2: Adicionar o esquema deSqlMembershipProviderao banco de dados

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

Nota

A ferramenta aspnet_regsql.exe 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 adição do esquema SqlMembershipProvider precisa ser automatizada, como em scripts de build ou cenários de teste automatizados.

A ferramenta aspnet_regsql.exe é usada para adicionar ou remover ASP.NET serviços de aplicativo a um banco de dados do SQL Server especificado. Os serviços de aplicação ASP.NET incluem os esquemas para o SqlMembershipProvider e SqlRoleProvider, além dos esquemas para os provedores baseados em SQL para outros frameworks do ASP.NET 2.0. Precisamos fornecer dois bits de informações para a ferramenta aspnet_regsql.exe:

  • Se queremos adicionar ou remover serviços de aplicativo e
  • O banco de dados do qual adicionar ou remover o esquema de serviços de aplicativo

Ao solicitar o uso do banco de dados, a ferramenta aspnet_regsql.exe 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 Express do SQL Server, já deverá saber essas informações, pois são as mesmas informações que você deve fornecer por meio de uma cadeia de conexão ao trabalhar com o banco de dados por meio de uma página da Web ASP.NET. Determinar o nome do servidor e do banco de dados ao usar um banco de dados do SQL Server 2005 Express Edition na pasta App_Data, no entanto, é 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 do SQL Server 2005 Express Edition na pasta App_Data. Se você não estiver usando o 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 do SQL Server 2005 Express Edition na pastaApp_Data

Para usar a ferramenta aspnet_regsql.exe, 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 o 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. Os bancos de dados na pasta App_Data normalmente têm um nome de banco de dados que inclui um identificador globalmente exclusivo junto 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 de aspnet_regsql.exe.

A maneira mais fácil de verificar o nome do banco de dados é examiná-lo por meio do SQL Server Management Studio. O SQL Server Management Studio fornece uma interface gráfica para gerenciar bancos de dados do 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 do SQL Server Management Studio.

Nota

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 será 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 o SQL Server Management Studio e conecte-se ao banco de dados localhost\InstanceName do 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 do SQL Server 2005 Express Edition

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

Depois de se conectar à instância do 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 é 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 banco de dados SecurityTutorials.mdf e clique em OK. A Figura 4 mostra a caixa de diálogo Anexar Bancos de Dados após a seleção do banco de dados SecurityTutorials.mdf. A Figura 5 mostra o Pesquisador de Objetos do Management Studio depois que o banco de dados foi anexado com êxito.

Anexe o banco de dados SecurityTutorials.mdf

Figura 4: Anexar o Banco de Dados SecurityTutorials.mdf (Clique para exibir imagem em tamanho real)

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

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

Como mostra a Figura 5, o banco de dados SecurityTutorials.mdf 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 no 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 de servidor e banco de dados do arquivo de banco de dados SecurityTutorials.mdf: localhost\InstanceName e SecurityTutorialsDatabase, respectivamente. Agora estamos prontos para instalar os serviços de aplicativo por meio da ferramenta aspnet_regsql.exe.

Instalando os Serviços de Aplicativo

Para iniciar a ferramenta aspnet_regsql.exe, 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 na pasta apropriada e clicar duas vezes no arquivo aspnet_regsql.exe. Qualquer abordagem obterá os mesmos resultados.

A execução da ferramenta aspnet_regsql.exe sem parâmetros de linha de comando inicia a interface gráfica do assistente de instalação do SQL Server para ASP.NET. O assistente facilita a adição ou 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 Configuração do SQL Server do ASP.NET para Adicionar o Esquema de Associação

Figura 7: use o Assistente de Instalação do SQL Server do ASP.NET 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 o SQL Server para serviços de aplicativo. Posteriormente, se você quiser remover este esquema do banco de dados, execute novamente este assistente, mas escolha a opção Remover informações de serviços de aplicativo de um banco de dados existente.

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

Figura 8: escolha a opção Configurar o SQL Server para Serviços de Aplicativo (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 banco de dados SecurityTutorials.mdf a App_Data, anexado a localhost\InstanceNamee renomeado para 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 visualizar 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, em Concluir para terminar o assistente.

Nota

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 banco de dados SecurityTutorialsDatabase, 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 Gerenciador de Banco de Dados. 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.

várias tabelas, exibições e procedimentos armazenados foram adicionados ao banco de dados

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

Nota

A interface gráfica do usuário da ferramenta aspnet_regsql.exe instala todo o esquema de serviços de aplicativo. No entanto, ao executar aspnet_regsql.exe da linha de comando, você pode especificar quais componentes específicos dos serviços de aplicativo instalar (ou remover). Portanto, se você quiser adicionar apenas as tabelas, exibições e procedimentos armazenados necessários para os provedores de SqlMembershipProvider 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 pasta WINDIR%\Microsoft.Net\Framework\v2.0.50727\ 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 Associação de que ela deve usar o SqlMembershipProvider (versus, digamos, o ActiveDirectoryMembershipProvider) e que o SqlMembershipProvider deve usar o banco de dados SecurityTutorials. 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 implantação são encapsulados pelo provedor. Em tutoriais futuros, nos adaptaremos a essas estruturas por meio das classes Membership e Roles do .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 esquemas SqlMembershipProvider 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ções diretamente no nível do banco de dados (em vez de por meio das classes Membership ou Roles).

Particionando o Repositório de Usuários em aplicativos

As estruturas de Associação e Funções são projetadas de forma que um único repositório de usuários e funções possa ser compartilhado entre vários 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 o mesmo usuário e repositórios de funções. A Figura 11 ilustra os repositórios de função e de usuário particionados em três aplicativos: HRSite, CustomerSite e SalesSite. Esses três aplicativos Web têm seus próprios usuários e funções exclusivos, mas todos 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 divididas em várias aplicações (clique para ver a imagem em tamanho real)

A tabela aspnet_Applications é 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 tabela aspnet_Applications 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 humanos para cada aplicação.

As outras tabelas relacionadas à Associação e à Função são vinculadas novamente ao campo ApplicationId em aspnet_Applications. Por exemplo, a tabela aspnet_Users, que contém um registro para cada conta de usuário, tem um campo de chave estrangeira ApplicationId; ditto para a tabela aspnet_Roles. O campo ApplicationId nessas tabelas especifica a partição do 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 estão alojadas em duas tabelas: aspnet_Users e aspnet_Membership. A tabela aspnet_Users 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 tabela aspnet_Membership.) ApplicationId vincula a conta de usuário a um aplicativo específico em aspnet_Applications. Há uma restrição composta UNIQUE nas colunas UserName 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 tabela aspnet_Membership inclui informações adicionais da conta de usuário, como a senha do usuário, o endereço de email, a última data e hora de logon e assim por diante. Há uma correspondência um-para-um entre registros nas tabelas aspnet_Users e aspnet_Membership. Essa relação é assegurada pelo campo UserId em aspnet_Membership, que serve como a chave primária da tabela. Assim como a tabela aspnet_Users, aspnet_Membership inclui um campo ApplicationId que vincula essas informações a uma partição de aplicativo específica.

Protegendo senhas

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

  • Limpar – a senha é armazenada no banco de dados como texto sem formatação. Eu desaconselho fortemente o uso desta opção. Se o banco de dados estiver comprometido - seja por um hacker que encontre uma brecha de segurança ou um funcionário descontente que tenha acesso ao banco de dados - as credenciais de cada usuário estão prontas para serem roubadas.
  • Com Hash: as senhas são transformadas em 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 configurações de SqlMembershipProvider especificadas em Web.config. Examinaremos a personalização das configurações de SqlMembershipProvider 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 recebe 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 coluna Password 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 a aparência dessas três colunas 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 />
Clear MySecret! 0 tTnkPlesqissc2y2SMEygA==
Com hash 2oXm6sZHWbTHFgjgkGQsc2Ec9ZM= 1 wFgjUfhdUFOCKQiI61vtiQ==
Criptografado 62RZgDvhxykkqsMchZ0Yly7HS6onhpaoCYaRxV8g0F4CW56OXUU3e7Inza9j9BKp 2 LSRzhGS/aa/oqAXGLHJNBw==

Tabela 1: Valores de Exemplo para os Campos Password-Related ao Armazenar a Senha MySecret!

Nota

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

Armazenamento de funções e associações de funções

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 tabela aspnet_Roles representa uma função para um aplicativo específico. Assim como a tabela aspnet_Users, a tabela aspnet_Roles 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 em aspnet_Applications. Há uma restrição composta de UNIQUE nas colunas RoleName e ApplicationId, garantindo que, em uma determinada aplicação, cada nome de função seja exclusivo.

A tabela aspnet_UsersInRoles 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 de associação, a classe Membership 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 métodos da classe Membership entregam a solicitação para o provedor configurado – usaremos o SqlMembershipProvider. Quando invocamos um dos métodos na classe Membership, como a estrutura de associação sabe delegar a chamada ao SqlMembershipProvider?

A classe Membership tem uma propriedade Providers 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 coleção Providers, enquanto o tipo identifica a classe de provedor. Além disso, cada provedor registrado pode incluir configurações. As configurações para a estrutura Associação incluem passwordFormat e requiresUniqueEmail, entre muitos outras. Consulte a Tabela 2 para obter uma lista completa das configurações usadas pelo SqlMembershipProvider.

O conteúdo da propriedade Providers é especificado por meio das configurações 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 é registrado em machine.config (localizado em %WINDIR%\Microsoft.Net\Framework\v2.0.50727\CONFIG):

Aviso

Parece que o exemplo que você está procurando se moveu! Tenha certeza de que estamos trabalhando para resolver isso.

Como mostra a marcação acima, o elemento <membership> define as configurações da estrutura de Associação enquanto o elemento filho <providers> especifica os provedores registrados. Os provedores podem ser adicionados ou removidos usando os elementos <add> ou <remove>; use o elemento <clear> 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 atributos name e type, o elemento <add> contém atributos que definem os valores para várias configurações de configuração. A Tabela 2 lista as configurações SqlMembershipProviderespecíficas disponíveis, juntamente com uma descrição de cada uma.

Nota

Todos os valores padrão observados na Tabela 2 referem-se aos valores padrão definidos na classe SqlMembershipProvider. Observe que nem todas as configurações em AspNetSqlMembershipProvider correspondem aos valores padrão da classe SqlMembershipProvider. Por exemplo, se não for especificado em um provedor de Associação, a configuração requiresUniqueEmail tem 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 de associação permite que um único repositório de usuários seja dividido entre 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 do tempo limite do comando SQL (em segundos). O valor padrão é 30.
connectionStringName O nome da cadeia de conexão no elemento <connectionStrings> 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 a 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 passwordAttemptWindow especificado 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 login com falha são rastreadas. Se um usuário fornecer credenciais de logon inválidas maxInvalidPasswordAttempts vezes 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 a 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: associação e SqlMembershipProvider definições de configuração

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

Nota

A estrutura de 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 de funções e sua marcação de configuração em detalhes em um tutorial futuro.

Personalizando as configurações deSqlMembershipProvider

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

Aviso

Parece que o exemplo que você está procurando se moveu! Tenha certeza de que estamos trabalhando para resolver isso.

Como você pode ver, essa cadeia de conexão define um banco de dados do SQL 2005 Express Edition localizado em |DataDirectory|aspnetdb.mdf'. A cadeia de caracteres |DataDirectory| é traduzida em tempo de execução para apontar para o diretório ~/App_Data/, portanto, o caminho do banco de dados "|DataDirectory|aspnetdb.mdf" se converte em ~/App_Data/aspnet.mdf.

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

  • Especifique um valor para o LocalSqlServernome da cadeia de conexão noWeb.config. Ao substituir o valor do nome da cadeia de conexão LocalSqlServer em Web.config, podemos usar o provedor de associação padrão registrado (AspNetSqlMembershipProvider) e fazê-lo funcionar corretamente com o banco de dados SecurityTutorials.mdf. Essa abordagem é boa se você estiver satisfeito com as configurações especificadas por AspNetSqlMembershipProvider. Para obter mais informações sobre essa técnica, consulte a publicação no blog de Scott Guthrie, Configuração do ASP.NET 2.0 Application Services para usar o SQL Server 2000 ou o SQL Server 2005.
  • Adicionar um novo provedor registrado do tipoSqlMembershipProvidere definir sua configuração deconnectionStringNamepara apontar para o banco de dadosSecurityTutorials.mdf. Essa abordagem é útil em cenários em que você deseja personalizar outras propriedades de configuração além da cadeia de conexão de banco de dados. Em meus próprios projetos, sempre uso essa abordagem devido à sua flexibilidade e legibilidade.

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

Aviso

Parece que o exemplo que você está procurando se moveu! Tenha certeza de que estamos trabalhando para resolver isso.

Nota

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

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

Aviso

Parece que o exemplo que você está procurando se moveu! Tenha certeza de que estamos trabalhando para resolver isso.

Além de registrar o provedor de SecurityTutorialsSqlMembershipProvider, a marcação acima define o SecurityTutorialsSqlMembershipProvider como o provedor padrão (por meio do atributo defaultProvider no elemento <membership>). Lembre-se de que a estrutura Associação pode ter vários provedores registrados. Como AspNetSqlMembershipProvider é registrado como o primeiro provedor em 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 provedor de SecurityTutorialsSqlMembershipProvider, poderíamos ter removido todos os provedores registrados anteriormente ao adicionar um elemento <clear /> diretamente antes do nosso elemento <add>. 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 Usar <clear /> ao adicionar provedores.

Observe que a configuração SecurityTutorialsSqlMembershipProviderdo connectionStringName faz referência ao nome da cadeia de conexão SecurityTutorialsConnectionString recém-adicionada e que sua configuração applicationName foi definida como um valor de SecurityTutorials. Além disso, a configuração de requiresUniqueEmail foi definida como true. Todas as outras opções de configuração são idênticas aos valores em AspNetSqlMembershipProvider. Fique à vontade para fazer as 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 tamanho da senha para oito caracteres em vez de sete.

Nota

Lembre-se de que a estrutura de Associação permite que um único armazenamento de usuário seja particionado em vários aplicativos. A configuração applicationName do Membership provider indica qual aplicativo o provedor utiliza ao lidar com o banco de dados de usuários. É importante definir explicitamente um valor para a configuração de applicationName 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 configuração de applicationName também será alterada. Quando isso acontecer, o provedor de associação começará a trabalhar com uma partição de aplicativo diferente da usada anteriormente. As contas de usuário criadas antes da mudança 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 este assunto, consulte Sempre defina a propriedade applicationName ao configurar a Associação do ASP.NET 2.0 e outros provedores.

Resumo

Neste ponto, temos um banco de dados com os serviços de aplicativo configurados (SecurityTutorials.mdf) e configuramos nosso aplicativo Web para que a estrutura de Associação use o provedor de SecurityTutorialsSqlMembershipProvider que acabamos de registrar. Esse provedor registrado é do tipo SqlMembershipProvider e tem sua connectionStringName definida como a cadeia de conexão apropriada (SecurityTutorialsConnectionString) e seu valor applicationName 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. Depois disso, 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.

Feliz programação!

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 no http://ScottOnWriting.NET.

Agradecimentos Especiais a

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, me mande uma mensagem em mitchell@4GuysFromRolla.com.