🛡️ Bài 3: Spring Security – Xác thực với Form Login & Quản lý Session
🎯 Mục tiêu bài học:
- Cấu hình Form Login tùy chỉnh
- Tạo một hệ thống xác thực đơn giản với Spring Security
- Hiểu cách quản lý Session sau khi người dùng đăng nhập
🔧 1️⃣ Thêm dependency cần thiết
Nếu bạn dùng Maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
🛠️ 2️⃣ Tạo UserDetailsService
và UserDetails
@Service
//
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
User user = userRepository.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("Không tìm thấy người dùng"));
return new org.springframework.security.core.userdetails.User(
user.getUsername(),
user.getPassword(),
Collections.singleton(new SimpleGrantedAuthority("ROLE_USER"))
);
}
}SimpleGrantedAuthority("ROLE_USER")
= Tạo một quyền (authority) với tên "ROLE_USER". Theo quy ước, Spring Security yêu cầu role phải bắt đầu bằng "ROLE_"
🛡️ 3️⃣ Cấu hình bảo mật (SecurityConfig
)
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Autowired
private CustomUserDetailsService userDetailsService;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/login", "/css/**").permitAll()
.anyRequest().authenticated()
)
.formLogin(form -> form
.loginPage("/login") // Trang login tùy chỉnh
.defaultSuccessUrl("/home") // Sau khi đăng nhập thành công
.permitAll()
)
.logout(logout -> logout
.logoutUrl("/logout")
.logoutSuccessUrl("/login?logout")
.invalidateHttpSession(true)
.clearAuthentication(true)
.permitAll()
)
.sessionManagement(session -> session
.invalidSessionUrl("/login?expired")
.maximumSessions(1)
.expiredUrl("/login?expired")
);
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
💾 4️⃣ Tạo login.html
(Thymeleaf hoặc HTML thường)
<!DOCTYPE html>
<html>
<head><title>Login</title></head>
<body>
<form th:action="@{/login}" method="post">
<label>Username:</label><input type="text" name="username" /><br/>
<label>Password:</label><input type="password" name="password" /><br/>
<button type="submit">Login</button>
</form>
<p th:if="${param.error}">Sai tên đăng nhập hoặc mật khẩu!</p>
<p th:if="${param.logout}">Bạn đã đăng xuất.</p>
</body>
</html>
🧠 5️⃣ Session hoạt động như thế nào?
- Mỗi người dùng khi đăng nhập thành công sẽ có một session (HttpSession)
- Session giúp lưu thông tin người dùng → tránh phải login mỗi lần
- Spring quản lý session thông qua
SecurityContextHolder
✅ Kết quả
- Bạn có thể truy cập
/login
để đăng nhập. - Sau khi login, chuyển đến
/home
. - Nếu chưa đăng nhập mà truy cập
/home
, sẽ bị chuyển đến/login
. - Hết phiên (session timeout), bạn phải đăng nhập lại.