<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Anastácio Gomes</title>
    <description>The latest articles on Forem by Anastácio Gomes (@gloinho).</description>
    <link>https://forem.com/gloinho</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1143358%2Fa9be3cc4-f787-499a-9351-e84fcdf11888.jpeg</url>
      <title>Forem: Anastácio Gomes</title>
      <link>https://forem.com/gloinho</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/gloinho"/>
    <language>en</language>
    <item>
      <title>Autenticação e Autorização de uma ASP .NET Web API com Keycloak</title>
      <dc:creator>Anastácio Gomes</dc:creator>
      <pubDate>Tue, 22 Aug 2023 21:52:37 +0000</pubDate>
      <link>https://forem.com/gloinho/autenticacao-e-autorizacao-de-uma-asp-net-web-api-com-keycloak-loe</link>
      <guid>https://forem.com/gloinho/autenticacao-e-autorizacao-de-uma-asp-net-web-api-com-keycloak-loe</guid>
      <description>&lt;p&gt;Olá pessoal!&lt;/p&gt;

&lt;p&gt;No meu primeiro artigo eu gostaria de falar um pouco sobre autenticação, autorização e como podemos realiza-los de uma maneira muito prática e performática utilizando Keycloak.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é autorização e autenticação?
&lt;/h2&gt;

&lt;p&gt;Esses dois conceitos são utilizados frequentemente quando estamos falando de segurança de aplicações, mas se referem a aspectos distintos no gerenciamento de acesso a recursos.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Autenticação&lt;/strong&gt;: É a verificação da identidade do usuário. O primeiro processo quando você tenta acessar alguma aplicação, e nesse processo, é verificado se você é realmente quem você diz quem é e se a aplicação o conhece. Usualmente é feito por algum tipo de "segredo", como uma senha, uma assinatura digital ou uma impressão digital.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Autorização&lt;/strong&gt; : Após verificado a identidade do usuário com sucesso, e o usuário já se encontra dentro da aplicação, é necessário limitar quais recursos aquele usuário pode acessar ou não pode acessar. Aqui entra a autorização: é a definição de quais açoes, operaçoes ou recursos um usuário ou um grupo tem acesso.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introdução ao Keycloak
&lt;/h2&gt;

&lt;p&gt;De maneira sucinta, o Keycloak é um gerenciador de identidade e acesso open source, que adiciona autenticação a suas aplicações e evita a necessidade de armazenar ou autenticar usuários.&lt;br&gt;
Entre suas principais funcionalidades, é interessante ser destacado que o keycloak: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Realiza SSO nas suas aplicações (Single-Sign-on)&lt;/li&gt;
&lt;li&gt;Gerencia seus usuários&lt;/li&gt;
&lt;li&gt;Gerencia funcionalidades por meio de UI interativa&lt;/li&gt;
&lt;li&gt;Realiza isolamento de Tenants ( no Keycloak são os &lt;em&gt;realms&lt;/em&gt; que achei super legal )&lt;/li&gt;
&lt;li&gt;Reliza federação de usuários&lt;/li&gt;
&lt;li&gt;Conta com provedores externos de identidade (como GitHub, Instagram, Facebook etc)&lt;/li&gt;
&lt;li&gt;Possui diversos serviços de autenticação como OpenID, oAuth 2.0 e SAML 2.0.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Demonstração
&lt;/h2&gt;

&lt;p&gt;Para demonstrar a facilidade de realizar a autenticação e autorização em uma aplicação, irei demonstrar passo a passo como podemos:&lt;br&gt;
1) Iniciar o KeyCloak via Docker;&lt;br&gt;
2) Criar um novo realm;&lt;br&gt;
3) Criar usuários;&lt;br&gt;
4) Criar uma web-api e configurar o Keycloak;&lt;br&gt;
5) Testar endpoints protegidas&lt;br&gt;
6) Criar grupos, roles e associar grupos, usuários e roles;&lt;br&gt;
7) Testar novamente os endpoints;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Requisitos:

&lt;ul&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;.NET 6.0&lt;/li&gt;
&lt;li&gt;Postman ou Insomnia&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Iniciando o Keycloak via Docker
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Para esse passo, é necessário que você tenha o Docker instalado. Se não tiver, é só seguir o passo a passo na própria documentação (&lt;a href="https://www.docker.com/get-started/" rel="noopener noreferrer"&gt;https://www.docker.com/get-started/&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Abra um terminal e digite o seguinte comando:
```bash
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;docker run -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak:22.0.1 start-dev&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; Aqui, estamos expondo a porta 8080 e configurando as chaves de ambiente para acesso ao Console de Administrador e iniciando o Keycloak em modo de desenvolvimento com o start-dev.

Vamos para o console administrador via http://localhost:8080/admin/master/console/ e podemos acessar pelas credenciais cadastradas acima.

![img](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cdv0wscmhpwumo8qqne9.png)

## Criação de um novo Realm
Vamos realizar a criação de um novo realm para nossa aplicação
Clique no dropdown embaixo de KeyCloak e clique em Create Realm

![createrealm](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mcmxoqoko9emnx852mue.png)
Dê um nome para o seu realm, no caso estarei nomeando o meu como **mordor**

![mordorrealm](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n9ebyhlv2seq5fr7pttz.png)
Feito isso, o realm já estará ativo e selecionado e podemos passar para o próximo passo.

## Criação de usuários.
Dentro do realm que acabamos de criar, podemos realizar a criação de usuários clicando em Users no painel lateral e depois em Add User


![users](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sv9suxqfr0xphmjx8slr.png)

Irei criar inicialmente três usuários: Sam, Frodo e Sauron. Todos eles com apenas username e name.
Ao criar um usuário, precisamos definir a sua senha. Clique em um usuário e na aba Credentials, clique em Set Password e desmarque senha temporária apenas para testes.


![pass](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jm54ur423zsslx0z1qb9.png)

Feito isso, já temos nossos tres usuários criados e podemos partir para a criação de nossa web-api para realizarmos nossos primeiros testes de autenticação! 

## Criação da web-api e configuração do Keycloak 
Crie uma nova aplicação do tipo web-api. Pode ser feito via UI pelo Visual Studio ou pelo comando:
```bash


dotnet new webapi -n NomeDoProjeto


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Instale as bibliotecas do KeyCloak necessárias via NuGet&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

dotnet add package Keycloak.AuthServices.Authorization
dotnet add package Keycloak.AuthServices.Authentication


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Para verificar se foi instalado corretamente, podemos abrir o &lt;code&gt;csproj&lt;/code&gt; do nosso projeto. Deverá estar assim: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgxg7t6hlnnytst3lphv0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgxg7t6hlnnytst3lphv0.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Precisamos fazer com que o KeyCloak identifique nossa aplicação, isso significa que precisaremos criar um &lt;strong&gt;Client&lt;/strong&gt; pelo Console de Administrador.&lt;/p&gt;

&lt;p&gt;No painel lateral, clique em Client e depois em Create Client. O meu Client ID será &lt;em&gt;mordor-api&lt;/em&gt; e clique em Next.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiqjqat9dez9h8tl8htsa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiqjqat9dez9h8tl8htsa.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Iremos marcar Client authentication e Authorization e clicar em Next&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F21ztfyj50gasjgewd75h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F21ztfyj50gasjgewd75h.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No Login Settings, podemos definir qual a Home URL e as URL de redirecionamento, ou URL após realizar o Logout. Como estamos fazendo uma demonstração simples de uma web-api, não iremos preencher nenhum desses campos, mas é interessante notar que esses campos precisam ser preenchidos quando temos uma tela de login, e precisamos realizar o redirecionamento para nossa home page após a autenticação de um usuário.&lt;/p&gt;

&lt;p&gt;Criado nosso primeiro Client, iremos definir agora o &lt;strong&gt;Client Scope&lt;/strong&gt;, que se refere a um conjunto de permissões, atributos ou funcionalidades que são concedidos a um aplicativo durante a autenticação e autorização. No painel lateral, vamos clicar em Client scopes e depois em Create client scope.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk7l0en0w51lca1fb1tsw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk7l0en0w51lca1fb1tsw.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dê um nome ao seu escopo, selecione o Type como Default e o prococolo sendo OpenID Connect.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft99o3oo6p7lh96kj5xgd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft99o3oo6p7lh96kj5xgd.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após criado o escopo, iremos definir alguns &lt;strong&gt;Mappers&lt;/strong&gt;, que serão certos campos que serão mapeados dentro do token.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvvefncfx5h6i2mioq9n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvvefncfx5h6i2mioq9n.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Primeiro, iremos adicionar um mapper pre-definido para adicionar as roles de um client dentro do token.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F584xt7kyparvxhw98n1s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F584xt7kyparvxhw98n1s.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Iremos adicionar um novo mapper configurado, para adicionar o campo de Audience no token. Clique em AddMapper e depois em ByConfiguration e depois em Audience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5xz9iphy77fzvyyrl9wx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5xz9iphy77fzvyyrl9wx.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fptbo47pv94jb07cmkhpw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fptbo47pv94jb07cmkhpw.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nosso escopo deverá ter dois mappers:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5o0h81hqjnfh2xjk11qk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5o0h81hqjnfh2xjk11qk.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Precisamos adicionar o scope criado ao nosso client. Na aba Clients, clique no client que você criou e depois disso na aba superior Client scopes e Add client scope.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh7vrzqv9u4rzhta7hpap.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh7vrzqv9u4rzhta7hpap.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frm3t8ewt602l0iinhe4c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frm3t8ewt602l0iinhe4c.png" alt="img"&gt;&lt;/a&gt;&lt;br&gt;
Iremos extrair as configurações necessárias do nosso Client, para configurar nossa web-api. Ainda no menu Clients, clique no dropdown Action no canto superior direito e depois em Download Adapter config. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpmes0y2ojmegl327i6vd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpmes0y2ojmegl327i6vd.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdtd1djv1x9uqghlxq9ex.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdtd1djv1x9uqghlxq9ex.png" alt="img"&gt;&lt;/a&gt;&lt;br&gt;
Altere o campo "ssl-required": "external" para "ssl-required": "none", visto que não iremos utilizar nenhum tipo de certificado.&lt;br&gt;
Copie todo esse JSON, e no &lt;code&gt;appsettings.Development.json&lt;/code&gt;  coloque a chave como sendo "Keycloak". Suas configurações deverão ficar assim:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc61hcias9i25ap9g7znl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc61hcias9i25ap9g7znl.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora, precisamos adicionar a autenticação e autorização no nosso &lt;code&gt;Program.cs&lt;/code&gt;.&lt;br&gt;
Adicione as seguintes linhas de código ao seu &lt;code&gt;Program.cs&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;authenticationOptions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;
                            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;
                            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetSection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;KeycloakAuthenticationOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Section&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;KeycloakAuthenticationOptions&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddKeycloakAuthentication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;authenticationOptions&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;authorizationOptions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;
                            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;
                            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetSection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;KeycloakProtectionClientOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Section&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;KeycloakProtectionClientOptions&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddKeycloakAuthorization&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;authorizationOptions&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;É importante notar que a Section no &lt;code&gt;appsettings.json&lt;/code&gt; deverá ser exatamente &lt;code&gt;Keycloak&lt;/code&gt;, visto que o &lt;code&gt;KeycloakAuthenticationOptions.Section&lt;/code&gt; é o padrão da biblioteca. Dessa maneira, o KeycloakAuthenticationOptions será bindado corretamente com as informações obtidas pelo adapter, que extraimos do console de administrador.&lt;br&gt;
Ah, não se esqueça também de adicionar:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseAuthentication&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseAuthorization&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Feito isso, crie um Controller e alguns endpoints para efetuar testes. Criei dois endpoints assim:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpGet&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Authorize&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;ActionResult&lt;/span&gt; &lt;span class="nf"&gt;CreateRing&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Ash nazg durbatulûk, ash nazg gimbatul, ash nazg thrakatulûk, agh burzum-ishi krimpatul"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpDelete&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Authorize&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;ActionResult&lt;/span&gt; &lt;span class="nf"&gt;DestroyRing&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;NoContent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Testando os endpoints protegidos
&lt;/h2&gt;

&lt;p&gt;Com o Postman, podemos obter o &lt;code&gt;acess_token&lt;/code&gt; enviando um request do tipo &lt;code&gt;POST&lt;/code&gt; para &lt;a href="http://localhost:8080/realms/mordor/protocol/openid-connect/token" rel="noopener noreferrer"&gt;http://localhost:8080/realms/mordor/protocol/openid-connect/token&lt;/a&gt;.&lt;br&gt;
No &lt;code&gt;Body&lt;/code&gt; da requisição, iremos realizar o grant_type do acess_token por meio da senha configurada para o usuário&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frh09brzddtohjuz9qbh9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frh09brzddtohjuz9qbh9.png" alt="img"&gt;&lt;/a&gt;&lt;br&gt;
Se tudo estiver correto, como resposta iremos receber uma resposta assim: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk7mcuor2lii0j3eyl3f8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk7mcuor2lii0j3eyl3f8.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Podemos colar o &lt;code&gt;access_token&lt;/code&gt; no site &lt;a href="https://jwt.io/" rel="noopener noreferrer"&gt;https://jwt.io/&lt;/a&gt; para verificar quais foram os campos que vieram no nosso JWT! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fczv54wm0d16endnp1bch.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fczv54wm0d16endnp1bch.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Iremos testar um dos nossos endpoints protegidos sem estarmos autorizados:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0wne8igswdbb7d0hpi8s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0wne8igswdbb7d0hpi8s.png" alt="img"&gt;&lt;/a&gt;&lt;br&gt;
Podemos observar que o Status foi 401 Unauthorized. Agora, nos autorizarmos colando o &lt;code&gt;access_token&lt;/code&gt; no Bearer Token obtemos um Status 200.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fubix9qzan56d9hbxpo1b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fubix9qzan56d9hbxpo1b.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Criação de grupos e roles e associação de usuários e grupos.
&lt;/h2&gt;

&lt;p&gt;Voltando ao Console de Administrador do KeyCloak, podemos realizar a criação de grupos no painel lateral. Irei criar apenas um grupo chamado FellowshipOfTheRing&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fppvzh33ki0c2ezvqs5ln.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fppvzh33ki0c2ezvqs5ln.png" alt="img"&gt;&lt;/a&gt;&lt;br&gt;
Agora iremos criar uma role para o nosso Client. Na aba Client, selecione o client que criamos para realizar a demonstração e na aba Roles, crie uma nova Role. Criei duas roles como indicado abaixo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnlqpuxqi846ffjv7bg7t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnlqpuxqi846ffjv7bg7t.png" alt="img"&gt;&lt;/a&gt;&lt;br&gt;
Vamos colocar Frodo e Sam (os usuários que criei) dentro do grupo FellowshipOfTheRing. Clique na aba groups e depois clique em Members e AddMember&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fllvirs7xkl2dlzw5qwaf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fllvirs7xkl2dlzw5qwaf.png" alt="img"&gt;&lt;/a&gt;&lt;br&gt;
Mapearemos apenas uma role para nosso grupo. Clique na aba Role mapping e depois em Assign Role. Filtramos por Clients (isso significa que podemos ver as roles que criamos no nosso client) e atribuimos a role DestroyRing para nosso grupo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh376ua4rv0m8ulrpdef7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh376ua4rv0m8ulrpdef7.png" alt="img"&gt;&lt;/a&gt;&lt;br&gt;
Agora, no painel lateral, em Users, iremos atribuir a role CreateRing para o usuario Sauron.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdlnu5fqya2pbmwavfawo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdlnu5fqya2pbmwavfawo.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Testar novamente os endpoints.
&lt;/h2&gt;

&lt;p&gt;Feitas as novas configuraçoes de acesso aos nossos recursos, podemos configurar nossas endpoints de acordo com essas configuraçoes de Roles. No Controller, irei mudar as rotas inserindo o parametro que irá verificar as Roles que o usuário possui.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpGet&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Authorize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Roles&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"CreateRing"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;ActionResult&lt;/span&gt; &lt;span class="nf"&gt;CreateRing&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Ash nazg durbatulûk, ash nazg gimbatul, ash nazg thrakatulûk, agh burzum-ishi krimpatul"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpDelete&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Authorize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Roles&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"DestroyRing"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;ActionResult&lt;/span&gt; &lt;span class="nf"&gt;DestroyRing&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;NoContent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;No Postman, vamos receber o &lt;code&gt;access_token&lt;/code&gt; como Sauron, e tentar acessar o endpoint DestroyRing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftj70lw6yngeur3j45rrr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftj70lw6yngeur3j45rrr.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Podemos perceber que o Status Code foi 403 Forbidden, visto que Sauron não possui a Role &lt;code&gt;DestroyRing&lt;/code&gt; atribuida a ele. Agora se formos acessar a rota CreateRing obtemos o StatusCode 200, visto que o usuário Sauron possui a role necessária para o acesso ao endpoint. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi7j6m7q51x7o7f84q5x8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi7j6m7q51x7o7f84q5x8.png" alt="img"&gt;&lt;/a&gt;&lt;br&gt;
Se solicitarmos o access_token como Frodo ou como Sam, será que podemos acessar a endpoint CreateRing visto que atribuimos a role apenas para o grupo? A resposta é sim! Uma role atribuida a um grupo é repassada para os usuários que estão atribuidos a este grupo!&lt;br&gt;
Obtendo o &lt;code&gt;access_token&lt;/code&gt; e verificando o token no &lt;a href="https://jwt.io/" rel="noopener noreferrer"&gt;https://jwt.io/&lt;/a&gt; verificamos a Role que atribuimos ao grupo FellowshipOfTheRing e podemos realizar normalmente a requisição para o endpoint.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsif4x02y0qw3ppjcvxay.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsif4x02y0qw3ppjcvxay.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1edfdjugtf3koe8pieb8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1edfdjugtf3koe8pieb8.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Podemos perceber que as funcionalidades do Keycloak são inúmeras, e facilitam a nossa vida como desenvolvedor. As documentações são bastante claras e apresentam diversas explicações de como podemos implementar as features que o Keycloak oferecem em nossos projetos e em empresas. &lt;/p&gt;

&lt;p&gt;Espero que tenham gostado desse passo-a-passo! Pretendo aprofundar um pouco mais no tópico e irei trazer mais novidades por aqui! &lt;/p&gt;

&lt;p&gt;Segue o repositório da demonstração &lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/gloinho" rel="noopener noreferrer"&gt;
        gloinho
      &lt;/a&gt; / &lt;a href="https://github.com/gloinho/mordor-api" rel="noopener noreferrer"&gt;
        mordor-api
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Exemplo para demonstração de autenticação e autorização utilizando Keycloak
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;mordor-api&lt;/h1&gt;

&lt;/div&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/gloinho/mordor-api" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;Até a proxima!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>api</category>
      <category>security</category>
    </item>
  </channel>
</rss>
