DEV Community

Vinícius Boscardin
Vinícius Boscardin

Posted on

Autenticação, Autorização, MFA e muito mais com Golang

"Ó o cara falando de autenticação em pleno 2024!"

Sim! Vamos explorar como realizar fluxos de autenticação e autorização, e de quebra, entender a diferença entre estar autenticado e estar autorizado (spoiler: não é a mesma coisa!).

Image description

Neste texto, falaremos sobre três tópicos importantes:

  • JWT (o queridinho do mundo stateless)
  • OAuth (aquele que vive nas sombras das APIs de terceiros)
  • Casdoor (uma ferramenta que promete facilitar sua vida)

Autenticação vs. Autorização: Entendendo a Treta

Se você já trabalhou com autenticação, provavelmente ouviu algo como: “Fulano foi autenticado, então ele pode acessar tal recurso”. Calma lá! Estar autenticado é apenas dizer: “Sim, você é você mesmo!”. Agora, autorização é outra parada — significa: “Você, mesmo sendo você, tem permissão para mexer aqui?”. Percebe a diferença?


JWT: JSON Web Tokens no Role

JWT é aquele formato que a gente ama... até começar a lidar com expiração, rotação de tokens e as temidas brechas de segurança. O básico é simples:

token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
    "user": "fulano",
    "admin": true,
    "exp":  time.Now().Add(time.Hour * 24).Unix(),
})
tokenString, err := token.SignedString([]byte("s3cr3t"))
if err != nil {
    log.Fatal(err)
}
fmt.Println("Token:", tokenString)
Enter fullscreen mode Exit fullscreen mode

Simples, né? Um JWT é basicamente um pacote de informações assinado. O problema é que, depois de gerado, ele vive por aí, distribuído na rede. Por isso, controle bem o tempo de expiração e o armazenamento dos tokens!


OAuth

Quando você quer integrar com outros serviços, tipo permitir que o usuário faça login com Google, GitHub, ou aquele app de delivery, você provavelmente usará OAuth. A ideia é a seguinte: o serviço terceiro confirma quem é o usuário e devolve um token para você, dizendo: “Ele é quem diz ser e está autorizado a fazer tal coisa”.

A sequência geralmente é assim:

  1. O usuário clica em "Login com Google".
  2. Redirecionamos ele para o Google para se autenticar.
  3. Ele autoriza seu app a usar as informações.
  4. Seu app recebe um access token e, se for bonzinho, também um refresh token.

Casdoor

Agora, se você quer uma solução completa para autenticação e autorização que já vem com UI e suporte a múltiplos protocolos (JWT, OAuth, etc.), Casdoor pode ser uma boa opção. Ele é uma plataforma open-source, escrita em GOLANG para autenticação e autorização, projetada para facilitar a gestão de usuários e permissões em aplicações modernas. Ele oferece suporte a múltiplos protocolos de autenticação, como JWT, OAuth, SAML, LDAP, e até integração com serviços de identidade populares, como Google, GitHub, WeChat, entre outros.

Com o Casdoor, você obtém:

  • Interface de gerenciamento de usuários pronta para uso.
  • Administração centralizada de permissões e roles.
  • Integração fácil com APIs e front-ends em diferentes linguagens, incluindo Golang.
  • Multi-fator de autenticação (MFA) disponível para aumentar a segurança.
  • Suporte a OAuth e SSO (Single Sign-On), ideal para aplicações que precisam conectar múltiplos serviços.

Além de ser fácil de configurar, o Casdoor é ideal para quem quer rapidez na implementação e precisa de uma interface intuitiva para gerenciar usuários e autorização sem muito esforço.

Você pode explorar mais sobre o projeto no GitHub do Casdoor ou no site oficial.


Como Rodar o Casdoor com Docker para Testes

Se você quer experimentar o Casdoor rapidamente, a maneira mais fácil é rodá-lo com Docker usando a imagem casbin/casdoor-all-in-one. Esse contêiner já vem com tudo configurado (servidor e banco de dados), facilitando o processo.

Passo 1: Rodar o Casdoor com Docker

Execute o seguinte comando no terminal:

docker run -p 8000:8000 casbin/casdoor-all-in-one
Enter fullscreen mode Exit fullscreen mode

Isso irá:

  1. Baixar a imagem do Casdoor (caso você ainda não tenha).
  2. Rodar o servidor Casdoor na porta 8000.

Passo 2: Acessar a Interface do Casdoor

Assim que o contêiner estiver rodando, você pode acessar a interface de administração no navegador:

http://localhost:8000
Enter fullscreen mode Exit fullscreen mode

Passo 3: Login na Interface de Admin

As credenciais padrão para o login são:

  • Usuário: admin
  • Senha: 123

Com isso, você poderá explorar as funcionalidades do Casdoor, configurar provedores de autenticação, criar usuários e definir permissões.


Configuração Básica do Casdoor

1. Criar uma Organização

As organizações em Casdoor são usadas para agrupar usuários e aplicações. Siga as etapas para criar sua primeira organização.

Image description


2. Criar Provedores

