Série WebApi Parte 2 – Autenticação via token.

logo

Quando falamos de aplicações web e aplicações mobile a questão de autenticação é importante para garantir a integridade de sua implementação e segurança de seus dados, em um cenário web tradicional é amplamente utilizado o uso de cookies ou sessions para guardar  a autenticação válida durante a navegação evitando assim que seja preciso se autenticar toda a vez que tentar utilizar algum recurso protegido de um sistema.

Quando estamos falando de serviços a autenticação muda um pouco, elas não podem manter um cookie por exemplo, então recorrem a um token a cada vez que precisar acessar algum recurso protegido.

Neste artigo vou mostrar como implementar segurança via token em uma aplicação WEBAPI criada com os conceitos do OWIN (se não conhece o OWIN ainda vá ao meu artigo anterior), o OWIN já possui alguns middlewares e entre eles está o OAuth2 que serve para executar o processo de autenticação.

O protocolo OAuth2 efetua a validação e gera o token para devolução ao cliente, para isso basta efetuar um post para o endereço configurado em uma propriedade chamada TokenEndpointPath , passando no body da mensagem três parâmetros: grant_type, username e password.

No parâmetro grant_type devemos sempre passar a string “password”, ao validar essas informações o OAuth2 retorna em formato JSON um objeto que contém um token e o tempo de expiração, este tempo é determinado em sua implementação.

Com esse token em mãos você do lado do cliente deve guardar e usar nas requisições futuras até que perca a validade e você tenha que requisitar um novo.

Vamos criar uma WEBAPI nova no projeto do artigo anterior, então crie um novo projeto com o nome de WebApiToken e deixe o mesmo igual ao projeto WebApiOwin. (estes fontes já se encontram lá no github).

Depois de criar o projeto igual ao anterior e verificar que  o mesmo está rodando corretamente faça a inclusão do pacote Microsoft.Owin.Security.OAuth pelo nuget digitando no package manager console:

Install-Package Microsoft.Owin.Security.OAuth

Ao finalizar a instalação da biblioteca do OAuth, abra o arquivo Startup.cs e vamos começar a fazer algumas mudanças para efetuar a autenticação via Token:

webapitoken_image1Foi criado um método novo ConfigureAccessToken, dentro deste método vamos configurar um objeto do tipo OAuthAuthorizationServerOptions com os seguintes parâmetros:

  • AllowInsecureHttp – defina esse parâmetro como true, mas lembre-se que em produção deverá ser false;
  • TokenEndPointPath – este é o endereço que irá fornecer o token de acesso;
  • AccessTokenExpireTimeSpan – é o valor em tempo que o token irá expirar;
  • Provider – aqui vamos definir a classe que irá efetivamente validar o usuário e devolver o token.

Agora vamos criar a classe ProviderTokenAccess, para isso crie uma classe na raiz do projeto e insira o código abaixo:

webapitoken_image2Esta classe herda a classe do OAuth OAuthAuthorizationServerProvider e basta agora subscrever os dois métodos ValidateClientAuthentication e GrantResourceOwnerCredentials

Neste exemplo foi criado uma lista estática com dois usuários somente para exemplificar, para isso criei um objeto User com duas propriedades Name e Password do tipo string e inseri em uma lista estática.

O método ValidateClientAuthentication é responsável por realizar validações extras quando o usuário se autentica com o token.

Dentro do método GrantResourceOwnerCredentials que recebe o contexto você terá acesso ao usuário e a senha através dos objetos contexto.UserName e contexto.Password, com esses dados você deverá efetuar a validação em suas regras de negocio, ou no banco, ou em um Active Directory, emfim aqui a validação fica a seu critério.

Caso não encontre o usuário devemos setar o objeto contexto.SetError com uma chave/valor e sair do método.

Caso encontre emitimos o token com o objeto ClaimsIdentity e o contexto.Validated.

Agora vamos abrir a classe controller HomeController e definir no método Get() que ele agora deverá ser protegido utilizado o atributo AUTORIZE:

webapitoken_image7Com essas definições prontas, vamos tentar chamar a API no browser e se tudo correu bem deveremos receber a mensagem: “Authorization has been denied for this request”:

webapitoken_image3Isso acontece porque fizemos uma chamada a WEBAPI sem mandar um token de acesso válido.

