Home > AI > Backend > SpringBoot > spring-boot-starter-security >

Customized the logout

Usually, the log out button looks like this

<form th:action="@{/logout}" method="post">
    <input type="submit" value="Logout" />
</form>

Logout URL:

By default, the logout url is /logout, you can customized by this way.

WebSecurityConfig.java

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                    .antMatchers("/", "/login_error_handler").permitAll()
                    .anyRequest().authenticated()



                .and()
                    .logout()
                    .logoutUrl("/logout_my");


               ;



    }

templates/logout_my.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
Logout
</body>
</html>

templates/home.html

<!DOCTYPE html>
<html xmlns:th="http:/www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
Home (protected)


<form th:action="@{/logout_my}" method="post">
    <input type="submit" value="Logout" />
</form>


</body>
</html>

WebMVCConfig.java

@Configuration
public class WebMVCConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {

        registry.addViewController("/").setViewName("index");
        registry.addViewController("/home").setViewName("home");


        // logout
        registry.addViewController("/logout_my").setViewName("logout_my");


    }


}

The original /logout endpoint will be unattached. If you visit it, it will have error (whitelabel page or direct you to the customized error page)

Logout successful page

Default is login page

.logoutSuccessUrl("/logout_success")

The complete the codes are here for Form Authentication

Dependencies

WebSecurityConfig.java

package com.example.demo10;

/**
 * Created by TUTEHUB on 2022/1/25 3:23 PM.
 * Copyright © 2022 TUTEHUB. All rights reserved.
 * ------------------------
 * Non-disclosure Terms
 * -------------------------
 * These codes are TUTEHUB's property, as the developer, such as employee, contractor, and intern, working for TUTEHUB cannot disclose, spread, copy, preserve, sell, and do other activities without the consent of TUTEHUB.
 * Developer dph agrees with above terms.
 * Technique Support: jobyme88.com
 * Contact: noreply@fengcaoculture.com
 */


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

import static org.springframework.security.config.Customizer.withDefaults;

/**
 * @description
 */
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                    .antMatchers("/", "/login_error_handler", "/logout_success", "/logout_success_handler").permitAll()
                    .anyRequest().authenticated()


                /**
                 * Login
                 */
                .and()
                    // use the login page
                    .formLogin()
                    // use customized login page
                    // can only use this name
                    .loginPage("/login")
                    // everyone can visit the /login
                    .permitAll()

                    /**
                     * Level 1
                     */
                    // if login successfully
                    // for unsecured endpoint
                    // will be directed here
                    // the endpoint is mapped in WebMVCConfig
                    .defaultSuccessUrl("/login_success")
                    // if login failed
                    // replace default /login?error
                    // the endpoint is mapped in WebMVCConfig
                    .failureUrl("/login_error")



                    /**
                     * Level 2
                     */
                    // if login successfully
                    // execute some extra code
                    // the endpoint is mapped in @Controller
                    // will override .defaultSuccessUrl
                    .successForwardUrl("/login_success_forward")
                    // if login failed
                    // execute some extra code
                    // the endpoint is mapped in @Controller
                    // will override .failureUrl
                    .failureForwardUrl("/login_error_forward")




                    /**
                     * Level 3
                     */
                    .successHandler(new AuthenticationSuccessHandler() {

                        @Override
                        public void onAuthenticationSuccess(HttpServletRequest request,
                                                            HttpServletResponse response,
                                                            Authentication authentication) throws IOException, ServletException {

                            System.out.println("[shark] Logged user: " + authentication.getName());

                            response.sendRedirect("/login_success_handler");
                        }
                    })

                    .failureHandler(new AuthenticationFailureHandler() {

                        @Override
                        public void onAuthenticationFailure(HttpServletRequest request,
                                                            HttpServletResponse response,
                                                            AuthenticationException exception) throws IOException, ServletException {
                            System.out.println("[shark] Login failed");
                            System.out.println(exception);

                            // needs to open visit
                            response.sendRedirect("/login_error_handler");
                        }
                    })




                /**
                 * Logout
                 */
                .and()
                    // open the /logout page
                    // GET /logout
                    // otherwise you will see error when you type /logout in the browser
                    .logout()
                    // By default, the logout endpoint is /logout
                    // customized this endpoint
                    .logoutUrl("/logout_my")
                    // Default is login page
                    // needs to be opened, otherwise you need to login
                    /**
                     * Level 1
                     */
                    .logoutSuccessUrl("/logout_success")
                    /**
                     * Level 2
                     */
                    .logoutSuccessHandler(new LogoutSuccessHandler() {
                        @Override
                        public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
                                                    Authentication authentication)
                                throws IOException, ServletException {

                            System.out.println("[shark] This user logged out: " + authentication.getName());

                            response.sendRedirect("/logout_success_handler");
                        }
                    })
            ;


               ;



    }







    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .passwordEncoder(passwordEncoder())
                .withUser("user")
                .password(passwordEncoder().encode("user"))
                .roles("USER");
    }



}

