Estoy trabajando en una aplicación web simple con fines de aprendizaje usando Angular para el frontend y Java Spring para el backend. No tengo un problema en particular con el que quiero que me ayuden, en cambio, tengo una pregunta sobre la autenticación OAuth2.
He registrado mi Angular SPA en Azure AD (Authorization Code Flow + PKCE), configuré roles y todo funciona bien. Mi pregunta es ¿qué hago cuando los usuarios autenticados hacen ping a mi backend? Mi backend no tiene información sobre los usuarios.
Pensé en una solución para hacer un filtro web, y cada vez que un usuario autenticado hace ping a cualquier punto final que requiera que el usuario esté autenticado, verifique la base de datos si el usuario existe (a través del nombre de usuario) y guárdelo si no existe. Estoy bastante seguro de que esto funcionará, pero no creo que esta sea la mejor solución, considerando que mi filtro web tendrá que leer de las bases de datos para cada solicitud HTTP que ingrese, y escribir en la base de datos ocasionalmente (si el usuario inicia sesión por primera vez).
No debería preocuparme por los problemas de rendimiento porque estoy construyendo esto estrictamente con fines de aprendizaje, pero, sin embargo, quiero hacerlo de la manera correcta. Intenté buscar esto en Google de varias maneras, pero supongo que no estoy usando las palabras clave correctas para encontrar lo que estoy buscando. ¡Cualquier opinión o consejo sería muy apreciado! ¡Gracias!
EDITAR: Seguí este artículo para lograr la autenticación y autorización OAuth2 + OIDC, mi configuración de seguridad en el backend es la misma: https://ordina-jworks.github.io/security/2020/08/18/Secure-Applications- Azure-AD.html
Publique la discusión con claridad sobre los requisitos. Si quieres usar tienes lo siguiente:
Con el requisito de no acceder siempre a su base de datos, una opción es utilizar un caché.
La solución ideal para que este caché funcione es:
Ejemplo:
Implementar un CacheService.java
package com.example.springboot; import java.util.Collections; import org.apache.catalina.User; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.concurrent.ConcurrentMapCache; import org.springframework.cache.support.SimpleCacheManager; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; @Component public class CacheService { @Bean public CacheManager cacheManager() { SimpleCacheManager cacheManager = new SimpleCacheManager(); cacheManager.setCaches(Collections.singletonList(new ConcurrentMapCache("users"))); return cacheManager; } @Cacheable(cacheNames = "users") public User getUser(String username) { // Code below will not execute after the first calling for the given username. // So if one username is already cached, it would not invoke for the same user again from the DB. // Get or Create a new user based on the Database call return null; } }Luego implemente un filtro web como:
package com.example.springboot; import java.io.IOException; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.filter.GenericFilterBean; @Component public class CredentialsInjectionFilter extends GenericFilterBean { @Autowired private CacheService cacheService; @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { cacheService.getUser("my_username"); filterChain.doFilter(servletRequest, servletResponse); } }Más información sobre almacenamiento en caché con Springboot: https://www.javadevjournal.com/spring/spring-caching/