Descomplicando o OAuth do Microsoft Graph
Tags: braziliandevs, azure, oauth, graph
Published: 2020-10-28 18:57:24

# Prólogo 

Nesse tempo que eu venho estudando as tecnologias da Microsoft, eu tirei algumas conclusões sobre as documentações: elas tem MUITA INFORMAÇÃO! Sério, é realmente muita informação. Porém, vendo por esse lado isso talvez seja algo que pode se tornar um pouco confuso tendo em mente que você está procurando algo muito especifico.

No meu caso, eu estava fazendo pesquisas sobre como implementar o Microsoft Graph e o OAuth mas foi bem mais complexo do que eu imaginava até entender as trocentas regras de negócio que implicavam dentro do processo de criação de um app. Uma das minhas maiores dores de cabeça nesse processo que durou aproximadamente DUAS SEMANAS foi entender que existe dois tipos de autenticação, sendo eles: o empresarial (utilizando o Tenant Id) que é focado para organizações e o pessoal que é o nosso foco. 

Não encontrei muita informação de facil acesso desse problema na internet e só consegui resolver de fato após pegar uma aplicação base que o Graph fornece e ficar olhando as diferenças de requisições, ou seja: foi um rolezão pra conseguir entender os diferentes fluxos.

Nesse processo eu decidi criar um post pra centralizar o básico das informações que eu adquiri fuçando na documentação da aplicação.

# Criando um novo App

