Firstly, let’s prepare the work
Dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
WebSecurityConfig.java
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/login_error_handler").permitAll()
.anyRequest().authenticated()
.and()
// use the login page
.formLogin()
// use customized login page
// can only use this name
.loginPage("/login")
// everyone can visit the /login
.permitAll()
// 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")
// 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")
.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");
}
});
}
@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
@Configuration
public class WebMVCConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/home").setViewName("home");
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");
}
}
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_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_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_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_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_handler.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
Login Error Handler
</body>
</html>
templates/home.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
Home (protected)
</body>
</html>
templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
Index (not protected)
</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>
Overview
methods | redirect | extra code | get credential |
---|---|---|---|
Level 1 | |||
defaultSuccessUrl | Yes | ||
failureUrl | Yes | ||
Level 2 | |||
successForwardUrl | Yes | Yes | |
failureForwardUrl | Yes | Yes | |
Level 3 | |||
successHandler | Yes | Yes | Yes |
failureHandler | Yes | Yes | Yes |