WebMVCConfig.java

package com.example.demo10;/**
 * Created by TUTEHUB on 2022/2/5 6:56 PM.
 * Copyright © 2022 TUTEHUB. All rights reserved.
 * ------------------------
 * Non-disclosure Terms
 * -------------------------
 * These codes are TUTEHUB's property, as the developer, such as employee, contractor, and intern, working for TUTEHUB cannot disclose, spread, copy, preserve, sell, and do other activities without the consent of TUTEHUB.
 * Developer dph agrees with above terms.
 * Technique Support: jobyme88.com
 * Contact: noreply@fengcaoculture.com
 */


import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @description
 */
@Configuration
public class WebMVCConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {

        registry.addViewController("/").setViewName("index");
        registry.addViewController("/home").setViewName("home");

        // login
        registry.addViewController("/login").setViewName("login");
        registry.addViewController("/login_success").setViewName("login_success");
        registry.addViewController("/login_error").setViewName("login_error");


        registry.addViewController("/login_success_handler").setViewName("login_success_handler");
        registry.addViewController("/login_error_handler").setViewName("login_error_handler");





        // logout
        registry.addViewController("/logout_my").setViewName("logout_my");
        registry.addViewController("/logout_success").setViewName("logout_success");
        registry.addViewController("/logout_success_handler").setViewName("logout_success_handler");




    }


}

WebController.java

package com.example.demo10;/**
 * Created by TUTEHUB on 2022/2/6 10:01 AM.
 * Copyright © 2022 TUTEHUB. All rights reserved.
 * ------------------------
 * Non-disclosure Terms
 * -------------------------
 * These codes are TUTEHUB's property, as the developer, such as employee, contractor, and intern, working for TUTEHUB cannot disclose, spread, copy, preserve, sell, and do other activities without the consent of TUTEHUB.
 * Developer dph agrees with above terms.
 * Technique Support: jobyme88.com
 * Contact: noreply@fengcaoculture.com
 */


import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;

/**
 * @description
 */
@Controller
public class WebController {

    @PostMapping("/login_success_forward")
    public String loginSuccessHandler() {
        System.out.println("[shark] Logging user login success...");
        return "login_success_forward";
    }



    @PostMapping("/login_error_forward")
    public String loginFailureHandler() {
        System.out.println("[shark] Login failure handler....");

        return "login_error_forward";
    }
}

templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
Index (not protected)
</body>
</html>

templates/home.html

<!DOCTYPE html>
<html xmlns:th="http:/www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
Home (protected)


<form th:action="@{/logout_my}" method="post">
    <input type="submit" value="Logout" />
</form>


</body>
</html>

templates/error.html

<!DOCTYPE html>
<html>
<head>
    <title>Error occurred</title>
</head>
<body>
<h1>Error occurred</h1>

<p>
    An error has occurred. Please contact the administrator; - template generic
</p>

</body>
</html>

templates/login.html

<!DOCTYPE html>
<html xmlns:th="http:/www.thymeleaf.org">
<head>
    <meta charset="ISO-8859-1">
    <title>Login - Company ABC</title>
</head>
<body>
<div>
    <form th:action="@{/login}" method="post" style="max-width: 400px; margin: 0 auto;">
        <p>
            Username: <input type="text" name="username" required />
        </p>
        <p>
            Password: <input type="password" name="password" required />
        </p>
        <p>
            <input type="submit" value="Login" />
        </p>
    </form>
</div>
</body>
</html>

templates/login_success.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
Login Successfully
</body>
</html>

templates/login_success_forward.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
Login Successfully Forward
</body>
</html>

templates/login_success_handler.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
Login Successfully Handler
</body>
</html>

templates/login_error.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
Oops,you log in wrongly.
</body>
</html>

templates/login_error_forward.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
Login Error Forward
</body>
</html>

templates/login_error_handler.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
Login Error Handler
</body>
</html>

templates/logout_my.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
Logout
</body>
</html>

templates/logout_success.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
Logout successfully
</body>
</html>

templates/logout_success_handler.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
Logout successfully handler
</body>
</html>

The complete github is https://github.com/sharkdeng/spring-login-logout

Leave a Reply