Noções básicas sobre segurança e suporte do ASP.NET (C#)
por Scott Mitchell
Observação
Desde que este artigo foi escrito, os provedores de associação ASP.NET foram substituídos pelo ASP.NET Identity. É altamente recomendável atualizar 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 sobre o sistema de associação ASP.NET, incluindo:
- Melhor desempenho
- Extensibilidade e capacidade de teste aprimoradas
- Suporte para OAuth, OpenID Connect e autenticação de dois fatores
- Suporte à identidade baseada em declarações
- Melhor interoperabilidade com ASP.Net Core
Este é o primeiro tutorial de uma série de tutoriais que explorarão técnicas para autenticar visitantes por meio de um formulário da Web, autorizar o acesso a páginas e funcionalidades específicas e gerenciar contas de usuário em um aplicativo ASP.NET.
Introdução
Qual é a única coisa que fóruns, sites de comércio eletrônico, sites de e-mail online, sites de portais e sites de redes sociais têm em comum? Todos eles oferecem contas de usuário. Os sites que oferecem contas de usuário devem fornecer vários serviços. No mínimo, os novos visitantes precisam ser capazes de criar uma conta e os visitantes recorrentes devem ser capazes de fazer login. Esses aplicativos da Web podem tomar decisões com base no usuário conectado: algumas páginas ou ações podem ser restritas apenas a usuários logados ou a um determinado subconjunto de usuários; Outras páginas podem mostrar informações específicas do usuário conectado ou podem mostrar mais ou menos informações, dependendo de qual usuário está visualizando a página.
Este é o primeiro tutorial de uma série de tutoriais que explorarão técnicas para autenticar visitantes por meio de um formulário da Web, autorizar o acesso a páginas e funcionalidades específicas e gerenciar contas de usuário em um aplicativo ASP.NET. Ao longo desses tutoriais, examinaremos como:
- Identificar e fazer login de usuários em um site
- Use ASP. NET para gerenciar contas de usuário
- Criar, atualizar e excluir contas de usuário
- Limitar o acesso a uma página da web, diretório ou funcionalidade específica com base no usuário conectado
- Use ASP. NET para associar contas de usuário a funções
- Gerenciar funções de usuário
- Limitar o acesso a uma página da Web, diretório ou funcionalidade específica com base na função do usuário conectado
- Personalize e estenda o ASP. NET
Esses tutoriais são voltados para serem concisos e fornecem instruções passo a passo com muitas capturas de tela para orientá-lo visualmente no processo. Cada tutorial está disponível nas versões C# e Visual Basic e inclui um download do código completo usado. (Este primeiro tutorial se concentra em conceitos de segurança de um ponto de vista de alto nível e, portanto, não contém nenhum código associado.)
Neste tutorial, discutiremos conceitos de segurança importantes e quais recursos estão disponíveis no ASP.NET para ajudar na implementação de autenticação de formulários, autorização, contas de usuário e funções. Vamos começar!
Observação
A segurança é um aspecto importante de qualquer aplicativo que abrange decisões físicas, tecnológicas e de política e requer um alto grau de planejamento e conhecimento de domínio. Esta série de tutoriais não se destina a ser um guia para o desenvolvimento de aplicativos Web seguros. Em vez disso, ele se concentra especificamente na autenticação, autorização, contas de usuário e funções de formulários. Embora alguns conceitos de segurança que giram em torno dessas questões sejam discutidos nesta série, outros são deixados inexplorados.
Autenticação, autorização, contas de usuário e funções
Autenticação, autorização, contas de usuário e funções são quatro termos que serão usados com muita frequência ao longo desta série de tutoriais, portanto, gostaria de dedicar um momento rápido para definir esses termos no contexto da segurança da Web. Em um modelo cliente-servidor, como a Internet, há muitos cenários em que o servidor precisa identificar o cliente que está fazendo a solicitação. A autenticação é o processo de verificar a identidade do cliente. Diz-se que um cliente que foi identificado com sucesso é autenticado. Um cliente não identificado é considerado não autenticado ou anônimo.
Os sistemas de autenticação segura envolvem pelo menos uma das três facetas a seguir: algo que você sabe, algo que você tem ou algo que você é. A maioria dos aplicativos da Web depende de algo que o cliente sabe, como uma senha ou um PIN. As informações usadas para identificar um usuário - seu nome de usuário e senha, por exemplo - são chamadas de credenciais. Esta série de tutoriais se concentra na autenticação de formulários, que é um modelo de autenticação em que os usuários fazem logon no site fornecendo suas credenciais em um formulário de página da Web. Todos nós já experimentamos esse tipo de autenticação antes. Vá para qualquer site de comércio eletrônico. Quando estiver pronto para finalizar a compra, você será solicitado a fazer login digitando seu nome de usuário e senha em caixas de texto em uma página da web.
Além de identificar clientes, um servidor pode precisar limitar quais recursos ou funcionalidades estão acessíveis, dependendo do cliente que faz a solicitação. Autorização é o processo de determinar se um determinado usuário tem autoridade para acessar um recurso ou funcionalidade específica.
Uma conta de usuário é um repositório para informações persistentes sobre um usuário específico. As contas de usuário devem incluir minimamente informações que identifiquem exclusivamente o usuário, como o nome de login e a senha do usuário. Junto com essas informações essenciais, as contas de usuário podem incluir coisas como: o endereço de e-mail do usuário; a data e a hora em que a conta foi criada; a data e hora em que fizeram login pela última vez; nome e sobrenome; número de telefone; e endereço para correspondência. Ao usar a autenticação de formulários, as informações da conta do usuário normalmente são armazenadas em um banco de dados relacional, como o Microsoft SQL Server.
Os aplicativos Web que dão suporte a contas de usuário podem, opcionalmente, agrupar usuários em funções. Uma função é simplesmente um rótulo aplicado a um usuário e fornece uma abstração para definir regras de autorização e funcionalidade no nível da página. Por exemplo, um site pode incluir uma função de Administrador com regras de autorização que proíbem qualquer pessoa, exceto um Administrador, de acessar um determinado conjunto de páginas da Web. Além disso, uma variedade de páginas acessíveis a todos os usuários (incluindo não administradores) pode exibir dados adicionais ou oferecer funcionalidade extra quando visitada por usuários na função Administradores. Usando funções, podemos definir essas regras de autorização função por função, em vez de usuário por usuário.
Autenticando usuários em um aplicativo ASP.NET
Quando um usuário insere uma URL na janela de endereço do navegador ou clica em um link, o navegador faz uma solicitação HTTP (Hypertext Transfer Protocol) ao servidor Web para o conteúdo especificado, seja uma página ASP.NET, uma imagem, um arquivo JavaScript ou qualquer outro tipo de conteúdo. O servidor Web tem a tarefa de retornar o conteúdo solicitado. Ao fazer isso, ele deve determinar várias coisas sobre a solicitação, incluindo quem fez a solicitação e se a identidade está autorizada a recuperar o conteúdo solicitado.
Por padrão, os navegadores enviam solicitações HTTP que não possuem nenhum tipo de informação de identificação. Mas se o navegador incluir informações de autenticação, o servidor Web iniciará o fluxo de trabalho de autenticação, que tentará identificar o cliente que está fazendo a solicitação. As etapas do fluxo de trabalho de autenticação dependem do tipo de autenticação que está sendo usado pelo aplicativo Web. ASP.NET oferece suporte a três tipos de autenticação: Windows, Passport e formulários. Esta série de tutoriais se concentra na autenticação de formulários, mas vamos comparar e contrastar os repositórios de usuários e o fluxo de trabalho da autenticação do Windows.
Autenticação via Autenticação do Windows
O fluxo de trabalho de autenticação do Windows usa uma das seguintes técnicas de autenticação:
- Autenticação Básica
- Autenticação digest
- Autenticação Integrada do Windows
Todas as três técnicas funcionam mais ou menos da mesma maneira: quando uma solicitação anônima e não autorizada chega, o servidor web envia de volta uma resposta HTTP que indica que a autorização é necessária para continuar. Em seguida, o navegador exibe uma caixa de diálogo modal que solicita ao usuário seu nome de usuário e senha (consulte a Figura 1). Essas informações são enviadas de volta ao servidor web por meio de um cabeçalho HTTP.
Figura 1: Uma caixa de diálogo modal solicita ao usuário suas credenciais
As credenciais fornecidas são validadas em relação ao Windows User Store do servidor Web. Isso significa que cada usuário autenticado em seu aplicativo Web deve ter uma conta do Windows em sua organização. Isso é comum em cenários de intranet. Na verdade, ao usar a Autenticação Integrada do Windows em uma configuração de intranet, o navegador fornece automaticamente ao servidor Web as credenciais usadas para fazer logon na rede, suprimindo assim a caixa de diálogo mostrada na Figura 1. Embora a autenticação do Windows seja ótima para aplicativos de intranet, geralmente é inviável para aplicativos da Internet, pois você não deseja criar contas do Windows para cada usuário que se inscreve em seu site.
Autenticação via autenticação de formulários
A autenticação de formulários, por outro lado, é ideal para aplicativos da Web da Internet. Lembre-se de que a autenticação de formulários identifica o usuário, solicitando que ele insira suas credenciais por meio de um formulário da web. Consequentemente, quando um usuário tenta acessar um recurso não autorizado, ele é redirecionado automaticamente para a página de login, onde pode inserir suas credenciais. As credenciais enviadas são validadas em um repositório de usuário personalizado - geralmente um banco de dados.
Depois de verificar as credenciais enviadas, um tíquete de autenticação de formulários é criado para o usuário. Esse tíquete indica que o usuário foi autenticado e inclui informações de identificação, como o nome de usuário. O tíquete de autenticação de formulários é (normalmente) armazenado como um cookie no computador cliente. Portanto, as visitas subsequentes ao site incluem o tíquete de autenticação de formulários na solicitação HTTP, permitindo assim que o aplicativo da Web identifique o usuário depois de fazer login.
A Figura 2 ilustra o fluxo de trabalho de autenticação de formulários de um ponto de vista de alto nível. Observe como as partes de autenticação e autorização em ASP.NET atuam como duas entidades separadas. O sistema de autenticação de formulários identifica o usuário (ou informa que ele é anônimo). O sistema de autorização é o que determina se o usuário tem acesso ao recurso solicitado. Se o usuário não estiver autorizado (como na Figura 2 ao tentar visitar ProtectedPage.aspx anonimamente), o sistema de autorização relatará que o usuário foi negado, fazendo com que o sistema de autenticação de formulários redirecione automaticamente o usuário para a página de login.
Depois que o usuário fizer login com êxito, as solicitações HTTP subsequentes incluirão o tíquete de autenticação de formulários. O sistema de autenticação de formulários apenas identifica o usuário - é o sistema de autorização que determina se o usuário pode acessar o recurso solicitado.
Figura 2: O fluxo de trabalho de autenticação de formulários
Vamos nos aprofundar na autenticação de formulários com muito mais detalhes no próximo tutorial, Uma visão geral da autenticação de formulários. Para obter mais informações sobre o ASP. NET, consulte Autenticação ASP.NET.
Limitando o acesso a páginas da Web, diretórios e funcionalidade de página
ASP.NET inclui duas maneiras de determinar se um usuário específico tem autoridade para acessar um arquivo ou diretório específico:
- Autorização de arquivo - como ASP.NET páginas e serviços da Web são implementados como arquivos que residem no sistema de arquivos do servidor da Web, o acesso a esses arquivos pode ser especificado por meio de ACLs (Listas de Controle de Acesso). A autorização de arquivo é mais comumente usada com a autenticação do Windows porque as ACLs são permissões que se aplicam a contas do Windows. Ao usar a autenticação de formulários, todas as solicitações no nível do sistema operacional e do sistema de arquivos são executadas pela mesma conta do Windows, independentemente do usuário que visita o site.
- Autorização de URL- com autorização de URL, o desenvolvedor da página especifica regras de autorização em Web.config. Essas regras de autorização especificam quais usuários ou funções têm permissão para acessar ou são impedidos de acessar determinadas páginas ou diretórios no aplicativo.
A autorização de arquivo e a autorização de URL definem regras de autorização para acessar uma página de ASP.NET específica ou para todas as páginas ASP.NET em um diretório específico. Usando essas técnicas, podemos instruir ASP.NET a negar solicitações a uma página específica para um usuário específico ou permitir o acesso a um conjunto de usuários e negar o acesso a todos os outros. E os cenários em que todos os usuários podem acessar a página, mas a funcionalidade da página depende do usuário? Por exemplo, muitos sites que oferecem suporte a contas de usuário têm páginas que exibem conteúdo ou dados diferentes para usuários autenticados versus usuários anônimos. Um usuário anônimo pode ver um link para fazer login no site, enquanto um usuário autenticado veria uma mensagem como Bem-vindo de volta, Nome de usuário junto com um link para sair. Outro exemplo: ao visualizar um item em um site de leilões, você vê informações diferentes, dependendo se você é um licitante ou aquele que leiloa o item.
Esses ajustes no nível da página podem ser realizados de forma declarativa ou programática. Para mostrar conteúdo diferente para usuários anônimos e autenticados, basta arrastar um controle LoginView para sua página e inserir o conteúdo apropriado em seus modelos AnonymousTemplate e LoggedInTemplate. Como alternativa, você pode determinar programaticamente se a solicitação atual é autenticada, quem é o usuário e a quais funções ele pertence (se houver). Você pode usar essas informações para mostrar ou ocultar colunas em uma grade ou painéis na página.
Esta série inclui três tutoriais que se concentram na autorização. A AutorizaçãoBaseada no Usuário examina como limitar o acesso a uma página ou páginas em um diretório para contas de usuário específicas; A Autorização Baseada em Função analisa o fornecimento de regras de autorização no nível da função; por fim, o tutorial Exibindo Conteúdo com Base no Usuário Conectado no Momento explora a modificação do conteúdo e da funcionalidade de uma página específica com base no usuário que visita a página. Para obter mais informações sobre o ASP. NET, consulte ASP.NET Autorização.
Contas e funções de usuário
ÁSPIDE. NET fornece uma infra-estrutura para que os usuários façam logon em um site e tenham seu estado autenticado lembrado nas visitas à página. E a autorização de URL oferece uma estrutura para limitar o acesso a arquivos ou pastas específicos em um aplicativo ASP.NET. Nenhum dos recursos, no entanto, fornece um meio de armazenar informações de conta de usuário ou gerenciar funções.
Antes do ASP.NET 2.0, os desenvolvedores eram responsáveis por criar seus próprios repositórios de usuários e funções. Eles também estavam no gancho para projetar as interfaces de usuário e escrever o código para páginas essenciais relacionadas à conta de usuário, como a página de login e a página para criar uma nova conta, entre outras. Sem nenhuma estrutura de conta de usuário integrada no ASP.NET, cada desenvolvedor que implementava contas de usuário tinha que chegar a suas próprias decisões de design em questões como: Como faço para armazenar senhas ou outras informações confidenciais? e Quais diretrizes devo impor em relação ao comprimento e à força da senha?
Hoje, a implementação de contas de usuário em um aplicativo ASP.NET é muito mais simples graças à estrutura de associação e aos controles Web de logon internos. A estrutura de associação é um punhado de classes no namespace System.Web.Security que fornecem funcionalidade para executar tarefas essenciais relacionadas à conta de usuário. A classe de chave na estrutura Membership é a classe Membership, que tem métodos como:
- CreateUser
- DeleteUser
- GetAllUsers
- GetUser
- Usuário de atualização
- ValidateUser
A estrutura de associação usa o modelo de provedor, que separa claramente a API da estrutura de associação de sua implementação. Isso permite que os desenvolvedores usem uma API comum, mas os capacita a usar uma implementação que atenda às necessidades personalizadas de seus aplicativos. Em resumo, a classe Membership define a funcionalidade essencial da estrutura (os métodos, propriedades e eventos), mas na verdade não fornece detalhes de implementação. Em vez disso, os métodos da classe Membership invocam o provedor configurado, que é o que executa o trabalho real. Por exemplo, quando o método CreateUser da classe Membership é invocado, a classe Membership não conhece os detalhes do repositório do usuário. Ele não sabe se os usuários estão sendo mantidos em um banco de dados ou em um arquivo XML ou em algum outro armazenamento. A classe Membership examina a configuração do aplicativo Web para determinar a qual provedor delegar a chamada, e essa classe de provedor é responsável por realmente criar a nova conta de usuário no repositório de usuários apropriado. Essa interação é ilustrada na Figura 3.
A Microsoft envia duas classes de provedor de associação no .NET Framework:
- ActiveDirectoryMembershipProvider - implementa a API de Associação no Active Directory e nos servidores do Modo de Aplicativo do Active Directory (ADAM).
- SqlMembershipProvider – implementa a API de Associação em um banco de dados SQL Server.
Esta série de tutoriais se concentra exclusivamente no SqlMembershipProvider.
Figura 03: O modelo de provedor permite que diferentes implementações sejam conectadas perfeitamente à estrutura (clique para exibir a imagem em tamanho real)
O benefício do modelo de provedor é que implementações alternativas podem ser desenvolvidas pela Microsoft, fornecedores de terceiros ou desenvolvedores individuais e conectadas diretamente à estrutura de associação. Por exemplo, a Microsoft lançou um provedor de associação para bancos de dados do Microsoft Access. Para obter mais informações sobre os provedores de associação, consulte o Kit de Ferramentas do Provedor, que inclui um passo a passo dos provedores de associação, provedores personalizados de exemplo, mais de 100 páginas de documentação sobre o modelo de provedor e o código-fonte completo para os provedores de associação internos (ou seja, ActiveDirectoryMembershipProvider e SqlMembershipProvider).
ASP.NET 2.0 também introduziu a estrutura de funções. Assim como a estrutura de associação, a estrutura de funções é criada sobre o modelo de provedor. Sua API é exposta por meio da classe Roles e o .NET Framework é fornecido com três classes de provedor:
- AuthorizationStoreRoleProvider - gerencia informações de função em um repositório de políticas do gerenciador de autorização, como o Active Directory ou o ADAM.
- SqlRoleProvider - implementa funções em um banco de dados SQL Server.
- WindowsTokenRoleProvider - associa informações de função com base no grupo Windows do visitante. Esse método normalmente é usado com a autenticação do Windows.
Esta série de tutoriais se concentra exclusivamente no SqlRoleProvider.
Como o modelo de provedor inclui uma única API voltada para o encaminhamento (as classes Membership e Roles), é possível criar funcionalidade em torno dessa API sem ter que se preocupar com os detalhes de implementação - eles são tratados pelos provedores selecionados pelo desenvolvedor da página. Essa API unificada permite que a Microsoft e fornecedores de terceiros criem controles da Web que fazem interface com as estruturas de Associação e Funções. ASP.NET é fornecido com vários controles Web de logon para implementar interfaces de usuário de conta de usuário comuns. Por exemplo, o controle Logon solicita a um usuário suas credenciais, valida-as e faz logon por meio da autenticação de formulários. O controle LoginView oferece modelos para exibir marcações diferentes para usuários anônimos versus usuários autenticados, ou marcação diferente com base na função do usuário. E o controle CreateUserWizard fornece uma interface do usuário passo a passo para criar uma nova conta de usuário.
Abaixo das capas, os vários controles de logon interagem com as estruturas de associação e funções. A maioria dos controles de logon pode ser implementada sem a necessidade de escrever uma única linha de código. Examinaremos esses controles com mais detalhes em tutoriais futuros, incluindo técnicas para estender e personalizar sua funcionalidade.
Resumo
Todos os aplicativos da Web que suportam contas de usuário exigem recursos semelhantes, como: a capacidade de os usuários fazerem login e terem seu status de login lembrado nas visitas à página; uma página da web para novos visitantes criarem uma conta; e a capacidade do desenvolvedor da página de especificar quais recursos, dados e funcionalidades estão disponíveis para quais usuários ou funções. As tarefas de autenticação e autorização de usuários e de gerenciamento de contas e funções de usuário são extremamente fáceis de realizar em aplicativos ASP.NET, graças à autenticação de formulários, autorização de URL e estruturas de associação e funções.
Ao longo dos próximos tutoriais, examinaremos esses aspectos criando um aplicativo da Web funcional do zero passo a passo. Nos próximos dois tutoriais, exploraremos a autenticação de formulários em detalhes. Veremos o fluxo de trabalho de autenticação de formulários em ação, dissecaremos o tíquete de autenticação de formulários, discutiremos questões de segurança e veremos como configurar o sistema de autenticação de formulários - tudo isso enquanto criamos um aplicativo da Web que permite que os visitantes façam login e logout.
Boa programação!
Leitura Adicional
Para obter mais informações sobre os tópicos discutidos neste tutorial, consulte os seguintes recursos:
- ASP.NET 2.0 Associação, funções, autenticação de formulários e recursos de segurança
- Diretrizes de segurança do ASP.NET 2.0
- Autenticação do ASP.NET
- ASP.NET Autorização
- Visão geral dos controles de login do ASP.NET
- Examinando a associação, as funções e o perfil do ASP.NET 2.0
- Como faço para proteger meu site usando associação e funções? (Vídeo)
- Introdução à associação
- Centro de Desenvolvedores de Segurança do MSDN
- Segurança, associação e gerenciamento de funções do Professional ASP.NET 2.0 (ISBN: 978-0-7645-9698-8)
- Kit de ferramentas do provedor
Sobre o autor
Scott Mitchell, autor de sete livros ASP/ASP.NET e fundador da 4GuysFromRolla.com, trabalha com tecnologias da Web da Microsoft desde 1998. Scott trabalha como consultor, instrutor e escritor independente. Seu último livro é Sams Teach Yourself ASP.NET 2.0 em 24 horas. Ele pode ser contatado em mitchell@4GuysFromRolla.com. ou através de seu blog, que pode ser encontrado em http://ScottOnWriting.NET.
Agradecimentos especiais a
Esta série de tutoriais foi revisada por muitos revisores úteis. O revisor principal deste tutorial foi Esta série de tutoriais foi revisada por muitos revisores úteis. Os principais revisores deste tutorial incluem Alicja Maziarz, John Suru e Teresa Murphy. Interessado em revisar meus próximos artigos do MSDN? Em caso afirmativo, envie-me uma mensagem para mitchell@4GuysFromRolla.com.