Introdução ao OAuth 2.0 e autorização JWT em Java
Aplicações web modernas e APIs exigem mecanismos robustos de autenticação e autorização. Dois padrões que se tornaram de facto no mundo do desenvolvimento Java são OAuth 2.0 e JWT (JSON Web Tokens). OAuth 2.0 fornece um protocolo para delegação de acesso, enquanto JWT é um formato compacto e autossuficiente para transmissão de dados. Neste artigo, vamos explorar como combinar essas tecnologias em Java usando Spring Security e bibliotecas populares.
Você aprenderá como configurar um servidor de autorização, gerar e validar tokens JWT, além de proteger seus endpoints REST. O material será útil tanto para iniciantes quanto para desenvolvedores Java experientes que desejam aprofundar seus conhecimentos em segurança.
Fundamentos do OAuth 2.0: Fluxos e papéis
OAuth 2.0 define quatro papéis: Resource Owner (proprietário do recurso), Client (aplicação), Authorization Server (servidor de autorização) e Resource Server (servidor de recursos). Os fluxos (grants) mais populares incluem:
- Authorization Code — para aplicações web com backend.
- Client Credentials — para comunicação servidor-a-servidor.
- Resource Owner Password — para clientes confiáveis (em desuso).
- Implicit — para SPAs (não mais recomendado).
Em Java, podemos implementar um servidor OAuth 2.0 usando spring-security-oauth2-authorization-server. Vejamos um exemplo de configuração de um servidor de autorização básico.
Configuração do Authorization Server com Spring Boot
Adicione as dependências no pom.xml:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-authorization-server</artifactId></dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency>Crie a configuração SecurityConfig.java:
@Configuration@EnableWebSecuritypublic class SecurityConfig {
@Bean @Order(1) public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); return http.build(); }
@Bean @Order(2) public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests(authorize -> authorize .anyRequest().authenticated()) .formLogin(Customizer.withDefaults()); return http.build(); }
@Bean public RegisteredClientRepository registeredClientRepository() { RegisteredClient registeredClient = RegisteredClient.withId("client-id") .clientId("my-client") .clientSecret("{noop}secret") .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) .redirectUri("http://localhost:8080/login/oauth2/code/my-client") .scope("read") .scope("write") .build(); return new InMemoryRegisteredClientRepository(registeredClient); }}JWT: Estrutura e geração de tokens
JWT consiste em três partes: Header, Payload e Signature. O Header contém o tipo do token e o algoritmo de criptografia. O Payload inclui claims (declarações), como sub (sujeito), exp (tempo de expiração) e roles. A Signature garante a integridade dos dados.
Para trabalhar com JWT em Java, usamos a biblioteca io.jsonwebtoken:jjwt. Adicione a dependência