Primeiras aulas do curso ASP.NET Identity parte 2: autenticação e segurança com lockout

ASP.NET Identity parte 2: autenticação e segurança com lockout

Login e senha de usuário - Introdução

Bem vindo a essa segunda parte do nosso curso sobre ASP.NET Identity, meu nome é Guilherme Matheus e aqui vamos aprender recursos fundamentais para qualquer aplicação, vamos aprender como funciona o mecanismo de login na nossa aplicação, no nosso fórum.

E vamos aprender qual é a melhor forma de fazer esse recurso de “Esqueci minha senha”, como vamos fazer o usuário mudar a senha dele depois que ele esqueceu.

E para isso, vamos usar uma confirmação de e-mail, vamos mandar um e-mail para o usuário com uma url especial, personalizada, para a nossa aplicação onde o usuário vai conseguir ter acesso novamente à sua conta.

Nós vamos aprender mais coisa sobre o ASP.NET Identity, como funciona o mecanismo de logoff e como funciona um mecanismo de lockout, lockout é quando nós nos protegemos de várias tentativas de login sem sucesso, ou seja, um ataque de força bruta.

Vamos fazer mais configuração no Owin para aprender como ele se conversa, como ele se comunica com o ASP.NET Identity, então vamos continuar esse projeto a partir da primeira parte do nosso curso, por isso, se você não a fez, vamos fazer a parte 1 porque vamos aprender coisas fundamentais, como arquitetura, como Owin e as principais classes do ASP.NET Identity.

Login e senha de usuário - Criando a pagina de login

Fizemos muita coisa sobre o registro do usuário, mas não vamos esquecer que isso daqui é um fórum e como todo fórum, precisamos dar a opção, a função, para o usuário criar um novo tópico.

Então eu vou criar uma controller chamada “TopicoController” e essa TopicoController vai ser a controller que vai ter as actions que o usuário vai poder criar os seus tópicos, então eu vou implementar aqui “Controller” e criar a nossa action, “public ActionResult Criar ()”, para o usuário criar um tópico.

Esse daqui é muito semelhante ao nosso método de registrar, é somente uma view que o usuário dá um get, então vamos “return View();” e depois ele vai dar o post, ele vai escrever o título, o conteúdo e vai dar o post back, então já vou criar aqui, “public ActionResult Criar()” e como é o post back, vamos receber como argumento o modelo desse tópico, eu vou dar o nome para essa classe que nós ainda vamos criar de “TopicoCriarViewModel”, eu vou chamar de “modelo”.

Só vou adornar com o atributo “[HttpPost]” e agora vamos criar esse TopicoCriarViewModel, aqui no diretório de view models, eu vou adicionar uma nova classe e o tópico vai ter dois argumentos, ele precisa de duas propriedades, uma “string” que é o seu “Titulo” e uma “string” que é o “Conteudo” do texto desse tópico. Criado.

Vamos consertar o código na controller, adicionar essa diretiva using, por enquanto nós não vamos fazer nada, aqui nós só vamos dar um “return View();”, mas agora que criamos a TopicoController, precisamos criar a view, então vou vir aqui na nossa Solution, Views, eu vou adicionar um diretório, Add Folder e eu vou chamar de “Topico”.

E na Topico, precisamos então criar uma view que vai se chamar “Criar”, eu vou dar um adicionar. Já vamos aproveitar e mudar o modelo dessa view que vai ser o “@model ByteBank.Forum.ViewModels.TopicoCriarViewModel” e aqui o usuário vai criar o tópico dele, então eu vou criar um novo formulário, “”@using(Html.BeginForm())” e aqui dentro, vamos ter aquela mensagem de validação, vamos ter os controles para o usuário preencher e o botão de submit.

Então vamos começar pela validação, então vamos ter o “@Html.ValidationSummary(“”, new { })”, primeiro argumento vazio, segundo argumento, um objeto anônimo para nós preenchermos atributos da div que vai ser renderizada por meio desse HTML Helper, então eu vou definir a classe, “{ @class=””})”, igual aquela que usamos no momento de registrar o nosso usuário, que é o “text-danger”.

