Actualmente estoy desarrollando una aplicación web usando Spring (con Spring Security) y Vue.js. He creado algunas aplicaciones web antes, pero son solo para fines escolares, por lo que en su mayoría están incompletas en lo que respecta a la autenticación y autorización. Entonces, como puede ver, no tengo mucha experiencia en lo que respecta a Spring Boot y Spring Security.
Mi proyecto está configurado de la siguiente manera:
carpeta de proyecto
Estaba siguiendo un tutorial para implementar Spring Security y, en este momento, puedo usar el formulario de inicio de sesión incorporado para autenticar a mi usuario con las credenciales que tengo almacenadas en mi base de datos MySQL.
El problema es que no quiero usar esta página de inicio de sesión y quiero crear la mía propia en mi proyecto de interfaz. Lo busqué y puedo cambiar la página de inicio de sesión, pero creo que debe estar en mi carpeta de recursos dentro de las carpetas de mi proyecto de back-end. Sin embargo, mi proyecto no está configurado de esta manera y prefiero no cambiarlo (si es posible). Pensé que solo podía hacer referencia a mi API a través de la URL, pero noté que Spring Security no envía una respuesta HTTP 200 cuando el inicio de sesión es exitoso, sino que envía una respuesta de redirección HTTP 302. He visto soluciones que deshabilitan el formulario de inicio de sesión y luego usan JWT para la autenticación, pero también he visto que no es una buena práctica porque no hay forma de revocar este token.
Así es como se ve mi ApplicationSecurityConfig
@Configuration @EnableWebSecurity public class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter { private final PasswordEncoder passwordEncoder; private final ApplicationUserService applicationUserService; @Autowired public ApplicationSecurityConfig(PasswordEncoder passwordEncoder, ApplicationUserService applicationUserService) { this.passwordEncoder = passwordEncoder; this.applicationUserService = applicationUserService; } @Override protected void configure(HttpSecurity http) throws Exception { http .csrf().disable() .authorizeRequests() .antMatchers("/", "/css/*", "/js/*").permitAll() .anyRequest() .authenticated() .and() .formLogin() .usernameParameter("email") .and() .logout() .logoutUrl("/logout") .logoutRequestMatcher(new AntPathRequestMatcher("/logout", "GET")) .clearAuthentication(true) .invalidateHttpSession(true) .deleteCookies("JSESSIONID", "remember-me") .logoutSuccessUrl("/login"); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .userDetailsService(applicationUserService) .passwordEncoder(passwordEncoder); }}
Entonces, ¿hay alguna manera de crear una página de inicio de sesión externa y usar las funciones de autenticación y autorización de Spring Security?
Hay muchas soluciones para este problema y depende principalmente de cuáles sean sus requisitos y cómo esté estructurando la aplicación, aquí hay un par de escenarios que me vienen a la mente:
Si todo el front-end está construido con Vuejs, entonces probablemente el back-end solo consistirá en una API REST que envía y recibe JSON, en este caso, un mecanismo de autenticación sin estado es lo que funciona mejor, como JSON Web Token (JWT).
En este escenario, el servidor expone un punto final, digamos /auth/login , en el que puede enviar un nombre de usuario y una contraseña y el servidor responderá con un token. Una vez que el frente de Vue tiene un token válido, debe enviarlo como parte del encabezado de la solicitud para cada llamada API subsiguiente que esté bajo autenticación, esto garantizará que el usuario sea quien dice ser y tenga los permisos correctos para acceder a la API.
La forma en que funciona JWT se debe a que se compone de tres partes:
Con esta información, el servidor puede verificar que el usuario tiene un token válido (ha sido generado por el servidor después de un inicio de sesión exitoso y no está caducado) sin necesidad de una sesión.
Para obtener más información sobre JWT, consulte https://jwt.io/ y RFC 7519 , también si necesita una buena implementación de Java, he usado la de Auth0 en el pasado y funciona muy bien.
En algunos casos, tendrá una aplicación mixta cuando parte del frente esté siendo generado por algún motor de plantilla en el servidor y Vuejs administrará algunos en el lado del cliente, y probablemente ya tendrá una autenticación basada en sesiones en marcha. Si ese es el caso, aún puede integrar la autenticación, recuerde que al final el servidor solo envía al cliente una cookie con la ID de sesión almacenada en el servidor, por lo que si envía la cookie con cada solicitud, el servidor reconocerá al usuario. como autenticado y permitir que se llame a la API.
El problema en este caso es que está realizando solicitudes desde diferentes dominios para que la cookie no se propague, puede configurar el paquete web desde el lado de Vue para compilar el proyecto en project-server/src/main/resources/static y servir la página de Spring para que el front-end y el back-end estén bajo el mismo dominio y la cookie debería enviarse con las solicitudes de ajax.
Configuró la autenticación Spring MVC, es para aplicaciones monolíticas Java + algún motor de plantilla como Thymeleaf (no Vue), usa redirecciones. Vue js es para aplicaciones SPA y no tiene ninguna relación con Spring MVC.
Lo más fácil que puede hacer es el mecanismo de autenticación JWT. Solo intente buscar en Google 'Spring JWT', 'Vue JWT', hay suficientes ejemplos.