Autorización y autenticación en Kotlin: guía completa
En el desarrollo web moderno con Kotlin, la seguridad de la aplicación comienza con la implementación correcta de la autenticación (verificación de la identidad del usuario) y la autorización (verificación de los permisos de acceso). En este artículo, exploraremos los enfoques principales, bibliotecas y herramientas para implementar estos mecanismos en las plataformas Spring Boot y Ktor.
Conceptos básicos
Antes de pasar al código, aclaremos los términos:
- Autenticación — proceso de verificar que el usuario es quien dice ser (generalmente mediante usuario/contraseña, token o biometría).
- Autorización — determinación de los permisos de acceso de un usuario autenticado (por ejemplo, acceso a rutas o datos específicos).
- JWT (JSON Web Token) — token compacto y autónomo para transferir datos entre partes.
- BCrypt — algoritmo de hash de contraseñas con sal, resistente a ataques de fuerza bruta.
Autenticación con JWT en Spring Boot
Spring Security proporciona una infraestructura potente para la autenticación. Veamos la implementación de autenticación JWT usando la biblioteca io.jsonwebtoken:jjwt.
// build.gradle.ktsdependencies { implementation("org.springframework.boot:spring-boot-starter-security") implementation("io.jsonwebtoken:jjwt-api:0.12.3") runtimeOnly("io.jsonwebtoken:jjwt-impl:0.12.3") runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.12.3")}Creemos una clase utilitaria para trabajar con JWT:
import io.jsonwebtoken.*import io.jsonwebtoken.security.Keysimport org.springframework.stereotype.Componentimport java.security.Keyimport java.util.*
@Componentclass JwtUtil { private val secretKey: Key = Keys.secretKeyFor(SignatureAlgorithm.HS256) private val expirationMs: Long = 3600000 // 1 hora
fun generateToken(username: String): String { return Jwts.builder() .subject(username) .issuedAt(Date()) .expiration(Date(System.currentTimeMillis() + expirationMs)) .signWith(secretKey) .compact() }
fun extractUsername(token: String): String? { return try { Jwts.parser().verifyWith(secretKey).build() .parseSignedClaims(token).payload.subject } catch (e: Exception) { null } }
fun validateToken(token: String): Boolean { return try { Jwts.parser().verifyWith(secretKey).build() .parseSignedClaims(token) true } catch (e: JwtException) { false } }}Filtro de autenticación para Spring Security
Ahora creemos un filtro que intercepte las solicitudes y verifique el token JWT:
import jakarta.servlet.FilterChainimport jakarta.servlet.http.HttpServletRequestimport jakarta.servlet.http.HttpServletResponseimport org.springframework.security.authentication.UsernamePasswordAuthenticationTokenimport org.springframework.security.core.context.SecurityContextHolderimport org.springframework.security.web.authentication.WebAuthenticationDetailsSourceimport org.springframework.stereotype.Componentimport org.springframework.web.filter.OncePerRequestFilter
@Componentclass JwtAuthFilter( private val jwtUtil: JwtUtil, private val userDetailsService: org.springframework.security.core.userdetails.UserDetailsService) : OncePerRequestFilter() {
override fun doFilterInternal( request: HttpServletRequest, response: HttpServletResponse, chain: FilterChain ) { val authHeader = request.getHeader("Authorization") if (authHeader == null || !authHeader.startsWith("Bearer ")) { chain.doFilter(request, re También en la biblioteca
EventKit Swift: guía completa con ejemplos prácticos
Axios para JavaScript (Node.js): guía completa con ejemplos
Generación de Swagger/OpenAPI para C++: revisión de herramientas y bibliotecas
Generación de códigos QR en Node.js: biblioteca qrcode y ejemplos