Agora com o serviço seguro o primeiro passo para consumir seus métodos e requisitar um token, vamos lá e para isso vamos utilizar o PostMan para efetuar nossas chamadas, a imagem abaixo mostra como chamar o serviço:

webapitoken_image4Notem que foi feito um request para a url http://localhost:10275/token  esse “/token” foi o que defimos lá na propriedade TokenEndPointPath da classe Startup.cs.

Caso passe alguma informação incorreta nos parâmetros, tipo uma senha ou usuario errados, a WEBAPI deverá retornar com erro como na imagem abaixo:

webapitoken_image5Agora vamos chamar o método protegido passando o token que conseguimos na primeira chamada:

webapitoken_image6Podemos ver no resultado que o request foi efetuado com sucesso, internamente a WEBAPI validou o token enviado e devolveu a resposta corretamente.

É isso ae, agora sua camada de serviços está segura com autenticação via token, no próximo artigo sobre WEBAPI vou falar um pouco sobre CORS (Cross-Origin Resource Sharing) e acrescentar mais algumas configurações bacanas na camada de serviço.

Lembrando que todo esse código está disponível no meu github. Bons estudos a todos e se ajudou comenta ae!

Abraço.

 

 

22 comments

    1. Ismael, você deverá ter um mecanismo no seu front-end que verifique sempre o retorno de suas API’s, caso o retorno seja de token inválido
      deverá novamente solicitar um token novo e substituir o que deixou em cache ou storage local.

  1. Parabéns, único tutorial de WebApi que encontrei sem aquele monte de frescura, querendo explicar cada virgula do código! Foi direto ao ponto e consegui até que enfim entender como funciona esse negócio!
    Vlw e parabéns!

      1. Marcelo, boa noite! muito boa sua página, tá ai uma coisa que estou tentando descobrir… Como configurar o IIS para aceitar esse tipo de autenticação…

  2. Amigo, não consigo acessar a rota “/token” que foi especificada no tutorial . Minha aplicação está rodando em localhost e quando faço http://localhost:2990/token, sempre recebo um 404 not found. Também tentei http://localhost:2990/api/token sem sucesso. A minha aplicação foi criada usando o minimo de componentes pré instalados (web api 2 vazia). Dessa forma, tive que fazer algumas configurações como a criação do arquivo Startup.cs e a sua configuração no Web.config, adicionando as seguintes keys:

    No caso Vpainel é o nome do meus namespace.
    Espero que possa me ajudar. Obrigado.

    1. Rogério, boa noite, desculpe a demora para responder, ainda está com problemas? se sim consegue disponibilizar seu código fonte para tentar descobrir o problema? abraço

  3. Marcelo,

    Gostaria de saber se consigo capturar o token neste momento que está sendo invocado o método protegido?
    Usaria esta informação para identificar quem está requisitando o serviço.
    Ou teria uma outra forma?

    Abs,

  4. Como consumir essa api via código C#?
    Minha dúvida está no ponto em que no postman usa “x-www.form-urlencoded”
    e não json. Como escrever um código C# para obter o token?

  5. Marcelo excelente trabalho, direto e simples, ajudou muito, porem estou com algumas duvidas, eu consigo ter acesso aos dados enviados pelo Token? ‘access_token’ e ‘expires_in’.
    Caso não tenha tem alguma forma de validar se o usuário que requisitou um novo Token ainda possui um access_token valido, ou seja que ainda não esperou?, obrigado.

  6. Parabéns Marcelo, ótimo artigo, porém estou com um porblema de autenticação, exibi a seguinte mensagem após da emissão do Token: Authorization has been denied for this request

  7. Bom dia. Gostaria de uma dica, como eu fa co para validar um token que foi gerado fora, não pela própria api? Eu preciso integrar uma ali com o cognito (aws) , não estou usando net core e nao posso mudar a versão do framework (4.5)

  8. Olá. Promo artigo. Poremneu tenho uma duvida, preciso fazer a integração de uma web api em net framework 4.5 com o contigo. O token nao será gerado pela api preciso apenas validada-lo e autorizar. Como faço isso?

  9. Otimo post, porém eu preciso fazer com que uma aplicaçao web api v2 (net framework 4.5) autorize com o token gerado pelo serviço da aws (cognito). Alguma dica de como implementar isso ?

Leave a Reply

O seu endereço de e-mail não será publicado.