Aqui podemos criar o nosso formulário para o usuário preencher, então “@Html.EditorForModel()”. E enfim, o nosso botão de submit, então vai ser um “<input type=”submit” value=“Criar Tópico” />”. E para o usuário criar o tópico, ele precisa chegar nessa página e para chegar nessa página, podemos colocar uma opção no menu.

Então vou voltar na nossa Solution Explorer, aqui no nosso diretório Shared, em “_Layout.cshtml”, eu vou adicionar esse novo link e eu vou aproveitar e dar uma limpada nesse código aqui gerado automaticamente pelo Visual Studio.

Por exemplo, esse Contact e esse About, eu vou remover, eu só vou aproveitar esse que eu vou usar ele para colocar nosso botão de criar tópico, “Criar novo tópico”, vamos acessar a action Criar da controller Topico. Outra coisa que podemos melhorar, é tirar esse Application name e colocar o “ByteBank Fórum”.

Vamos executar? Dei um start na aplicação, a aplicação rodando, temos esse botão “Criar novo tópico”, eu vou clicar nele e eu posso preencher o título, então como é o fórum do ByteBank, eu posso colocar algo relacionado a um cartão de crédito, então “Dúvida cartão de crédito” e aqui um conteúdo qualquer.

Mas espera, eu estou acessando essa página aqui e eu não estou logado no sistema, na verdade essa página deveria ser protegida, só para quem é membro do fórum ByteBank, não é uma página de acesso público, então vamos mudar esse código.

Eu vou fechar a aplicação e para termos uma action, como no caso a nossa TopicoController Criar, segura somente para membros autorizados na nossa aplicação e os membros autorizados são usuários do fórum, adornamos a nossa action com o atributo chamado “[Authorize]”.

E então eu quero que essa action seja protegida e eu quero que essa action aqui também seja protegida. Agora sim, vamos executar? Eu dei um start na aplicação, a aplicação está rodando, eu vou clicar de novo em “Criar novo tópico” e agora sim, temos essa página padrão de erro, erro 401, que é o código que indica que nós não temos autorização para acessar essa página.

Para ter autorização, precisamos fazer o login, então vamos colocar um botão aqui de login? Eu vou fechar a aplicação, vamos voltar aqui no nosso “_Layout.cshtml”, eu vou duplicar essa linha aqui do menu, que estamos construindo à direita, “Ctrl + C”, “Ctrl + V”, e eu vou chamar de “Login” e vamos criar uma action chamada Login na nossa ContaController.

Então Controllers, ContaController e vamos criar a nossa nova action. Eu vou criar aqui embaixo, “public”, eu já vou usar a sintaxe de um método assíncrono, “public Task ” e essa action aqui se chama “Login ()”, fechei aqui, vamos retornar uma view e vamos ter o post back, então copiei e colei, “[HttpPost]” e vamos criar uma “(ContaLoginViewModel modelo)”.

Vamos criar essa ContaLoginViewModel? Eu vou vir aqui na nossas view models e eu vou adicionar um novo item, uma nova classe, a ContaLoginViewModel, essa ContaLoginViewModel, ela vai precisar de duas coisas, o e-mail do usuário e a sua senha.

Então “public string Email {get; set; }” e “public string Senha {get; set; }”. Vamos aproveitar e adornar isso aqui, “[Required]”, porque são obrigatórios, copiei e colei aqui, vamos indicar que o “[DataType”, o tipo desse dado, é o “(DataType.Password)]” e vamos adornar o nosso e-mail dizendo que ele é um “[EmailAddress]”.

Agora estamos recebendo isso na nossa ContaController, aqui temos o nosso modelo. Primeira coisa que podemos fazer antes de validar isso daqui, é ver se o model state é válido, então “if(ModelState.IsValid)”, continuamos a operação para “// Realizar login pelo Identity”, caso contrário alguma coisa de errado aconteceu, “// Algo de errado aconteceu”, retornamos a view passando o nosso modelo como argumento e aí vamos mostrar a mensagem de erro para o usuário.

