Imagina que tienes una aplicación popular y los usuarios quieren registrarse, pero nadie quiere perder tiempo rellenando otro formulario de registro, inventando otra contraseña única y recordándola. En esos casos, los servicios de autenticación externos son un salvavidas.
Ejemplos de servicios externos populares:
- Google: aproximadamente uno de cada dos usuarios tiene una cuenta de Google.
- Facebook: a pesar de sus altibajos, sigue siendo una herramienta popular para autorización.
- GitHub: usado a menudo por desarrolladores.
- LinkedIn: ideal para comunidades de negocio.
Los servicios externos permiten a los usuarios entrar en tu aplicación usando una cuenta ya existente. Esto mejora la comodidad (¡nada de contraseñas nuevas!) y te da acceso a información verificada, como la dirección de email.
Cómo OAuth2 ayuda a integrar servicios externos
OAuth2 provee un mecanismo cómodo para usar servicios externos, gracias al cual tu aplicación (por ejemplo, el "cliente") puede solicitar acceso a los recursos del usuario al authorization server del servicio externo. Lo más importante: todo funciona mediante access tokens, no pasando contraseñas, lo que hace el proceso más seguro.
El principio básico es el siguiente:
- Tu aplicación redirige al usuario al authorization server (por ejemplo, Google).
- El usuario da permiso para el acceso.
- El authorization server emite a tu aplicación un access token.
- Con el token recibido, tu aplicación puede interactuar de forma segura con el resource server del proveedor externo.
Flujo de autorización: Authorization Flow
Authorization Flow es uno de los flujos de OAuth2, que se usa para conceder a terceros (es decir, a tu aplicación) acceso a los recursos del usuario con el permiso del propio usuario.
Vamos a desglosar las etapas clave:
1. Solicitud de autorización Tu aplicación redirige al usuario a la URL de autorización. Una URL típica se ve así:
https://accounts.google.com/o/oauth2/auth?
response_type=code&
client_id=YOUR_CLIENT_ID&
redirect_uri=YOUR_REDIRECT_URI&
scope=email profile&
state=xyz
Aquí:
- responsetype=code — indicamos que queremos usar Authorization Code Flow.
- clientid — el identificador de tu aplicación (obtenido al registrarla con el proveedor externo).
- redirect_uri — la URL a la que el servicio devolverá al usuario después de la autorización.
- scope — indica a qué datos el usuario debe dar acceso.
- state — se usa para prevenir ataques de falsificación de solicitudes (CSRF).
2. El usuario concede permiso Después de la redirección, el usuario ve la pantalla de autorización proporcionada por el proveedor (por ejemplo, Google). Allí puede decidir si quiere dar acceso a tu aplicación.
3. Obtención del Authorization Code Si el usuario acepta, el authorization server lo redirige de vuelta a tu redirect_uri, añadiendo en la URL el parámetro code:
https://yourapp.com/callback?code=4/SOME_AUTHORIZATION_CODE&state=xyz
Tu aplicación debe verificar el valor de state para asegurarse de que la solicitud viene de una fuente confiable.
4. Intercambio del Authorization Code por un Access Token Ahora tu aplicación envía una petición POST al authorization server para intercambiar el código por un token:
POST https://oauth2.googleapis.com/token
Content-Type: application/x-www-form-urlencoded
code=4/SOME_AUTHORIZATION_CODE&
client_id=YOUR_CLIENT_ID&
client_secret=YOUR_CLIENT_SECRET&
redirect_uri=YOUR_REDIRECT_URI&
grant_type=authorization_code
Si todo sale bien, en la respuesta recibirás un JSON con el token:
{
"access_token": "ya29.a0ARrdaM...",
"expires_in": 3599,
"scope": "email profile",
"token_type": "Bearer",
"refresh_token": "1//09n6..."
}
5. Acceso a los recursos Con el access_token obtenido, tu aplicación puede enviar peticiones al resource server del proveedor externo. Por ejemplo, para obtener el perfil del usuario:
GET https://www.googleapis.com/oauth2/v1/userinfo?alt=json
Authorization: Bearer ya29.a0ARrdaM...
Cómo se ve esto en Spring Boot
Aquí empieza lo más interesante: la implementación de este proceso en Spring Boot.
Paso 1: Añade las dependencias en pom.xml Para integrar Google OAuth2 necesitaremos la dependencia Spring Security OAuth2:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
Paso 2: Configura application.yml Indica las claves obtenidas de Google (u otro proveedor):
security:
oauth2:
client:
registration:
google:
client-id: YOUR_CLIENT_ID
client-secret: YOUR_CLIENT_SECRET
scope: profile, email
redirect-uri: "{baseUrl}/login/oauth2/code/google"
authorization-grant-type: authorization_code
provider:
google:
authorization-uri: https://accounts.google.com/o/oauth2/auth
token-uri: https://oauth2.googleapis.com/token
user-info-uri: https://www.googleapis.com/oauth2/v1/userinfo
Paso 3: Configura el controlador Crea un controlador para manejar la autenticación exitosa:
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@GetMapping("/user")
public String user(@AuthenticationPrincipal OAuth2User principal) {
return "Hola, " + principal.getAttribute("name");
}
}
Paso 4: Ejecuta la aplicación Arranca tu aplicación y ve a la URL /oauth2/authorization/google. Serás redirigido a Google para autorizar. Tras una autorización exitosa llegarás a /user, donde verás un saludo con tu nombre.
Errores típicos y sus soluciones
- Error de redirección: si
redirect_uriestá mal configurado, Google devolverá un error. Asegúrate de que coincide exactamente con lo que tienes en la Google Console. - Permisos insuficientes: si olvidaste indicar los
scopenecesarios en la configuración, no obtendrás los datos requeridos. - Token caducado: usa refresh tokens para renovar el
access_token.
OAuth2 con soporte para servicios externos es una herramienta potente para un acceso cómodo y seguro a tus aplicaciones. La implementación puede ser algo enrevesada, pero con Spring Boot tienes utilidades que simplifican el proceso. Como decía un colega programador: "¿Por qué no dejar que Google se ocupe de la autenticación?".
GO TO FULL VERSION