Provedores permitem que você configure como os usuários podem se autenticar (Google, GitHub, LDAP, etc.). Adicione um ou mais provedores de autenticação.

Image description


3. Criar Adapters

Os adapters permitem que você integre o Casdoor a sistemas de autorização externos. Crie um adapter para conectar seu sistema de permissões.

Image description


4. Criar uma Aplicação

As aplicações permitem vincular usuários e provedores a um contexto específico. Crie uma aplicação e associe a uma organização e provedores.

Image description


Passo 5: Adicionar os Providers na Aplicação

Após criar sua aplicação, você precisa associar os provedores (Providers) a ela. Isso garante que a aplicação saiba quais métodos de login estarão disponíveis para os usuários.

  1. Acesse a aplicação que você criou.
  2. Adicione os provedores configurados previamente à lista de Providers da aplicação.

Image description


Passo 6: Configurar o Layout do Login e do Cadastro

O Casdoor permite personalizar as telas de login e cadastro para que fiquem com a cara da sua aplicação.

  1. Na interface de administração, acesse as configurações de UI da aplicação.
  2. Personalize as cores, logos e textos para o login e o cadastro.
  3. Visualize as mudanças em tempo real e salve.

Image description


Passo 7: Obter a URL para Autenticação

Após configurar tudo, você precisará da URL de autenticação para iniciar o fluxo de login a partir da sua aplicação.

  1. Acesse a aplicação e copie a URL de autenticação disponível na aba de configurações.
  2. Utilize essa URL para redirecionar usuários ao Casdoor quando precisarem se autenticar.

Exemplo de URL:

http://localhost:8000/login/oauth/authorize?client_id=[CLIENT_ID]&response_type=code&redirect_uri=http://localhost:9000/callback&scope=read&state=casdoor
Enter fullscreen mode Exit fullscreen mode

Image description


Passo 8: Callback com o Code

Após o login bem-sucedido, o Casdoor redirecionará o usuário para a URL de callback com um code.

Exemplo de callback:

http://localhost:9000/callback?code=b1bf883de5a552aa43d6&state=casdoor
Enter fullscreen mode Exit fullscreen mode

Esse code é temporário e será trocado por tokens para acessar recursos protegidos.


Passo 9: Obter Access Token, ID Token e Refresh Token

Após receber o code, você deve trocá-lo por tokens chamando a URL de token do Casdoor.

URL para Obter Tokens:

POST http://localhost:8000/api/login/oauth/access_token
Enter fullscreen mode Exit fullscreen mode

Parâmetros necessários:

  • client_id: ID da aplicação.
  • client_secret: Segredo da aplicação.
  • code: O código recebido na URL de callback.
  • redirect_uri: A mesma URL usada no processo de login.
  • grant_type: "authorization_code".

A resposta incluirá:

{
  "access_token": "eyJhbGciOiJIUzI1...",
  "id_token": "eyJhbGciOiJIUzI1NiIs...",
  "refresh_token": "e5d92f3a...",
  "expires_in": 3600,
  "token_type": "Bearer"
}
Enter fullscreen mode Exit fullscreen mode

Image description


Passo 10: Renovar o Access Token com o Refresh Token

Quando o access token expirar, você poderá obter um novo token usando o refresh token. Isso evita que o usuário precise fazer login novamente.

URL para Renovar o Token:

POST http://localhost:8000/api/login/oauth/refresh_token
Enter fullscreen mode Exit fullscreen mode

Parâmetros necessários:

  • grant_type: "refresh_code".
  • client_secret: Segredo da aplicação.
  • client_secret: ID da aplicação.
  • refresh_token: O código JWT de refresh na URL de access_token.
  • scope: "read".

A resposta incluirá um novo json com tokens:

{
  "access_token": "eyJhbGciOiJIUzI1...",
  "id_token": "eyJhbGciOiJIUzI1NiIs...",
  "refresh_token": "e5d92f3a...",
  "expires_in": 3600,
  "token_type": "Bearer"
}
Enter fullscreen mode Exit fullscreen mode

Image description


API Completa e SDKs para Integração

O Casdoor também disponibiliza uma API completa documentada no Swagger, permitindo que você crie telas de autenticação totalmente customizadas e adapte o fluxo de login às necessidades do seu projeto. Além disso, ele oferece SDKs para diversas tecnologias populares, como Flutter, React, Vue, Angular, e muito mais, facilitando a integração com diferentes stacks e plataformas. Com essas ferramentas, você tem flexibilidade para implementar autenticação de maneira rápida e eficiente, seja para aplicações web ou mobile.

GET http://localhost:8000/swagger/
Enter fullscreen mode Exit fullscreen mode

Image description


Integração com Casbin para Autorização

Além da autenticação, o Casdoor pode ser integrado com o Casbin, uma poderosa biblioteca de autorização baseada em políticas. O Casbin permite definir quem pode acessar quais APIs e recursos de forma flexível, utilizando uma abordagem baseada em regras. Com suporte a diversos modelos, como ACL (Access Control List), RBAC (Role-Based Access Control) e ABAC (Attribute-Based Access Control), o Casbin facilita o controle granular de permissões.