Está faltando só mais uma coisa, precisamos criar essa página de login, então vou vir aqui no nosso projeto Views, Conta, eu vou criar uma nova view, essa view se chama “Login”, dei o Enter, nós já sabemos que o modelo dela é o “@model ByteBank.Forum.ViewModels.ContaLoginViewModel”.

E aqui vamos preencher o formulário, “@using(Html.BeginForm())”, vamos ter uma área para mostrar mensagem de erro e, de qualquer forma, vai ser muito semelhante ao que fizemos na criação de tópico. Então para tornar mais fácil, eu vou lá na nossa Topico, Criar e eu vou selecionar, eu vou copiar, eu vou vir aqui, eu vou colar. Aqui não é “Criar tópico”, aqui é “Fazer login!”.

Vamos testar? Eu vou dar um start na aplicação, a aplicação está rodando e olha só, como eu já estava com nossa página de login aberta, o Visual Studio, ele abriu a url automaticamente para nós aqui “Conta/Login”, mas vamos fazer o caminho natural do usuário, ele vai vir aqui na home do ByteBank Fórum e vai clicar em Login e está aqui, e-mail e senha, eu posso preencher, “guilherme.costa bytebank@gmail.com”, a senha, “teste123!” e clicar em Fazer login.

Vamos colocar um break point para ver se está tudo certo? Eu vou voltar na ContaLoginController, que está aqui, vamos procurar ela, eu vou colocar um break point aqui e vamos executar, Fazer login, nosso modelo, ele veio preenchido e agora só falta validarmos a senha que recebemos com a senha que está no banco de dados.

Login e senha de usuário - Entendendo o PasswordHash

Aqui é fácil, na nossa action, no post back do login, basta então que recuperemos o usuário daquele e-mail, então “var usuario = UserManager.FindByEmailAsync” e vamos pegar o nosso “(modelo.Email)”.

