SpringBoot
Tutorial SpringBoot: Autenticación OAuth en API REST
Aprende a implementar OAuth 2.0 y OpenID Connect en API REST con Spring Boot y GitHub para autenticación segura y stateless.
Aprende SpringBoot y certifícateImplementar seguridad OAuth en API REST de Spring con GitHub
La implementación de OAuth 2.0 con GitHub en una API REST de Spring Boot requiere configurar tanto el cliente OAuth como los endpoints de seguridad. A diferencia de las aplicaciones web tradicionales, nuestra API REST devolverá respuestas JSON y manejará la autenticación de forma stateless.
Configuración inicial del proyecto
Primero necesitamos agregar las dependencias necesarias en nuestro pom.xml
:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
Configuración de GitHub OAuth App
Para conectar con GitHub, necesitamos registrar nuestra aplicación en GitHub y obtener las credenciales OAuth. Ve a GitHub Settings > Developer settings > OAuth Apps y crea una nueva aplicación con:
- Application name: Tu nombre de aplicación
- Homepage URL:
http://localhost:8080
- Authorization callback URL:
http://localhost:8080/login/oauth2/code/github
GitHub te proporcionará un Client ID
y Client Secret
que necesitaremos para la configuración.
Configuración de propiedades
En application.yml
, configuramos los parámetros de OAuth:
spring:
security:
oauth2:
client:
registration:
github:
client-id: ${GITHUB_CLIENT_ID}
client-secret: ${GITHUB_CLIENT_SECRET}
scope:
- user:email
- read:user
provider:
github:
authorization-uri: https://github.com/login/oauth/authorize
token-uri: https://github.com/login/oauth/access_token
user-info-uri: https://api.github.com/user
user-name-attribute: id
server:
port: 8080
Configuración de Spring Security
Creamos la clase de configuración que define cómo manejar la autenticación OAuth:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authz -> authz
.requestMatchers("/", "/login", "/error").permitAll()
.anyRequest().authenticated()
)
.oauth2Login(oauth2 -> oauth2
.successHandler(authenticationSuccessHandler())
.failureHandler(authenticationFailureHandler())
)
.logout(logout -> logout
.logoutSuccessUrl("/")
.permitAll()
)
.csrf(csrf -> csrf.disable());
return http.build();
}
@Bean
public AuthenticationSuccessHandler authenticationSuccessHandler() {
return new OAuth2AuthenticationSuccessHandler();
}
@Bean
public AuthenticationFailureHandler authenticationFailureHandler() {
return new OAuth2AuthenticationFailureHandler();
}
}
Manejadores de autenticación
Implementamos manejadores personalizados para responder con JSON en lugar de redirecciones:
@Component
public class OAuth2AuthenticationSuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response,
Authentication authentication) throws IOException {
OAuth2AuthenticationToken token = (OAuth2AuthenticationToken) authentication;
Map<String, Object> attributes = token.getPrincipal().getAttributes();
// Crear respuesta JSON con información del usuario
Map<String, Object> userInfo = new HashMap<>();
userInfo.put("name", attributes.get("name"));
userInfo.put("email", attributes.get("email"));
userInfo.put("avatar_url", attributes.get("avatar_url"));
userInfo.put("authenticated", true);
response.setContentType("application/json");
response.setStatus(HttpStatus.OK.value());
ObjectMapper mapper = new ObjectMapper();
response.getWriter().write(mapper.writeValueAsString(userInfo));
}
}
@Component
public class OAuth2AuthenticationFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request,
HttpServletResponse response,
AuthenticationException exception) throws IOException {
Map<String, Object> errorResponse = new HashMap<>();
errorResponse.put("error", "authentication_failed");
errorResponse.put("message", "No se pudo autenticar con GitHub");
errorResponse.put("authenticated", false);
response.setContentType("application/json");
response.setStatus(HttpStatus.UNAUTHORIZED.value());
ObjectMapper mapper = new ObjectMapper();
response.getWriter().write(mapper.writeValueAsString(errorResponse));
}
}
Controlador REST para manejo de autenticación
Creamos un controlador que proporciona endpoints REST para la autenticación:
@RestController
@RequestMapping("/api/auth")
public class AuthController {
@GetMapping("/user")
public ResponseEntity<Map<String, Object>> getCurrentUser(Authentication authentication) {
if (authentication == null || !authentication.isAuthenticated()) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
.body(Map.of("authenticated", false));
}
OAuth2AuthenticationToken token = (OAuth2AuthenticationToken) authentication;
Map<String, Object> attributes = token.getPrincipal().getAttributes();
Map<String, Object> userInfo = new HashMap<>();
userInfo.put("id", attributes.get("id"));
userInfo.put("name", attributes.get("name"));
userInfo.put("email", attributes.get("email"));
userInfo.put("avatar_url", attributes.get("avatar_url"));
userInfo.put("authenticated", true);
return ResponseEntity.ok(userInfo);
}
@GetMapping("/status")
public ResponseEntity<Map<String, Object>> getAuthStatus(Authentication authentication) {
boolean isAuthenticated = authentication != null && authentication.isAuthenticated();
return ResponseEntity.ok(Map.of(
"authenticated", isAuthenticated,
"provider", isAuthenticated ? "github" : null
));
}
}
Controlador de recursos protegidos
Ejemplo de un controlador que requiere autenticación para acceder:
@RestController
@RequestMapping("/api/protected")
public class ProtectedController {
@GetMapping("/profile")
public ResponseEntity<Map<String, Object>> getUserProfile(Authentication authentication) {
OAuth2AuthenticationToken token = (OAuth2AuthenticationToken) authentication;
Map<String, Object> attributes = token.getPrincipal().getAttributes();
// Procesar información adicional del usuario
Map<String, Object> profile = new HashMap<>();
profile.put("username", attributes.get("login"));
profile.put("company", attributes.get("company"));
profile.put("location", attributes.get("location"));
profile.put("public_repos", attributes.get("public_repos"));
profile.put("followers", attributes.get("followers"));
return ResponseEntity.ok(profile);
}
@GetMapping("/dashboard")
public ResponseEntity<Map<String, Object>> getDashboard(Authentication authentication) {
String username = authentication.getName();
Map<String, Object> dashboard = new HashMap<>();
dashboard.put("welcome_message", "Bienvenido " + username);
dashboard.put("last_login", new Date());
dashboard.put("permissions", List.of("read", "write"));
return ResponseEntity.ok(dashboard);
}
}
Página de inicio para OAuth
Para facilitar el flujo de autenticación, creamos un endpoint simple que inicie el proceso:
@Controller
public class LoginController {
@GetMapping("/")
public ResponseEntity<Map<String, String>> home() {
Map<String, String> response = new HashMap<>();
response.put("message", "API REST con OAuth GitHub");
response.put("login_url", "/oauth2/authorization/github");
response.put("status_url", "/api/auth/status");
return ResponseEntity.ok(response);
}
@GetMapping("/login")
public void login(HttpServletResponse response) throws IOException {
// Redirige automáticamente a GitHub OAuth
response.sendRedirect("/oauth2/authorization/github");
}
}
Variables de entorno
Para mayor seguridad, configura las credenciales como variables de entorno:
export GITHUB_CLIENT_ID=tu_client_id_aqui
export GITHUB_CLIENT_SECRET=tu_client_secret_aqui
O crea un archivo .env
en el directorio raíz del proyecto:
GITHUB_CLIENT_ID=tu_client_id_aqui
GITHUB_CLIENT_SECRET=tu_client_secret_aqui
Flujo de autenticación
El flujo completo funciona de la siguiente manera:
- 1. El usuario accede a
/login
o/oauth2/authorization/github
- 2. Spring Security redirige a GitHub para autenticación
- 3. GitHub redirige de vuelta con el código de autorización
- 4. Spring Security intercambia el código por un token de acceso
- 5. Se obtiene la información del usuario desde la API de GitHub
- 6. El usuario queda autenticado y puede acceder a endpoints protegidos
Esta implementación proporciona una base sólida para integrar OAuth 2.0 con GitHub en tu API REST, manteniendo la simplicidad mientras ofrece la funcionalidad necesaria para autenticar usuarios de forma segura.
Otras lecciones de SpringBoot
Accede a todas las lecciones de SpringBoot y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Introducción A Spring Boot
Introducción Y Entorno
Spring Boot Starters
Introducción Y Entorno
Inyección De Dependencias
Introducción Y Entorno
Crear Proyecto Con Spring Initializr
Introducción Y Entorno
Crear Proyecto Desde Visual Studio Code
Introducción Y Entorno
Controladores Spring Mvc
Spring Mvc Con Thymeleaf
Vista En Spring Mvc Con Thymeleaf
Spring Mvc Con Thymeleaf
Controladores Spring Rest
Spring Mvc Con Thymeleaf
Open Api Y Cómo Agregarlo En Spring Boot
Spring Mvc Con Thymeleaf
Servicios En Spring
Spring Mvc Con Thymeleaf
Clientes Resttemplate Y Restclient
Spring Mvc Con Thymeleaf
Rxjava En Spring Web
Spring Mvc Con Thymeleaf
Métodos Post En Controladores Mvc
Spring Mvc Con Thymeleaf
Métodos Get En Controladores Mvc
Spring Mvc Con Thymeleaf
Formularios En Spring Mvc
Spring Mvc Con Thymeleaf
Crear Proyecto Con Intellij Idea
Spring Mvc Con Thymeleaf
Introducción A Los Modelos Mvc
Spring Mvc Con Thymeleaf
Layouts Y Fragmentos En Thymeleaf
Spring Mvc Con Thymeleaf
Estilización Con Bootstrap Css
Spring Mvc Con Thymeleaf
Gestión De Errores Controlleradvice
Spring Mvc Con Thymeleaf
Estilización Con Tailwind Css
Spring Mvc Con Thymeleaf
Introducción A Controladores Rest
Spring Rest
Métodos Get En Controladores Rest
Spring Rest
Métodos Post En Controladores Rest
Spring Rest
Métodos Delete En Controladores Rest
Spring Rest
Métodos Put Y Patch En Controladores Rest
Spring Rest
Gestión De Errores Restcontrolleradvice
Spring Rest
Creación De Entidades Jpa
Spring Data Jpa
Asociaciones De Entidades Jpa
Spring Data Jpa
Repositorios Spring Data
Spring Data Jpa
Métodos Find En Repositorios
Spring Data Jpa
Inserción De Datos
Spring Data Jpa
Actualizar Datos De Base De Datos
Spring Data Jpa
Borrar Datos De Base De Datos
Spring Data Jpa
Consultas Jpql Con @Query En Spring Data Jpa
Spring Data Jpa
Api Query By Example (Qbe)
Spring Data Jpa
Api Specification
Spring Data Jpa
Repositorios Reactivos
Spring Data Jpa
Configuración Base De Datos Postgresql
Spring Data Jpa
Configuración Base De Datos Mysql
Spring Data Jpa
Introducción A Jpa Y Spring Data Jpa
Spring Data Jpa
Configuración Base De Datos H2
Spring Data Jpa
Testing Unitario De Componentes Y Servicios
Testing Con Spring Test
Testing De Repositorios Spring Data Jpa
Testing Con Spring Test
Testing Controladores Spring Mvc Con Thymeleaf
Testing Con Spring Test
Testing Controladores Rest Con Json
Testing Con Spring Test
Testing De Aplicaciones Reactivas Webflux
Testing Con Spring Test
Testing De Seguridad Spring Security
Testing Con Spring Test
Testing Con Apache Kafka
Testing Con Spring Test
Introducción Al Testing
Testing Con Spring Test
Introducción A Spring Security
Seguridad Con Spring Security
Seguridad Basada En Formulario
Seguridad Con Spring Security
Registro De Usuarios En Api Rest
Seguridad Con Spring Security
Login De Usuarios En Api Rest
Seguridad Con Spring Security
Validación Jwt En Api Rest
Seguridad Con Spring Security
Autenticación Jwt Completa En Api Rest
Seguridad Con Spring Security
Seguridad Jwt En Api Rest Reactiva Spring Webflux
Seguridad Con Spring Security
Autenticación Y Autorización Con Anotaciones
Seguridad Con Spring Security
Fundamentos De Autenticación Oauth
Seguridad Con Spring Security
Autenticación Oauth Con Github
Seguridad Con Spring Security
Testing Con Spring Security Test
Seguridad Con Spring Security
Autenticación Oauth En Api Rest
Seguridad Con Spring Security
Introducción A Spring Webflux
Reactividad Webflux
Spring Data R2dbc
Reactividad Webflux
Controlador Reactivo Basado En Anotaciones
Reactividad Webflux
Controlador Reactivo Basado En Funciones
Reactividad Webflux
Operadores Reactivos Básicos
Reactividad Webflux
Operadores Reactivos Avanzados
Reactividad Webflux
Cliente Reactivo Webclient
Reactividad Webflux
Introducción E Instalación De Apache Kafka
Mensajería Asíncrona
Crear Proyecto Con Apache Kafka
Mensajería Asíncrona
Creación De Producers
Mensajería Asíncrona
Creación De Consumers
Mensajería Asíncrona
Kafka Streams En Spring Boot
Mensajería Asíncrona
Integración Con Angular
Integración Frontend
Integración Con React
Integración Frontend
Integración Con Vue
Integración Frontend
Ejercicios de programación de SpringBoot
Evalúa tus conocimientos de esta lección Autenticación OAuth en API REST con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
Crear entidades JPA
Controladores Spring MVC
Asociaciones de entidades JPA
Creación de entidades
Reto servicio PedidoService
Reto controlador REST
Consultas JPQL
Reto test controlador REST
Anotaciones JPA
Relación ManyToOne con Tarea y Proyecto
CRUD Customers Spring MVC + Spring Data JPA
Backend API REST con Spring Boot
Filtrar categorías por nombre
Reto controlador MVC Categoría
Entidad y repositorio
Métodos derivados y consultas JPQL en repositorios
En esta lección
Objetivos de aprendizaje de esta lección
- Comprender cómo configurar una aplicación OAuth en GitHub para obtener credenciales.
- Aprender a integrar OAuth 2.0 en una API REST con Spring Boot y Spring Security.
- Configurar manejadores personalizados para respuestas JSON en autenticación exitosa o fallida.
- Crear controladores REST que gestionen la autenticación y acceso a recursos protegidos.
- Entender el flujo completo de autenticación OAuth 2.0 con GitHub en un entorno stateless.