A combinação de Casdoor para autenticação e Casbin para autorização oferece uma solução robusta para controlar o acesso em suas aplicações. Você pode, por exemplo, autenticar o usuário com Casdoor e utilizar o Casbin para verificar se ele tem permissão para acessar uma rota ou recurso específico.


Como Funciona o Enforce no Casbin

O método Enforce é o coração do Casbin. Ele é responsável por verificar se uma determinada solicitação de acesso deve ser permitida ou negada com base nas políticas definidas. O método recebe três parâmetros principais: sub (o sujeito, ou usuário), obj (o objeto, ou recurso) e act (a ação, como GET ou POST). Se a política permitir a combinação desses três elementos, o Casbin retorna true, indicando que o acesso é autorizado; caso contrário, retorna false.

Por exemplo, no código abaixo, o Casbin verificará se o usuário pode realizar uma ação específica no recurso solicitado:

ok, err := e.Enforce("alice", "/admin", "GET")
if err != nil {
    log.Fatal(err)
}
if ok {
    fmt.Println("Acesso permitido")
} else {
    fmt.Println("Acesso negado")
}
Enter fullscreen mode Exit fullscreen mode

Esse processo garante que o acesso seja controlado dinamicamente com base nas permissões definidas na política, evitando que ações não autorizadas sejam executadas.


Exemplos de Uso em Controllers HTTP e Recursos

Aqui está um exemplo de como usar Casbin em uma aplicação Go para autorizar acesso a uma rota HTTP:

Exemplo de Middleware para Autorização com Casbin

package main

import (
    "github.com/casbin/casbin/v2"
    "net/http"
)

func authorize(e *casbin.Enforcer, sub, obj, act string) bool {
    ok, err := e.Enforce(sub, obj, act)
    if err != nil {
        return false
    }
    return ok
}

func middlewareAuth(e *casbin.Enforcer, next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        user := r.Header.Get("user") // Obtém o usuário do cabeçalho
        resource := r.URL.Path       // Recurso sendo acessado
        action := r.Method           // Método HTTP (GET, POST, etc.)

        if !authorize(e, user, resource, action) {
            http.Error(w, "Forbidden", http.StatusForbidden)
            return
        }

        next.ServeHTTP(w, r) // Continua se autorizado
    })
}
Enter fullscreen mode Exit fullscreen mode

Exemplo de Política RBAC (Role-Based Access Control)

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[role_definition]
g = _, _

[policy]
p, admin, /admin, GET
p, user, /profile, GET

[role_assignment]
g, alice, admin
g, bob, user
Enter fullscreen mode Exit fullscreen mode

Nesta política, o admin tem acesso à rota /admin e o user à rota /profile. O usuário Alice é atribuído ao papel de admin, enquanto Bob é um user.


Com essa abordagem, você pode criar sistemas seguros e escaláveis, combinando autenticação com o Casdoor e autorização com o Casbin.

Configuração no Casdoor

Passo 1: Criar o modelo

Image description


Passo 2: Definir o Enforce

Image description


E por fim, o MFA.

Como Configurar MFA no Casdoor

A Autenticação Multi-Fator (MFA) adiciona uma camada extra de segurança ao processo de login. Com ela, mesmo que alguém descubra a senha do usuário, será necessário um segundo fator para concluir a autenticação, como um código gerado por um app autenticador (Google Authenticator, Authy, etc.).

Passo 1: Adicionar autenticação 2 fatores no usuário.

Possível pela interface web ou implementando na API do casdoor para o usuário específico.

Image description


Passo 2: Realizar o Login

Ao realizar o login deve pedir o código de autenticação para validação.

Image description

Simples, não?


Conclusão

Autenticação e autorização são como aquelas engrenagens que, juntas, mantêm o sistema rodando redondo. A autenticação confirma quem é o usuário, enquanto a autorização define o que ele pode fazer. Não basta saber quem está logado; é preciso garantir que cada um só tenha acesso ao que realmente pode. É tipo festa: uma coisa é passar pela entrada, outra é conseguir entrar na área VIP.

Com o Casdoor, fica fácil gerenciar o processo de autenticação. Ele oferece uma variedade de opções, como login com Google, GitHub, além de integração com protocolos como JWT e OAuth. Já o Casbin é o cara que define as regras e garante que cada recurso seja acessado por quem tem permissão, funcionando como uma política de segurança que você controla.

Usar essas duas ferramentas juntas é uma solução poderosa. O Casdoor garante que só usuários legítimos passem pela porta, enquanto o Casbin faz o controle fino, autorizando ou bloqueando ações com base em regras personalizadas. E o melhor é que tudo isso pode ser integrado facilmente via API, com direito a documentação no Swagger e SDKs para várias tecnologias, como Flutter, React e Vue.

Com essa combinação, seu sistema fica bem organizado e seguro, sem complicação.

Top comments (2)

Collapse
 
gaabrielbrocco profile image
Gabriel Brocco

Fenômeno!

Collapse
 
bruno_chiot profile image
bruno chiot

Great article!
When will we have an English version?