Para que possamos consumir a API do Microsoft Graph, antes temos que criar uma conta na [Azure](https://portal.azure.com/) e após isso, vamos criar uma aplicação.

Para podermos localizar facilmente a aba de aplicações, basta pesquisar na barra de busca, como na GIF abaixo:

![Busca de aba para criação de novas aplicações](https://dev-to-uploads.s3.amazonaws.com/i/8qt744nrjlqma9ixiknp.gif)

Após entrarmos na aba de registro de novas aplicações, podemos ver que logo de cara temos o botão para criar uma nova aplicação. Apenas clique nele para prosseguir.

![Botão de criar novo aplicativo](https://dev-to-uploads.s3.amazonaws.com/i/1ryvtavriclgll4xuyxp.png)

Entrando na pagina de registro de uma nova aplicação, vamos ter alguns campos pra preencher. Porém, antes iremos entender o que cada um quer dizer.

![Registro de aplicação com campos destacados](https://dev-to-uploads.s3.amazonaws.com/i/x59qw31vzsusbg0xmtxr.png)

Seguem os campos

* **Name:** Nome da sua aplicação (pode ser mudado posteriormente)
* **Supported Account Types:** indica quais contas podem usar a sua aplicação. No caso, eu recomendo que você deixe todas as contas associadas a MS se conectarem.
* **Redirect URI:** indica para onde sua aplicação deverá ser redirecionada após feita a requisição de login. Deixe **http://localhost** como padrão caso você não tenha ideia de como configurar ainda.

Após configurar esses campos, estamos prontos para configurar nossa aplicação com o OAuth!

# Configurando o OAuth

Acho que antes de tudo, seria muito interessante entender o que é o OAuth. Afinal, fazer por fazer não é algo tão interessante.

> OAuth é um padrão aberto para autorização, comumente utilizado para permitir que os usuários da Internet possam fazer logon em sites de terceiros usando suas contas do Google, Facebook, Microsoft, Twitter, etc.—mas, sem expor suas senhas. 

Ou seja, o OAuth é um jeito de você integrar suas outras contas com a aplicação que você está criando/utilizando e isso é um padrão! Sim, é um padrão e você aprendendo como usar um deles você entende como aplicar com os outros provedores (Discord, Gmail, Spotify, Apple etc) e consegue escalar sua aplicação cada vez mais! 

No OAuth, você sempre terá que passar pela plataforma do seu provedor tendo que fazer login e vincular sua conta à aplicação da sua escolha e pra isso, você tem que ter um app na plataforma do provedor escolhido (que foi exatamente o que fizemos acima).

No caso do OAuth da Microsoft, é usado o Link abaixo:
```
Req type: GET

// URL em uma linha
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={GRAPH_ID}&redirect_uri={GRAPH_REDIRECT_URL}&response_type=code&response_mode=query&scope={GRAPH_SCOPES}

// URL explicativa
https://login.microsoftonline.com/common/oauth2/v2.0/authorize
?client_id={GRAPH_ID}
&redirect_uri={GRAPH_REDIRECT_URL}
&response_type=code
&response_mode=query
&scope={GRAPH_SCOPES}
```

No link acima, nós podemos ver que existem alguns campos preenchidos e algumas variáveis que devem ser substituídas (tudo que está entre chaves) pelas informações da sua aplicação. Mas antes, vamos entender sobre cada campo:

* **Client ID:** ID da sua Aplicação;
* **Redirect URI:** URL de redirecionamento (cadastrada no primeiro passo);
* **Response Type:** Tipo de resposta que irá ser retornada, use o **code** como padrão;
* **Response Mode:** Onde será retornado essa resposta, pode ser utilizado **query** (recomendado) ou **form_post**;
* **Scopes:** Referencia quais permissões o usuário precisa te conceder para que a sua aplicação passe a consumir;

Após entendermos todo o processo e suas variáveis, vamos para o painel da nossa aplicação buscar as informações necessárias para que possamos fazer login com a nossa aplicação.

ATENÇÃO: Nos tutoriais encontrados nas docs, é focado praticamente tudo em apps para organizações. O diferencial é que o app pessoal uma o `/common/` e os empresariais usam `/{TENANT_ID}/` então preste atenção na hora de criar sua URL e use os modelos descritos no post.

![Painel de Informações do meu APP](https://dev-to-uploads.s3.amazonaws.com/i/4qlxzpej6w3m0170gdq1.png)

Na imagem acima, podemos localizar facilmente as informações citadas acima. Iremos trabalhar apenas as informações basicas e no final do post falaremos sobre os `scopes` e para que eles servem.

Segue a URL da aplicação:

```
Req type: GET

// URL em uma linha
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=882d7378-a050-42b4-8ce7-492865e6a717&redirect_uri=http://localhost&response_type=code&response_mode=query&scope=mail.read+user.read

// URL explicativa (detalhada)
https://login.microsoftonline.com/common/oauth2/v2.0/authorize
?client_id=882d7378-a050-42b4-8ce7-492865e6a717
&redirect_uri=http://localhost
&response_type=code
&response_mode=query
&scope=mail.read+user.read
```

Após copiar o link de uma única linha acima e colar no browser, iremos ter o primeiro contato com o nosso provedor (Microsoft OAuth) para fazer login na nossa aplicação! O resultado final deve ser parecido com a print abaixo:

![Tela de autenticação com o OAuth da Microsoft](https://dev-to-uploads.s3.amazonaws.com/i/u2y3gl2l3cvedn84r61l.png)

Bonitão né? Essa é a tela de autenticação com o provedor, onde iremos conectar nossa conta Microsoft à nossa aplicação e pra isso acontecer basta ler e concordar com as permissões pedidas pelo app e clicar em aceitar.

![Autenticação no Browser](https://dev-to-uploads.s3.amazonaws.com/i/wpctuj8oipriqw23z7gi.png)
Após isso, você será redirecionado para a página que você cadastrou no inicio da sua aplicação com o código de autorização para você fazer o próximo passo da autenticação.

# Gerando o JWT para acessar a API do Graph

Após fazermos login na aplicação foi gerado um código único para confirmar aquele usuário (último passo) porém para que possamos fazer o uso desse código, precisamos usar esse código para autenticar na nossa aplicação e para que possamos usar as informações das API's do Graph.

Ou seja: temos que passar por mais uma requisição onde iremos fazer o código que retornou na URL se tornar um token para usarmos nas requisições para a API. Mas como iremos fazer isso? Segue a nova requisição que teremos que fazer:

```
Req type: POST

// URL em uma linha
https://login.microsoftonline.com/common/oauth2/v2.0/token?client_id={GRAPH_ID}&client_secret={GRAPH_SECRET}&redirect_uri={GRAPH_REDIRECT_URL}&grant_type=authorization_code&code={CODE}

// URL explicativa
https://login.microsoftonline.com/common/oauth2/v2.0/token
?client_id={GRAPH_ID}
&client_secret={GRAPH_SECRET}
&redirect_uri={GRAPH_REDIRECT_URL}
&grant_type=authorization_code
&code={CODE}
```

Existem informações que nós já vimos na requisição anterior, porém agora temos um **client_secret** e isso não foi mostrado ainda. Pra criar um novo secret, basta você ir na aba de **Certificates & Secrets** e gerar uma nova chave.

![Criação de chaves de App](https://dev-to-uploads.s3.amazonaws.com/i/zex8vogwams16ekuishu.png)

Atenção: você só poderá ver essa chave gerada uma única vez então salve-a assim que você gerar.

Após gerarmos essa chave, estamos prontos para fazer a nossa requisição de autenticação e pra isso irei usar o **Postman** pois esse post será livre de linguagens de programação, tendo apenas o conceito da coisa toda. Dito isso, irei gerar e preencher a nossa requisição no Postman e enviar.

![Requisição sendo replicada no POSTMAN](https://dev-to-uploads.s3.amazonaws.com/i/mknjq83t1arw5kunr2r1.png)

Quando executamos nossa requisição, podemos ver na print acima que é retornado um token do tipo `Bearer` e isso significa que estamos autenticados! Agora é usar esse token pra fazer algum tipo de requisição dentro das API's do Graph.
 
# Entendendo Escopos

Em qualquer OAuth você deve sempre se preocupar com as permissões que você pede para o cliente, pois isso implica diretamente em quanto poder a sua aplicação está tendo sob o usuário. Então, nós precisamos inicialmente entender quais permissões serão necessárias para que a sua aplicação funcione do jeito esperado.

No tutorial acima, foram usados dois escopos sendo eles o Mail.Read e User.Read. Esses dois escopos dão acesso à leitura da sua caixa de e-mail (exatamente, alguém pode ler seus e-mails com isso caso consiga seu token de acesso) e também acesso as suas informações pessoais. Porém existe uns vários escopos diferentes para acessar outras ferramentas do Graph que você irá descobrir em breve usando o **Graph Explorer** (link no final do post).

Para que possamos cadastrar algum escopo novo, devemos ir na aba `API Permissions` como mostrado na print abaixo.

![Pagina de Escopos do Microsoft Graph](https://dev-to-uploads.s3.amazonaws.com/i/0t271ldngxabfjivh2rj.png)
Vemos que na nossa requisição, pedimos dois escopos e na lista só está aparecendo um deles. O que acontece é que todos os escopos citados nessa lista são estritamente necessários para que sua aplicação todas as funções necessárias. Caso esteja listado, ele deverá estar no parametro `&scopes=` da sua URL de autenticação ou alguma coisa na sua aplicação NÃO FUNCIONARÁ.

Para adicionar novas permissões, basta clicar em `Add Permissions` e selecionar a aba do Graph e selecionar os escopos desejados.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/9vjuy6qgfq641so3crpg.gif)


Um último adendo quando aos escopos é que  não necessariamente eles são escritos do jeito resumido. Entenda:

```
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=882d7378-a050-42b4-8ce7-492865e6a717&redirect_uri=http://localhost&response_type=code&response_mode=query&scope=mail.read+user.read

Escopos resumidos
mail.read user.read
```

Porém alguns escopos levam diretamente URL mostrada na informação do escopo colocado dentro do seu app. O gif abaixo mostra onde você irá encontrar o conteúdo do escopo para a URL de fato.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/af2lqzw1d9jdqxl3j14f.gif)


```
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=882d7378-a050-42b4-8ce7-492865e6a717&redirect_uri=http://localhost&response_type=code&response_mode=query&scope=mail.read+user.read+https://graph.microsoft.com/Files.Read

Escopos resumidos
mail.read user.read

Escopos como URL
https://graph.microsoft.com/Files.Read
```

Agora se você me perguntar o por quê que alguns escopos funcionam sem a URL completa e outros não eu realmente não vou saber te responder, mas espero feedbacks sobre esse processo.

Caso você tenha conseguido implementar o projeto, deixa nos comentários ai como foi o processo e se o post foi útil pra isso acontecer.

Link para o [Graph Explorer](https://developer.microsoft.com/en-us/graph/graph-explorer)