Spring boot + Keycloak - protegendo suas APIs (parte 1)
Marcelo
Posted on July 16, 2021
Segurança em APIs?
Tem APIs nos teus serviços? Como esta a segurança destas APIs?
Temos algumas maneiras de aplicar seguranças nas nossas APIs. Uma delas é a autenticação e autorização utilizando OpenID/OAuth2.
Keycloak
Pra que desenvolver se já temos ferramentas prontas?
O Keycloak é uma ferramenta open source que prove autenticação e autorização para serviços utilizando alguns protocolos como OpenID, OAuth2 e SAML. Ele tem integração com LDAP, AD e redes sociais.
Para testarmos, vamos subir uma instância do docker:
docker run --name keycloak -p 8080:8080 -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin quay.io/keycloak/keycloak:14.0.0
Ele sobe uma instância do H2 e mesmo que o serviço for reiniciado não vai perder as configurações que fizermos.
Configurando o Keycloak
O serviço vai subir na porta 8080 e pode ser acessado pela url http://localhost:8080
Quando subimos o docker, setamos um usuário e senha iniciais (KEYCLOAK_USER=admin e KEYCLOAK_PASSWORD=admin). Clique em "Administration Console", informe o usuário/senha para entrar no console.
A primeira coisa que precisamos fazer dentro do console é a criação de um realm. Podemos entender aqui que o realm é a representação da sua aplicação, podemos ter varias aplicações rodando na mesma instância do Keycloak.
Por default já é criado um realm master, é onde existe a conta de admin criado inicialmente e só iremos utiliza-lo para a criação de outros realms.
Então no canto superior esquerdo, vamos clicar em "Add realm".
O próximo passo é criar e configurar o client. Na aba lateral esquerda, clique em "Clients" e depois no botão "Create".
Depois de salvo, iremos editar as seguintes propriedades do client.
Aqui a url foi adicionada apenas por ser requerida, não iremos utiliza-la.
Estas alterações são necessárias para que, utilizando este client-id, conseguirmos adquirir um token para acesso as APIs.
Aplicação
Vamos criar um projeto simples utilizando o Spring Initializr.
Abra o projeto na sua IDE, edite o application.properties e adicione a porta que sua aplicação vai subir:
server.port=8090
Vamos adicionar o controller abaixo:
Subindo o projeto e fazendo um teste básico no postman podemos ver que o endpoint esta completamente aberto, sem nenhuma segurança.
Agora vamos adicionar a segurança. Edite o pom.xml e adicione as dependências necessárias:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
Só de adicionar as dependências, nossos endpoints já não estarão mais expostos.
Agora vamos informar ao spring security qual é a url de validação do token. Vamos editar o application.properties e vamos adicionar a propriedades necessária:
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8080/auth/realms/security-api
Atenção ao ultimo elemento da url, ele é o nome do seu realm.
E isso é o básico que precisamos para ter nossa API segura.
Pegando um token
Vamos pegar um access token no Keycloak pra testar nosso endpoint. A url para buscar o access token é:
http://localhost:8080/auth/realms/security-api/protocol/openid-connect/token
Lembrando que security-api é o nome do realm.
No postman, crie um request POST utilizando esta url acima. No body do request vamos enviar o seguinte:
- client_id: é o nome do client que foi criado no keycloak, no nosso caso é web-app.
- client_secret: aqui precisamos pegar o valor gerado lá no cadastro do client no keycloak. Edite o client, vá na aba "Credentials" e copie o valor de "Secret"
- grant_type: vamos setar "client_credentials", pois iremos gerar um token de um client cadastrado no keycloak.
Testando o endpoint seguro
Vamos copiar o valor do campo "access_token" do response e vamos editar o request ao nosso serviço. Este token deve ser incluído no header do request com a key Authorization e no value incluiremos um prefixo que mostra o tipo do token que será Bearer. Vai ficar assim:
Por ora é isto... vamos melhorar este código na parte 2.
O código deste tutorial esta no github
Já saiu a segunda parte de tutorial, você pode ver aqui
Posted on July 16, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.