Implementando Bearer Autentication com WebAPI e Owin

Tags: webapi, security, owin, oauth, token

Introdução

Durante praticamente todos projetos que trabalhamos, nos deparamos com a necessidade da implementação de recursos de segurança, como autenticação e autorização. No desenvolvimento de APIs isto não é diferente, pois em vários endpoints teremos o conteúdo restrito a determinados usuários e grupos.

Como funciona a autenticação no WebAPI

Ao contrario de aplicações ASP.NET convencionais, quando trabalhamos com serviços (WebAPI) não temos os dados do usuário em uma sessão, ou seja, você não se autentica uma vez e simplesmente faz as requisições que quiser, você deve se autenticar a cada requisição.

Isto acontece pois o contexto de serviços é diferente das aplicações convencionais, onde temos a duração do mesmo para apenas uma requisição. Resumidamente, a requisição acontece, você autentica seu usuário, retorna o resultado (200, 404, 401) e essa requisição termina, morre!

Existem alguns tipos de autenticação como Bearer e Basic, onde eu particularmente prefiro o Bearer, pois ele trafega um token e não um usuário/senha no header. Embora o usuário/senha trafegados no header da autenticação Basic sejam encriptados em Base64, eles são facilmente desencriptados com o próprio Fiddler.

Como comentei anteriormente, a cada requisição devemos enviar o Token, sendo assim, uma requisição a um endpoint ficaria neste formato:

Bearer

Content-Type: application/json
Authorization: Bearer SEUTOKENAQUI

Basic

Content-Type: application/json
Authorization: Basic USER_PASS_EM_BASE64

Com base nestas informações, temos as seguintes tarefas para a autenticação:

  • Obter um Token
  • Fazer um request enviando o Token
  • Validar o token
  • Retornar o resultado da requisição

Neste post não vou entrar em méritos de como você está recuperando seus usuários. Estou partindo do ponto que você tem um repositório de usuários e alguma forma de validar seu usuário e senha.

Projeto e Dependências

Para este projeto, vou utilizar alguns pacotes para geração de Token, que por usa vez já se baseiam no Owin, então iniciamos o projeto com um “Empty Web Application” e marcamos a opção “WebAPI” para trazer somente o necessário para a aplicação.

Os pacotes necessários são:

  • Install-Package Microsoft.AspNet.WebApi.Owin
  • Install-Package Microsoft.Owin.Host.SystemWeb
  • Install-Package Microsoft.Owin.Security.OAuth
  • Install-Package Microsoft.Owin.Cors

Startup

Como estamos trabalhando com o Owin, temos tudo concentrado na classe Startup.cs, na raiz da aplicação. Sendo assim, nossa classe Startup.cs fica desta forma:

Como podemos ver, o único ponto diferente nesta classe é o método ConfigureOAuth, onde vamos cofigurar a segurança.

Para ter um provedor de Tokens na sua API com Owin + Auth, basicamente o que precisamos é uma configuração básica, dada pela instância do OAuthAuthorizationServerOptions, onde informamos itens como o endpoint on de token será gerado (Linha 28), tempo de vida do token (Linha 29) e o ainda não criado Provider (Linha 30).

Os itens mais importantes aqui são o Provider e o TokenEndPoint, pois são através deles que vamos gerar o token de acesso.

Criando um Provider

A criação de um provider nada mais é do que a implementação de uma classe que herde de OAuthAuthorizationServerProvider, cujo internamente terá dois métodos, ValidateClientAuthentication e GrantResourceOwnerCredentials. Destes métodos, utilizaremos o GrantResourceOwnerCredentials para validar um usuário e senha. Deste modo, a classe fica assim:

Na linha 24 temos o tratamento para os casos de CORS, pois imaginamos que teremos requisições para este end-point de vários domínios.

Feito este tratamento, das linhas 25 à 34 fazemos a validação do usuário e senha, e caso seja inválido, retornamos um erro (Linha 31).

Se tudo ocorrer bem, criamos um ClaimIdentity (Modelo de autorização) e retornamos como válido (Linha 40).

Com estes dois arquivos nossa API já está pronta para nos retornar um token.

Obtendo um token

Para obter um token, precisamos de três informações:

  • grant_type
  • username
  • password

Neste caso, o grant_type será sempre password, pois estamos trabalhando com usuário/senha na autenticação, o que torna nossa requisição assim:

image

Para a requisição acima utilizei o Postman, um App do Chrome.

Bloqueando Acessos

Para tornar uma action restrita a este modelo de autenticação, basta utilizar o atributo [Authorize] para decorá-la.

Simples né :)

Acessando um endpoint restrito

Agora, para acessar este conteúdo bloqueado, precisamos informar o tipo de autorização e token no cabeçalho da requisição.

image

E como resultado temos:

image

Um demo deste código está no meu GitHub: https://github.com/andrebaltieri/oauth-bearer

Espero que tenham gostado!

 

André Baltieri
Microsoft MVP ASP.NET/IIS

http://andrebaltieri.net/
http://facebook.com/andre.baltieri