E agora, se esse usuário for nulo, é sinal que ele não existe na nossa base, se ele não existe, nós não vamos continuar a validação, mas se o usuário for diferente de nulo, então precisamos comparar a senha desse usuário com a senha do modelo, então já vou colocar um “if (modelo.Senha == usuario.”, senha em inglês, “Password”.

Espera, aqui o usuário, ele não tem uma propriedade “Password”, na verdade o usuário é uma task, é uma task porque eu esqueci da palavra chave “await”, agora que eu coloquei ela, vamos acessar a nossa password.

Mas continua não tendo password e agora com certeza, esse aqui é o identity user, olha só. Nós só temos esse “PasswordHash”, o que é esse PasswordHash? Vamos ver a nossa tabela? Eu vou abrir, View, SQL Server Object Explorer, View Data e vamos dar uma olhada no que tem nessa coluna aqui, PasswordHash.

Esse PasswordHash só tem um código gigante, o que é isso? E o que isso tem haver com a minha senha? Ter uma aplicação em um servidor comprometido, não é uma coisa tão rara.

E se um hacker tem acesso ao seu banco de dados, vamos dar de bandeja para ele toda uma lista de usuários e toda lista de senha bruta aqui nessa tabela? Nós não podemos fazer isso, se fazemos isso, o nosso negócio está falido, nós não podemos entregar a senha do nosso usuário para qualquer pessoa.

Então, na verdade o que guardamos é o hash, vamos ver o que é esse tal de hash? Eu criei uma função no PowerShell para ajudar nós a entendermos o que é esse hash. Essa função se chama “Obter-SenhaHash -Senha” e como argumento, ela recebe uma senha, então vou colocar aqui, “Teste123” e eu dei um Enter.

Isso daqui é o hash da senha “Teste123”, então o hash na verdade ele é uma bagunça, ele recebe uma string de entrada e ele devolve uma string toda bagunçada, que é isso daqui. Agora, se mudarmos esse Teste123 e colocar “1234”, “Teste123” e “Teste1234” é muitíssimo semelhante, então o que é natural esperarmos? Vai ter uma pequena mudança aqui nesse hash, provavelmente vai terminar com “79” ou vai mudar esse “078” para “100”, vamos dar um Enter.

Eu dei um Enter e eu só mudei um caractere aqui na nossa senha, mas o hash, ele mudou totalmente, esse daqui é um hash totalmente diferente do hash que tínhamos no “Teste123”.

Esse daqui é um aspecto importantíssimo, então eu mudo um caractere, uma pequena porção da string de entrada e a string de saída, o hash, depois dele passar por essa função de hash, ele muda totalmente, não dando dica para o usuário mal intencionado, para a pessoa mal intencionada, que isso daqui pode de alguma forma ter relação com esse hash aqui, então nós não sabemos isso.

Mas fizemos o “Teste1234”, vamos fazer de novo o “Teste123”? Então vamos observar que o hash, ele é sempre o mesmo para a mesma entrada de string, então “Teste123”, ele sempre vai retornar esse hash, comparando com a primeira tentativa que fizemos, o primeiro “Teste”.

“Guilherme, então significa que ao invés de guardar a minha senha bruta, eu posso guardar esse hash e guardando esse hash, o hacker, a pessoa mal intencionada, que tiver acesso a essa tabela, não vai conseguir bater o olho e descobrir qual senha é qual, não é mesmo?” Exatamente.

Mas, espera aí, temos um monte de senha manjada, então por exemplo, “Teste123” é uma senha manjada, outra senha manjada, que é uma senha catalogada entre as senhas mais utilizadas no mundo é, por exemplo, “abcdef”.

E olha só, eu não sei quem tem a senha “abcdef”, mas eu como hacker, eu sei que o hash dessa senha é essa porção aqui, então eu posso na verdade buscar essa porção aqui, na coluna PasswordHash e eu vou descobrir quais usuários tem a senha “abcdef”. Isso é verdade.

Mas o identity, ele coloca mais uma camada de segurança para nós e isso se chama salt, então quando o identity, ele recebe uma senha, ele adiciona, de forma gerada randomicamente, um salt e ele pega e ele dá um append, ele coloca um sufixo nessa senha.

Esse sufixo pode ser “SUFIXO_QUALQUER_1” e o hash não é calculado na senha “abcdef”, ele é calculado nessa união de “abcdef SUFIXO_QUALQUER_1” e eu vou dar um Enter e vemos que temos um hash totalmente diferente e esse sufixo, pelo identity, ele é gerado randomicamente, então vamos ter um “SUFIXO_QUALQUER_2”.

E inclusive nós não sabemos nem quais são os usuários que têm a mesma senha, olha aqui, eu tenho “abcdef”, eu tenho “abcdef” de novo, eu só mudei o salt, essa porção adicionada pelo identity e eu tenho um hash totalmente diferente.

Então não é pela senha que vamos comparar, vamos comparar pelo hash dessa senha e como é o identity que coloca esse salt, vamos usar o identity para ele resolver o hash também.

Sobre o curso ASP.NET Identity parte 2: autenticação e segurança com lockout

O curso ASP.NET Identity parte 2: autenticação e segurança com lockout possui 109 minutos de vídeos, em um total de 37 atividades. Gostou? Conheça nossos outros cursos de .NET em Programação, ou leia nossos artigos de Programação.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda .NET acessando integralmente esse e outros cursos, comece hoje!

  • 1124 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

Premium

  • 1124 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$75
à vista R$900
Matricule-se

Premium Plus

  • 1124 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$100
à vista R$1.200
Matricule-se

Max

  • 1124 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$120
à vista R$1.440
Matricule-se
Procurando planos para empresas?
Acesso por 1 ano
Estude 24h/dia onde e quando quiser
Novos cursos toda semana