Dando continuidade ao post que fiz há um tempo sobre representação de arquitetura de aplicações com diagramas C4, neste post trago uma questão muito importante quando falamos sobre desenvolvimento de API's Rest, que é a segurança. Para exemplificar a segurança em API's Rest, trago um exemplo de implementação de um dos componentes da arquitetura representada no diagrama do post anterior. Neste post apresento a implementação do microservice ecommerce-ms-product
implementado com Java 17, JPA e Spring Boot. Para a segurança da API utilizei o Keycloak como Identity and Access Management(IAM).
O que é um Identity and Access Management(IAM)?
A gestão de identidade e acesso oferece supervisão sobre a autenticação de usuários e a disponibilidade de recursos. Frequentemente referida como IAM, essa tecnologia assegura que as pessoas adequadas tenham acesso aos recursos digitais apropriados no momento oportuno e pelas razões corretas.
Conceitos básicos sobre IAM
Um recurso digital refere-se a qualquer combinação de aplicativos e dados dentro de um sistema computacional. Entre os exemplos, estão aplicativos web, APIs, plataformas, dispositivos e bancos de dados.
No centro do IAM está a identidade. Alguém deseja acessar seu recurso, seja um cliente, funcionário, membro ou participante. No contexto do IAM, uma conta de usuário corresponde a uma identidade digital. Além de representar pessoas, essas contas também podem estar associadas a elementos não humanos, como softwares, dispositivos da Internet das Coisas (IoT) ou robôs.
A autenticação consiste na verificação de uma identidade digital, garantindo que alguém (ou algo) comprove ser quem afirma.
Já a autorização determina quais recursos um usuário tem permissão para acessar.
Os padrões de autenticação e autorização são essenciais para garantir a segurança e a eficiência dos sistemas de gerenciamento de identidade (IAM). Os mais reconhecidos e amplamente adotados na indústria incluem:
OAuth 2.0: Protocolo de autorização que permite acesso seguro a recursos sem expor credenciais.
OpenID Connect (OIDC): Extensão do OAuth 2.0 para autenticação, permitindo que usuários se identifiquem de maneira segura.
SAML (Security Assertion Markup Language): Protocolo baseado em XML usado para autenticação e troca de informações de identidade entre diferentes sistemas.
FIDO2/WebAuthn: Padrão para autenticação sem senha, baseado em chaves criptográficas.
LDAP (Lightweight Directory Access Protocol): Protocolo usado para acessar e manter diretórios de informações sobre usuários e dispositivos.
Esses padrões são amplamente considerados os mais seguros e confiáveis para gerenciar identidades, proteger dados pessoais e controlar o acesso a recursos.
Client Credentials Flow
Na implementação utilizei o Client Credentials Flow(definido no OAuth 2.0 RFC 6749, seção 4.4) envolve um aplicativo trocando suas credenciais de aplicativo, como client ID e client secret, por um token de acesso.
Este fluxo é mais adequado para aplicativos Máquina-a-Máquina (M2M), como CLIs, daemons ou serviços de backend, porque o sistema deve autenticar e autorizar o aplicativo em vez de um usuário.
Na prática
Na implementação do microservice ecommerce-ms-product criei duas coleções de recurso:
/produtos
/categorias
Nelas implementei endpoints para criar, consultar deletar e atualizar esses recursos. Para proteger esses endpoints, para que sejam acessados apenas por quem tem as credenciais necessárias, adicionei no aquivo application.properties
do projeto a seguinte entrada:
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:7080/realms/security-ecommerce-api
Essa entrada configura a aplicação para utilizar o realm security-ecommerce-api
que foi criado no Keycloak
Também adicionei as seguintes dependências do Spring no projeto:
<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>
Com essas dependências no projeto, os endpoints do projeto já ficam indisponíveis, sendo acessadas apenas por quem tem as credenciais adequadas.
Configuração do Realm security-ecommerce-api
Na área interna do Keycloak, crie um novo Realm:
No Realm criado, vá ao menu Clients e crie um novo Client:
No nosso exemplo, criei o client ID ecommerce-client
, o client secret é gerado pelo Keycloak e apresentado na aba Credentials:
Testando a API segura
Para testar essa implementação, utilizei uma extensão do VSCode, Rest Client para executar requisições:
Configuração para Keycloak local
Para rodar o Keycloak local utilizei o Docker e Compose para subir os serviços do Mysql, para a base de dados do Keycloak, e do Keycloak.
services:
mysqlsrv:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: "MySql2019!"
MYSQL_DATABASE: "ecommerce-produtos"
ports:
- "3306:3306"
volumes:
- /home/paulo/Desenvolvimento/docker/mysql:/var/lib/mysql
networks:
- ecommerce-network
keycloak:
image: quay.io/keycloak/keycloak:24.0
container_name: keycloak-ecommerce
environment:
KC_HOSTNAME: localhost
KC_HOSTNAME_PORT: 7080
KC_HOSTNAME_STRICT_BACKCHANNEL: "true"
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin
KC_HEALTH_ENABLED: "true"
KC_LOG_LEVEL: info
KC_DB: mysql
KC_DB_USERNAME: root
KC_DB_PASSWORD: MySql2019!
KC_DB_URL_HOST: mysqlsrv
KC_DB_URL_PORT: 3306
KC_DB_SCHEMA: keycloak
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:7080/health/ready"]
interval: 15s
timeout: 2s
retries: 15
command: ["start-dev", "--http-port", "7080", "--https-port", "7443"]
ports:
- "7080:7080"
- "7443:7443"
networks:
- ecommerce-network
depends_on:
- mysqlsrv
networks:
ecommerce-network:
driver: bridge
Top comments (0)