Seguridad de Spring: Funcionalidad de Olvido de Contrase帽a

    Introducci贸n

    Internet se est谩 orientando cada vez m谩s a los servicios con m谩s negocios y empresas que presentan ofertas que se pueden proporcionar o acceder en l铆nea. Esto requiere que los usuarios creen muchas cuentas en muchas plataformas diferentes para los servicios que obtienen en l铆nea. Dichos servicios van desde compras en l铆nea hasta servicios basados 鈥嬧媏n suscripci贸n, como ofertas de m煤sica y entretenimiento y tambi茅n servicios educativos que incluyen cursos y paquetes de tutoriales.

    Los usuarios de Internet terminan creando muchas cuentas diferentes para diferentes plataformas y no se recomienda usar la misma contrase帽a en todos los servicios. Esto conlleva la carga de recordar m煤ltiples contrase帽as diferentes para m煤ltiples cuentas y, desafortunadamente, algunas se filtran y se olvidan porque, despu茅s de todo, somos humanos.

    Olvidar las contrase帽as es un problema real al que se enfrentan los usuarios y, como desarrolladores de sistemas y plataformas, podemos facilitar a nuestros usuarios la gesti贸n de sus contrase帽as al ofrecer una funcionalidad que les permita restablecer sus contrase帽as de forma segura en caso de que las olviden. Esto ayudar谩 a mejorar la retenci贸n de clientes en nuestra plataforma, ya que pueden estar seguros de que, en caso de que pierdan su contrase帽a, no habr谩n perdido su cuenta.

    En esta publicaci贸n, exploraremos c贸mo Spring Security nos ayuda no solo a proteger nuestras aplicaciones basadas en Spring, sino que tambi茅n ayuda a nuestros usuarios a recuperar sus contrase帽as perdidas de una manera f谩cil y segura.

    Protecci贸n de aplicaciones web con Spring Security

    Spring Security es un marco que es f谩cil de ampliar y personalizar y se centra en la provisi贸n de funciones de autenticaci贸n y control de acceso para aplicaciones basadas en Spring. Maneja la autenticaci贸n y autorizaci贸n y tambi茅n ayuda a proteger las aplicaciones Java contra vulnerabilidades de seguridad y ataques comunes, como la fijaci贸n de sesiones, el secuestro de clics y la falsificaci贸n de solicitudes entre sitios, entre otros.

    Spring Security tambi茅n se puede usar para simplificar las instalaciones de administraci贸n de cuentas en la aplicaci贸n Java Enterprise a trav茅s de caracter铆sticas como la provisi贸n de un marco de autorizaci贸n OAuth2 para permitir que los usuarios usen plataformas de terceros para identificarse en nuestras aplicaciones Java.

    Esto se implementa m谩s com煤nmente a trav茅s del inicio de sesi贸n social, donde podemos usar nuestras cuentas en plataformas como Facebook, Twitter, Google y Github para acceder e identificarnos en otras plataformas.

    OpenID es un protocolo de autenticaci贸n promovido por OpenID Foundation que es descentralizado y est谩ndar, que se puede usar para iniciar sesi贸n en varios sitios web sin tener que crear nuevas contrase帽as. OpenID es compatible con Spring Security y se puede utilizar para facilitar el registro y el acceso a nuestras aplicaciones Java para nuestros usuarios finales.

    En el caso de organizaciones que utilizan el protocolo LDAP (Protocolo ligero de acceso a directorios) como servicio de autenticaci贸n y repositorio central de informaci贸n del usuario, Spring Security proporciona la funcionalidad para integrar LDAP en su aplicaci贸n basada en Spring.

    Esto permitir谩 a los miembros actuales de las organizaciones acceder de forma segura a nuevas aplicaciones con sus credenciales existentes sin tener que crear un nuevo conjunto de credenciales.

    Gesti贸n de contrase帽as en Spring Security

    Hemos visto un subconjunto de la funcionalidad que ofrece Spring Security y hace a煤n m谩s por nuestras contrase帽as. Spring Security toma las credenciales de un usuario y las convierte en un token que se pasa a una AuthenticationManagerinstancia para validar las credenciales. En caso de que la contrase帽a sea incorrecta, Spring Security proporcionar谩 comentarios sobre el error y el proceso no continuar谩 m谩s all谩 de ese punto.

    Despu茅s de la validaci贸n, se establece un contexto de seguridad y ahora el usuario se considera autenticado. El contexto de seguridad tambi茅n define la funci贸n del usuario en el sistema y se puede utilizar para determinar el nivel de acceso permitido, ya sea como administrador o como usuario normal.

    Spring Security utiliza una PasswordEncoderinterfaz para codificar o transformar contrase帽as para facilitar el almacenamiento seguro de las credenciales. Se supone que esta contrase帽a codificada es unidireccional y el proceso de verificaci贸n implica comparar la contrase帽a que el usuario ha proporcionado con la que est谩 almacenada, y si coinciden, los detalles son correctos.

    Para mejorar la seguridad de las contrase帽as de los usuarios, Spring Security permite a los desarrolladores usar funciones unidireccionales (o hashes) para codificar contrase帽as como Bcrypt , Argon2 , Scrypt y PBKDF2 . Estas funciones requieren muchos recursos, pero su prop贸sito es ser unidireccionales y dificultar a los atacantes descifrar y extraer las credenciales de los usuarios.

    Si desea leer m谩s sobre este tema, puede consultar el art铆culo Codificaci贸n de contrase帽a con Spring Security.

    Las pr谩cticas de almacenamiento de contrase帽as seguir谩n cambiando con el tiempo para mejorar la seguridad de los m茅todos actuales y es por esta raz贸n que Spring Security introdujo la DelegatingPasswordEncoderinterfaz en la versi贸n 5.0+.

    Garantiza que la codificaci贸n de contrase帽as utilice los m茅todos recomendados actualmente para el almacenamiento de contrase帽as y permite la actualizaci贸n de las funciones de codificaci贸n en el futuro. Tambi茅n nos permite usar diferentes funciones de codificaci贸n para diferentes contrase帽as y esto se puede distinguir usando un identificador prefijado en la contrase帽a codificada. Por ejemplo, si usamos Bcrypt para codificar nuestras contrase帽as, la salida ser铆a, por ejemplo:

    {bcrypt}$2a$12$rBvYrRneJjT/pmXakMbBg.vA1jUCpEMPE5z2tY3/4kyFw.KoiZA6C
    

    En ausencia del prefijo de identificaci贸n, se utiliza una funci贸n de codificaci贸n predeterminada.

    As铆 es como Spring maneja las contrase帽as y la seguridad en general, pero 驴qu茅 sucede cuando nuestros usuarios olvidan sus credenciales?

    Env铆o de correos electr贸nicos en Spring Boot

    Los sistemas y plataformas utilizan ampliamente los correos electr贸nicos para identificar a los usuarios y tambi茅n para enviarles comunicaciones y promociones. Esto hace que las direcciones de correo electr贸nico sean importantes para la identidad de un usuario de Internet que termina teniendo pocas cuentas de correo electr贸nico para uso personal. Esto significa que la cuenta de correo electr贸nico de un usuario es f谩cil y f谩cilmente accesible para ellos, ya que la usan con frecuencia. El correo electr贸nico es, por tanto, una de las mejores v铆as para ayudar a los usuarios a recuperar sus contrase帽as.

    Para permitir que nuestros usuarios restablezcan sus contrase帽as, nuestra aplicaci贸n basada en Spring deber铆a poder enviar correos electr贸nicos a los usuarios. A trav茅s de estos correos electr贸nicos, podemos proporcionar tokens o enlaces o instrucciones a nuestros usuarios que detallan c贸mo pueden recuperar sus cuentas.

    Java proporciona la biblioteca javax.mail , que tambi茅n se conoce como JavaMail, que podemos usar para enviar correos electr贸nicos a nuestros usuarios cada vez que olvidan sus contrase帽as. La JavaMailbiblioteca nos permite redactar y enviar correos electr贸nicos a trav茅s de varios protocolos, como SMTP (Protocolo simple de transferencia de correo), POP (Protocolo de oficina postal) o IMAP (Protocolo de acceso a mensajes de Internet).

    Nos permite enviar correos electr贸nicos de texto sin formato, as铆 como mensajes que contienen HTML, lo que hace que nuestros correos electr贸nicos sean llamativos y atractivos a la vista. Incluso podemos enviar correos electr贸nicos con archivos adjuntos cuando usamos la JavaMailbiblioteca.

    Si est谩 interesado en obtener m谩s informaci贸n sobre el env铆o de correos electr贸nicos en Java, lo tenemos cubierto.

    Otras bibliotecas que puede usar para enviar correos electr贸nicos en Java incluyen:

    Implementaci贸n

    Reunamos ahora todo lo anterior en un proyecto y ayudemos a nuestros usuarios a recuperar sus contrase帽as con facilidad.

    El objetivo principal de este art铆culo fue brindar orientaci贸n sobre la funcionalidad de restablecimiento de contrase帽a. Antes de que podamos restablecer las contrase帽as, debemos permitir que los usuarios se registren, confirmen sus cuentas por correo electr贸nico e inicien sesi贸n en sus cuentas confirmadas.

    El art铆culo Spring Security: Registro de verificaci贸n de correo electr贸nico cubre el registro de usuario y la confirmaci贸n de cuentas a trav茅s de un token enviado al correo electr贸nico del usuario. Con el 谩nimo de mantener este art铆culo centrado en la funcionalidad de restablecimiento de contrase帽a, bifurcaremos y ampliaremos este proyecto en GitHub que se basa en ese art铆culo y agregaremos nuestra nueva funcionalidad que incluye la funcionalidad de inicio de sesi贸n y restablecimiento de contrase帽a.

    Resumen

    El proyecto utiliza el marco Spring junto con Spring Security junto con Thymeleaf como motor de plantillas del lado del servidor. Hibernate se usa para interactuar con una base de datos MySQL para guardar los detalles de los usuarios.

    Un usuario accede al sistema e inmediatamente se le solicita que se registre proporcionando sus detalles, incluidos sus nombres, direcci贸n de correo electr贸nico para verificaci贸n y una contrase帽a. En las siguientes secciones, comenzaremos desde all铆 y agregaremos la funcionalidad de inicio de sesi贸n primero, luego agregaremos la funcionalidad de restablecimiento de contrase帽a para ayudar a nuestros usuarios a restablecer sus contrase帽as.

    Cambios y adiciones

    Hay algunas cosas que cambiaremos en este proyecto y las destacar茅 a medida que avancemos. Primero, actualizaremos la versi贸n Spring de 1.5.4a 2.1.4.RELEASEen nuestro pom.xml. Tambi茅n actualizaremos la versi贸n del conector MySQL a la versi贸n 8.0.13para que el proyecto se ejecute sin problemas con la versi贸n Spring actualizada.

    Si bien la versi贸n anterior a煤n funciona, la actualizaci贸n de las dependencias garantiza que podamos aprovechar la nueva funcionalidad que se ha introducido en la versi贸n posterior. Adem谩s, algunos problemas que podr铆amos enfrentar se eliminar谩n mediante el uso de paquetes actualizados.

    Necesitaremos configurar nuestra base de datos local y actualizar el applications.propertiesarchivo para que se adapte a nuestra nueva configuraci贸n. Tambi茅n necesitaremos actualizar la configuraci贸n del correo electr贸nico para facilitar el env铆o de correos electr贸nicos:

    # add these new properties
    spring.mail.transport.protocol=smtp
    spring.mail.from.email=<your-email-goes-here>
    
    # modify these properties with your credentials
    spring.mail.username=<your-email-goes-here>
    spring.mail.password=<password-goes-here>
    
    # update our database configuration
    spring.datasource.url=jdbc:mysql://localhost:3306/demodb?allowPublicKeyRetrieval=true&useSSL=false
    spring.datasource.username=<database-username>
    spring.datasource.password=<database-password>
    

    Con esta configuraci贸n modificada, podemos ejecutar el proyecto y registrarnos como nuevos usuarios. El correo electr贸nico proporcionado en application.propertiesaparecer谩 como el remitente del correo electr贸nico que contiene el token de confirmaci贸n.

    Funcionalidad de inicio de sesi贸n

    Podemos registrarnos y confirmar nuestra cuenta por correo electr贸nico en este momento. Antes de que podamos restablecer nuestras contrase帽as, deber铆amos poder iniciar sesi贸n, y cuando olvidemos nuestra contrase帽a, deber铆amos poder restablecerla. Para implementar la funcionalidad de inicio de sesi贸n, comenzaremos creando las plantillas, luego la vista en el controlador.

    Nuestra p谩gina de inicio de sesi贸n tendr谩 campos para el correo electr贸nico y la contrase帽a, y una secci贸n oculta para mostrar cualquier mensaje cuando sea necesario. Dichos mensajes pueden incluir notificar al usuario cuando proporciona credenciales no v谩lidas o cuando el usuario no existe en el sistema. Tambi茅n crearemos una plantilla adicional que se mostrar谩 al iniciar sesi贸n correctamente, que servir谩 como nuestra p谩gina de inicio.

    En nuestra carpeta de plantillas, agregamos la p谩gina de inicio de sesi贸n:

    <!DOCTYPE html>
    <html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
        <head> <title>Login</title> </head>
        <body>
            <center> <span th:text="${message}"></span> <br/> </center>
            <center>
                <form action="#" th:action="@{/login}" th:object="${user}" method="post">
                    <table>
                        <tr>
                            <td><label for="emailId">Email</label></td>
                            <td><input th:field="*{emailId}" type="text" name="emailId"></input></td>
                        </tr>
                        <tr>
                            <td><label for="password">Password</label></td>
                            <td><input th:field="*{password}" type="password" name="password"></input></td>
                        </tr>
                        <tr>
                            <td><input type="reset" value="Clear"/></td>
                            <td><input type="submit" value="Submit"></input></td>
                        </tr>
                    </table>
                </form>
    
                <a href="/forgot-password">Forgot Password?</a>
            </center>
        </body>
    </html>
    

    Este es un formulario que toma una direcci贸n de correo electr贸nico y una contrase帽a y env铆a esa informaci贸n a nuestro controlador en el /loginpunto final para su verificaci贸n. Tambi茅n hay un Forgot Password?enlace, que implementaremos m谩s adelante.

    Despu茅s de iniciar sesi贸n correctamente, notificamos al usuario y lo redirigimos a la p谩gina de inicio, que en nuestro caso ser谩 simplemente successLogin.html:

    <!DOCTYPE html>
    <html lang="en" xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
        <head> <title>Login Success</title> </head>
        <body>
            <center> <span th:text="${message}"></span> </center>
        </body>
    </html>
    

    Extendamos nuestro UserAccountControllerque se encuentra en la controllercarpeta para incluir la funcionalidad de inicio de sesi贸n.

    Primero, importaremos la BCryptPasswordEncoderclase para codificar nuestras contrase帽as y crearemos una instancia para encriptar y comparar nuestras contrase帽as. Inicialmente, el proyecto guard贸 las contrase帽as sin procesar en la base de datos, lo modificaremos para tener las contrase帽as encriptadas cuando el usuario se registre, ya que guardar las contrase帽as sin procesar no es una buena pr谩ctica.

    Para la funcionalidad de inicio de sesi贸n, implementaremos una funci贸n para mostrar la p谩gina con el formulario de inicio de sesi贸n y otra funci贸n para recibir las credenciales, verificarlas y notificar cualquier problema o llevar al usuario a la p谩gina siguiente si se ha realizado correctamente. Si el correo electr贸nico proporcionado no existe en nuestra base de datos, tambi茅n se lo notificaremos al usuario.

    BCryptPasswordEncoderproporciona la matches(rawPassword, encodedPassword)funci贸n que nos ayuda a comparar la contrase帽a proporcionada con la que tenemos en los registros. Usamos este m茅todo en lugar de codificar la contrase帽a sin procesar y comparar, ya que cada vez se usa una sal diferente y una comparaci贸n directa fallar铆a todo el tiempo.

    Primero agregamos la nueva importaci贸n:

    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    

    Y luego incluye estos cambios:

        // Instantiate our encoder
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(12);
    
        // Right before saving the user on registration, we encode the password
        user.setPassword(encoder.encode(user.getPassword()));
        userRepository.save(user);
    
        // Function to display login page
        @RequestMapping(value="/login", method=RequestMethod.GET)
        public ModelAndView displayLogin(ModelAndView modelAndView, User user) {
            modelAndView.addObject("user", user);
            modelAndView.setViewName("login");
            return modelAndView;
        }
    
        // Function to handle the login process
        @RequestMapping(value="/login", method=RequestMethod.POST)
        public ModelAndView loginUser(ModelAndView modelAndView, User user) {
            User existingUser = userRepository.findByEmailIdIgnoreCase(user.getEmailId());
            if (existingUser != null) {
                // Use encoder.matches to compare raw password with encrypted password
    
                if (encoder.matches(user.getPassword(), existingUser.getPassword())){
                    // Successfully logged in
                    modelAndView.addObject("message", "Successfully logged in!");
                    modelAndView.setViewName("successLogin");
                } else {
                    // Wrong password
                    modelAndView.addObject("message", "Incorrect password. Try again.");
                    modelAndView.setViewName("login");
                }
            } else {
                modelAndView.addObject("message", "The email provided does not exist!");
                modelAndView.setViewName("login");
            }
            return modelAndView;
        }
    

    Cuando ejecutamos nuestro proyecto, esta es la p谩gina resultante cuando navegamos hasta el /loginpunto final:

    Si las credenciales son incorrectas, se muestra un mensaje con el error en la parte superior del formulario y, si son v谩lidas, se redirige al usuario a una p谩gina que muestra un mensaje de 茅xito.

    Ahora nuestro usuario puede iniciar sesi贸n con sus credenciales, pero 驴qu茅 pasa cuando las olvida? El Forgot Password?enlace viene al rescate.

    Funcionalidad de contrase帽a olvidada

    Cuando un usuario olvida su contrase帽a, puede solicitar que se restablezca haciendo clic en el Forgot Password?enlace. Se le pedir谩 al usuario que proporcione la direcci贸n de correo electr贸nico con la que se registr贸 y se generar谩 un token y se enviar谩 a la direcci贸n de correo electr贸nico como parte del enlace.

    Una vez que el usuario haga clic en el enlace de restablecimiento, validaremos el token y redirigiremos al usuario a una p谩gina donde puede ingresar una nueva contrase帽a para su cuenta. Ahora guardaremos esta nueva contrase帽a despu茅s de haber confirmado que el usuario tiene acceso a la direcci贸n de correo electr贸nico que proporcion贸. Ahora podr谩n iniciar sesi贸n con las credenciales actualizadas.

    Crearemos la plantilla de contrase帽a olvidada donde el usuario ingresar谩 su direcci贸n de correo electr贸nico a trav茅s de la forgotPassword.htmlplantilla:

    <!DOCTYPE html>
    <html lang="en" xmlns="http://www.w3.org/1999/xhtml"
     xmlns:th="http://www.thymeleaf.org">
        <head> <title>Forgot Password</title> </head>
        <body>
            <center>
                <form action="#" th:action="@{/forgot-password}" th:object="${user}" method="post">
                    <table>
                        <tr>
                            <td><label for="emailId">Email</label></td>
                            <td><input th:field="*{emailId}" type="text" name="emailId"></input></td>
                        </tr>
                        <tr>
                            <td><input type="reset" value="Clear"/></td>
                            <td><input type="submit" value="Reset Password"></input></td>
                        </tr>
                    </table>
                </form>
            </center>
        </body>
    </html>
    

    Crearemos una successForgotPassword.htmlplantilla adicional para mostrar el mensaje de 茅xito cuando la contrase帽a se haya restablecido correctamente y est茅 presente en la base de c贸digo completa vinculada a continuaci贸n.

    Con la plantilla en su lugar, perm铆tanos actualizar nuestra UserAccountControllerpara manejar esta nueva funcionalidad. Tendremos una funci贸n para mostrar el formulario, y otra para recibir el correo electr贸nico, crear un token y enviar un correo electr贸nico al usuario con el enlace para restablecer la contrase帽a del usuario.

    Las adiciones a nuestro controlador incluyen:

        // Display the form
        @RequestMapping(value="/forgot-password", method=RequestMethod.GET)
        public ModelAndView displayResetPassword(ModelAndView modelAndView, User user) {
            modelAndView.addObject("user", user);
            modelAndView.setViewName("forgotPassword");
            return modelAndView;
        }
    
        // Receive the address and send an email
        @RequestMapping(value="/forgot-password", method=RequestMethod.POST)
        public ModelAndView forgotUserPassword(ModelAndView modelAndView, User user) {
            User existingUser = userRepository.findByEmailIdIgnoreCase(user.getEmailId());
            if (existingUser != null) {
                // Create token
                ConfirmationToken confirmationToken = new ConfirmationToken(existingUser);
    
                // Save it
                confirmationTokenRepository.save(confirmationToken);
    
                // Create the email
                SimpleMailMessage mailMessage = new SimpleMailMessage();
                mailMessage.setTo(existingUser.getEmailId());
                mailMessage.setSubject("Complete Password Reset!");
                mailMessage.setFrom("[email聽protected]");
                mailMessage.setText("To complete the password reset process, please click here: "
                  + "http://localhost:8082/confirm-reset?token="+confirmationToken.getConfirmationToken());
    
                // Send the email
                emailSenderService.sendEmail(mailMessage);
    
                modelAndView.addObject("message", "Request to reset password received. Check your inbox for the reset link.");
                modelAndView.setViewName("successForgotPassword");
    
            } else {
                modelAndView.addObject("message", "This email address does not exist!");
                modelAndView.setViewName("error");
            }
            return modelAndView;
        }
    

    Ahora podemos empaquetar y ejecutar nuestro proyecto nuevamente usando el mvn spring-boot:runcomando. Cuando hacemos clic en el Forgot Password?enlace, podemos ver un formulario con un campo de correo electr贸nico. Cuando completamos nuestra direcci贸n de correo electr贸nico registrada, recibimos el siguiente correo electr贸nico:

    Hasta ahora, hemos podido recibir una solicitud de restablecimiento de contrase帽a y hemos enviado un correo electr贸nico al usuario con un enlace para restablecer su contrase帽a.

    Para implementar la siguiente parte de la funcionalidad de restablecimiento de contrase帽a, necesitaremos crear una plantilla que reciba la nueva contrase帽a del usuario. Se parecer谩 a la p谩gina de inicio de sesi贸n, la 煤nica diferencia importante es que el campo de correo electr贸nico ser谩 de solo lectura.

    La nueva plantilla resetPassword:

    <!DOCTYPE html>
    <html lang="en" xmlns="http://www.w3.org/1999/xhtml"
     xmlns:th="http://www.thymeleaf.org">
        <head> <title>Reset Password</title> </head>
        <body>
            <center>
                <h2>Enter new password:</h2>
                <form action="#" th:action="@{/reset-password}" th:object="${user}" method="post">
                    <table>
                        <tr>
                            <td><label for="emailId">Email</label></td>
                            <td><input th:field="*{emailId}" type="text" name="emailId" readonly></input></td>
                        </tr>
                        <tr>
                            <td><label for="password">Password</label></td>
                            <td><input th:field="*{password}" type="password" name="password"></input></td>
                        </tr>
                        <tr>
                            <td><input type="reset" value="Clear"/></td>
                            <td><input type="submit" value="Submit"></input></td>
                        </tr>
                    </table>
                </form>
            </center>
        </body>
    </html>
    

    Prellenaremos la direcci贸n de correo electr贸nico del usuario en un campo de solo lectura y luego dejaremos que el usuario ingrese su nueva contrase帽a.

    En este punto, se introducir谩n dos nuevos puntos finales:

    • /confirm-reset: maneja la verificaci贸n del token y, en caso de 茅xito, redirigir谩 al usuario al siguiente punto final
    • /reset-password: muestra el formulario anterior, recibe las nuevas credenciales y las actualiza en la base de datos

    Agreguemos estos nuevos puntos finales en nuestro controlador de la siguiente manera:

        // Endpoint to confirm the token
        @RequestMapping(value="/confirm-reset", method= {RequestMethod.GET, RequestMethod.POST})
        public ModelAndView validateResetToken(ModelAndView modelAndView, @RequestParam("token")String confirmationToken) {
            ConfirmationToken token = confirmationTokenRepository.findByConfirmationToken(confirmationToken);
    
            if (token != null) {
                User user = userRepository.findByEmailIdIgnoreCase(token.getUser().getEmailId());
                user.setEnabled(true);
                userRepository.save(user);
                modelAndView.addObject("user", user);
                modelAndView.addObject("emailId", user.getEmailId());
                modelAndView.setViewName("resetPassword");
            } else {
                modelAndView.addObject("message", "The link is invalid or broken!");
                modelAndView.setViewName("error");
            }
            return modelAndView;
        }
    
        // Endpoint to update a user's password
        @RequestMapping(value = "/reset-password", method = RequestMethod.POST)
        public ModelAndView resetUserPassword(ModelAndView modelAndView, User user) {
            if (user.getEmailId() != null) {
                // Use email to find user
                User tokenUser = userRepository.findByEmailIdIgnoreCase(user.getEmailId());
                tokenUser.setPassword(encoder.encode(user.getPassword()));
                userRepository.save(tokenUser);
                modelAndView.addObject("message", "Password successfully reset. You can now log in with the new credentials.");
                modelAndView.setViewName("successResetPassword");
            } else {
                modelAndView.addObject("message","The link is invalid or broken!");
                modelAndView.setViewName("error");
            }
            return modelAndView;
        }
    

    Con estos nuevos cambios, podemos ejecutar el proyecto y hacer clic en el enlace que ven铆a en el correo electr贸nico para restablecer la contrase帽a que se envi贸 anteriormente. El resultado es:

    Cuando ingresamos nuestra nueva contrase帽a, recibimos un mensaje de 茅xito. Nuestra contrase帽a se ha actualizado y podemos probar esta nueva contrase帽a navegando a la p谩gina de inicio de sesi贸n e iniciando sesi贸n con las nuevas credenciales.

    隆Funciona! Nuestros usuarios ahora pueden restablecer sus contrase帽as olvidadas a trav茅s de enlaces enviados a su direcci贸n de correo electr贸nico desde nuestra aplicaci贸n web Spring Boot.

    Conclusi贸n

    Hemos aprendido de las diversas formas en que Spring Security puede proporcionar funciones de autenticaci贸n y control de acceso para ayudarnos a proteger nuestras aplicaciones basadas en Spring de una manera f谩cilmente extensible y personalizable.

    Tambi茅n hemos entendido c贸mo Spring Security maneja las contrase帽as de nuestros usuarios a trav茅s de varios algoritmos para codificar y almacenar de forma segura la contrase帽a de manera que sea indescifrable para un atacante. Destacamos brevemente c贸mo podemos enviar correos electr贸nicos en Spring y, en nuestro caso, usamos este conocimiento para enviar correos electr贸nicos para confirmar las cuentas de nuestros usuarios cuando se est谩n registrando y tambi茅n recuperando su cuenta. Esta funcionalidad de correo electr贸nico tambi茅n se puede utilizar para enviar notificaciones de inicio de sesi贸n o marcar actividades sospechosas en las cuentas de los usuarios.

    Finalmente, ampliamos un proyecto de registro de correo electr贸nico de Spring agregando la funcionalidad de inicio de sesi贸n y restablecimiento de contrase帽a para ayudar a nuestros usuarios en caso de que no puedan recordar sus credenciales.

    La base de c贸digo completa y final de este proyecto est谩 disponible aqu铆 en Github .

     

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *