CyStack logo
  • Sản phẩm & Dịch vụ
  • Giải pháp
  • Bảng giá
  • Công ty
  • Tài liệu
Vi

vi

Mục lục

Trang chủBlogĐăng nhập và đăng xuất vớ...
Java

Đăng nhập và đăng xuất với Spring Security

8 phút đọc07/07/2025
CyStack Author
Bao Tran

Web Developer

0 lượt xem
Reading Time: 8 minutes

Hôm nay, chúng ta sẽ tìm hiểu về đăng nhập và đăng xuất với Spring Security. Trước khi làm theo ví dụ này, đầu tiên bạn nên xem qua bài viết trước của chúng tôi về framework này để nắm được các kiến thức cơ bản.

Đăng nhập và đăng xuất với Spring security

Ví dụ về đăng nhập và đăng xuất với Spring Security

Trong bài viết này, chúng ta sẽ phát triển một ứng dụng web Spring 4 MVC Security với tính năng đăng nhập và đăng xuất bằng cách sử dụng tùy chọn In-Memory. Ví dụ này sử dụng Spring Java Config cùng với các Spring Annotation. Điều này có nghĩa là ta sẽ không cần dùng đến file web.xml và cấu hình Spring bằng XML như cách cũ.

Spring 4 Security Module hỗ trợ các tùy chọn sau để lưu trữ và quản lý thông tin xác thực người dùng (user credential):

  1. In-Memory Store (lưu trữ trong bộ nhớ)
  2. Cơ sở dữ liệu quan hệ (RDBMS)
  3. Kho dữ liệu NoSQL
  4. LDAP

Trong ví dụ này, ta sẽ sử dụng tùy chọn In-Memory Store. Các tùy chọn khác sẽ được đề cập trong những bài viết sau. Trong ví dụ này, chúng ta sẽ sử dụng Spring 4.0.2.RELEASE, Spring STS 3.7 Suite IDE, Spring TC Server 3.1 với Java 1.8 và công cụ build Maven.

Ví dụ đăng nhập với Spring Security

Chúng ta sẽ phát triển logic đăng nhập và đăng xuất bằng các tính năng của Spring 4 Security. Mục tiêu chính của ứng dụng này là phát triển một ứng dụng mà không cần sử dụng web.xml và không cần viết một dòng cấu hình Spring Bean bằng XML nào. Điều này có nghĩa là chúng ta sẽ sử dụng tính năng Spring Java Config với các Spring Annotation.

Ứng dụng sẽ có các tính năng sau:

  1. Trang Chào mừng (Welcome Page)
  2. Trang Đăng nhập (Login Page)
  3. Trang Chủ (Home Page)
  4. Tính năng Đăng xuất (Logout)

Hãy làm theo các bước sau để phát triển và tìm hiểu tính năng đăng nhập đơn giản trong Spring 4 Security.

Tạo một project “Simple Spring Web Maven” trong Spring STS Suite với các thông tin sau

Project Name : SpringMVCSecruityMavenApp

Cập nhật file pom.xml với nội dung dưới đây




	4.0.0
	com.journaldev
	SpringMVCSecruityMavenApp
	war
	1.0

	
	    1.8
	    4.0.2.RELEASE
	    4.0.2.RELEASE
	    3.1.0
	    2.2
	    1.2
	

	
		
			org.springframework
			spring-core
			${spring.version}
		
		
			org.springframework
			spring-web
			${spring.version}
		
		
			org.springframework
			spring-webmvc
			${spring.version}
		
		
			org.springframework.security
			spring-security-web
			${spring.security.version}
		
		
			org.springframework.security
			spring-security-config
			${spring.security.version}
		
		
			javax.servlet
			javax.servlet-api
			${servlet.api.version}
				
		
			javax.servlet.jsp
			jsp-api
			${jsp.api.version}
		
		
			jstl
			jstl
			${jstl.version}
		
		

	
	    SpringMVCSecruityMavenApp
	    
		
		     org.apache.maven.plugins
		     maven-compiler-plugin
		     3.1
		     
			${java.version}
			${java.version}
		     
		
		
	           org.apache.maven.plugins
	           maven-war-plugin
	           
	              false
	                      
        	
	    
	

LƯU Ý: Nếu bạn không hiểu rõ về cờ , hãy đọc phần cuối của bài viết này để biết cách sử dụng của nó.

Đầu tiên, phát triển Login Controller bằng annotation @Controller của Spring.

File LoginController.java:

package com.journaldev.spring.web.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class LoginController {

	@RequestMapping(value = { "/"}, method = RequestMethod.GET)
	public ModelAndView welcomePage() {
		ModelAndView model = new ModelAndView();
		model.setViewName("welcomePage");
		return model;
	}

	@RequestMapping(value = { "/homePage"}, method = RequestMethod.GET)
	public ModelAndView homePage() {
		ModelAndView model = new ModelAndView();
		model.setViewName("homePage");
		return model;
	}
	
	@RequestMapping(value = "/loginPage", method = RequestMethod.GET)
	public ModelAndView loginPage(@RequestParam(value = "error",required = false) String error,
	@RequestParam(value = "logout",	required = false) String logout) {
		
		ModelAndView model = new ModelAndView();
		if (error != null) {
			model.addObject("error", "Invalid Credentials provided.");
		}

		if (logout != null) {
			model.addObject("message", "Logged out from JournalDEV successfully.");
		}

		model.setViewName("loginPage");
		return model;
	}

}

Ở trên ta đã định nghĩa ba phương thức trong LoginController để xử lý ba loại request khác nhau từ client:

  1. welcomePage() sẽ xử lý tất cả request của client có URI là /.
  2. homePage() sẽ xử lý tất cả request của client có URI là /homePage.
  3. loginPage() sẽ xử lý tất cả request của client có URI là /loginPage.
  4. Trong loginPage(), chúng ta đã xử lý các thông báo lỗi và đăng xuất.
  • Tiếp theo, viết class LoginSecurityConfig để cung cấp các tính năng bảo mật cho việc đăng nhập và đăng xuất với Spring 4 Security API.

File LoginSecurityConfig.java:

package com.journaldev.spring.secuity.config;

import org.springframework.beans.factory.annotation.Autowired;
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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class LoginSecurityConfig extends WebSecurityConfigurerAdapter {

	@Autowired
	public void configureGlobal(AuthenticationManagerBuilder authenticationMgr) throws Exception {
		authenticationMgr.inMemoryAuthentication()
			.withUser("journaldev")
			.password("jd@123")
			.authorities("ROLE_USER");
	}
	
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.authorizeRequests()
			.antMatchers("/homePage").access("hasRole('ROLE_USER')")
			.and()
				.formLogin().loginPage("/loginPage")
				.defaultSuccessUrl("/homePage")
				.failureUrl("/loginPage?error")
				.usernameParameter("username").passwordParameter("password")				
			.and()
				.logout().logoutSuccessUrl("/loginPage?logout"); 
		
	}
}

Chúng ta đã định nghĩa hai phương thức trong LoginSecurityConfig ở file trên để lưu trữ, quản lý thông tin xác thực người dùng và xử lý các tính năng bảo mật đăng nhập và đăng xuất.

  1. Annotation @EnableWebSecurity được dùng để kích hoạt tính năng bảo mật web trong bất kỳ ứng dụng web nào.
  2. Annotation @EnableWebMVCSecurity được dùng để kích hoạt tính năng bảo mật web trong ứng dụng web dựa trên Spring MVC. LƯU Ý: @EnableWebSecurity = @EnableWebMVCSecurity + các tính năng bổ sung. Đó là lý do tại sao Annotation @EnableWebMVCSecurity chuẩn bị bị loại bỏ trong Spring Framework 4.x. Class LoginSecurityConfig (hoặc bất kỳ class nào được chỉ định để cấu hình Spring Security) nên kế thừa từ class WebSecurityConfigurerAdapter hoặc triển khai interface liên quan.
  3. Phương thức configureGlobal() được sử dụng để lưu trữ và quản lý thông tin xác thực người dùng.
  4. Trong phương thức configureGlobal(), ta có thể sử dụng phương thức authorities() để định nghĩa các role của ứng dụng như “ROLE_USER”. Ta cũng có thể sử dụng phương thức roles() cho cùng mục đích.
  5. Sự khác biệt giữa phương thức authorities()roles(): authorities() cần một tên role hoàn chỉnh như “ROLE_USER”, trong khi roles() chỉ cần tên role như “USER”. Nó sẽ tự động thêm tiền tố “ROLE_” vào tên role “USER”. LƯU Ý: Chúng ta sẽ phát triển một ví dụ khác để minh họa các role như “USER”, “ADMIN” trong các bài viết sắp tới.
  6. Phương thức quan trọng để xử lý bảo mật Đăng nhập và Đăng xuất là configure(HttpSecurity http).
  7. Đoạn code sau được sử dụng để ngăn chặn truy cập trái phép vào /homePage. Nếu cố gắng truy cập trang này, bạn sẽ tự động được chuyển hướng đến trang /loginPage.
.antMatchers("/homePage").access("hasRole('ROLE_USER')")

Nếu ta bỏ đi lời gọi phương thức access(“hasRole(‘ROLE_USER’)”), thì ta có thể truy cập trang này mà không cần đăng nhập vào ứng dụng. Chúng ta đã cấu hình các tính năng đăng nhập và đăng xuất bằng các phương thức formLogin()logout().

Kích hoạt cấu hình Spring MVC với file LoginApplicationConfig.java:

package com.journaldev.spring.secuity.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

@EnableWebMvc
@Configuration
@ComponentScan({ "com.journaldev.spring.*" })
@Import(value = { LoginSecurityConfig.class })
public class LoginApplicationConfig {
	@Bean
	public InternalResourceViewResolver viewResolver() {
		InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
		viewResolver.setViewClass(JstlView.class);
		viewResolver.setPrefix("/WEB-INF/views/");
		viewResolver.setSuffix(".jsp");
		return viewResolver;
	}
	
}

Ở đây ta sử dụng class LoginApplicationConfig để định nghĩa các View Resolver (thành phần xác định view nào sẽ render dữ liệu từ controller) của Spring MVC và tránh việc phải viết file web.xml.

  1. Annotation @EnableWebMvc được dùng để kích hoạt các tính năng của ứng dụng Spring Web MVC trong Spring Framework.
  2. Annotation @Import được dùng để import class cấu hình Spring Security vào class này.
  3. Annotation @ComponentScan được dùng để quét các thành phần trong package đã chỉ định. Nó tương đương với trong cấu hình Spring XML.

Khởi tạo Spring Security với đoạn code sau:

package com.journaldev.spring.secuity.config.core;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {

}

SpringSecurityInitializer được dùng để đăng ký springSecurityFilterChain. Điều này giúp không cần phải viết cấu hình Filter trong file web.xml.

Khởi tạo ứng dụng Spring MVC trong file SpringMVCWebAppInitializer.java dưới đây. Class SpringMVCWebAppInitializer được sử dụng để khởi tạo DispatcherServlet mà không cần file web.xml khi cấu hình dựa trên Annotation.

package com.journaldev.spring.secuity.config.core;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import com.journaldev.spring.secuity.config.LoginApplicationConfig;

public class SpringMVCWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

	@Override
	protected Class[] getRootConfigClasses() {
		return new Class[] { LoginApplicationConfig.class };
	}

	@Override
	protected Class[] getServletConfigClasses() {
		return null;
	}

	@Override
	protected String[] getServletMappings() {
		return new String[] { "/" };
	}
	
}

LƯU Ý:

  1. Khi chúng ta truy cập ứng dụng, theo mặc định, phương thức getServletMappings() của SpringMVCWebAppInitializer sẽ cho phép truy cập URL gốc: /. Chúng ta có thể ghi đè phương thức này để chuyển hướng đến một URL khác.
  2. Đội ngũ team Spring (Pivotal) đang xử lý vấn đề này để giảm bớt lượng code Java cần thiết bằng cách giới thiệu một annotation mới.

Tạo file welcomePage.jsp

Welcome to JournalDEV Tutorials

Login to Journal

Tạo file loginPage.jsp

<%@ taglib prefix="c" uri=""%>


	

JournalDEV Tutorials

${error}
${message}
UserName:
Password:

Tạo file homepage.jsp

<%@taglib prefix="c" uri=""%>

Welcome to JournalDEV Tutorials

  • Java 8 tutorial
  • Spring tutorial
  • Gradle tutorial
  • BigData tutorial
Logout

Cấu trúc cuối cùng của project sẽ trông như sau:

Cấu hình ví dụ đăng nhập và đăng xuất với Spring Security

Chạy ví dụ đăng nhập và đăng xuất với Spring Security MVC

Để chạy ứng dụng Spring Web này, chúng ta cần một Web Container bất kỳ hỗ trợ môi trường Spring 4 và Java 8 với Servlet 3.1.0 Container.

Deploy và chạy trên server Spring TC trong Spring STS Suite. Nó sẽ tự động truy cập trang chào mừng như bên dưới.

Ứng dụng ví dụ đăng nhập và đăng xuất với Spring Security

Nhấn vào liên kết Login to JournalDEV để truy cập trang đăng nhập.

Ứng dụng ví dụ đăng nhập và đăng xuất với Spring Security

Bây giờ, hãy thử nhập thông tin đăng nhập sai và nhấn nút Login.

Ứng dụng ví dụ đăng nhập và đăng xuất với Spring Security

Ta sẽ thấy thông báo lỗi: “Invalid Credentials provided.” Nhập lại thông tin đăng nhập chính xác đã được cấu hình trong class LoginSecurityConfig.

Ứng dụng ví dụ đăng nhập và đăng xuất với Spring Security

Khi đăng nhập thành công, ta sẽ thấy trang chủ của ứng dụng cùng với link Logout. Nhấn vào link Logout để đăng xuất khỏi ứng dụng.

Ứng dụng ví dụ đăng nhập và đăng xuất với Spring Security

Ta sẽ thấy ứng dụng đã đăng xuất thành công kèm theo thông báo và chuyển hướng về lại trang đăng nhập.

LƯU Ý: Nếu để ý, bạn sẽ thấy ví dụ này ta không sử dụng file web.xml. Vì đây là một ứng dụng web, Maven sẽ tìm kiếm file web.xml và báo lỗi nếu không tìm thấy nó trong ứng dụng. Để tránh các vấn đề liên quan đến Maven, chúng ta cần cấu hình cờ trong file pom.xml.

Tổng kết

Trên đây là toàn bộ nội dung về cách tạo một ví dụ về đơn giản đăng nhập và đăng xuất với Spring Security. Trong các bài viết tiếp theo, chúng ta sẽ tìm hiểu thêm một số ví dụ khác không kém thực tế và hữu ích như quản lý Role, tính năng Remember-Me, và WebSocket Security.

Về tác giả

Bao Tran
Bao TranWeb Developer

I’m passionate about web development and sharing my insights through articles, with over 8 years of experience. I hope these sharings inspire you and help build a strong web development community. @#@ Tôi đam mê phát triển web và chia sẻ những hiểu biết của mình thông qua các bài viết, với hơn 8 năm kinh nghiệm. Tôi hy vọng những chia sẻ này sẽ truyền cảm hứng cho các bạn và giúp xây dựng một cộng đồng phát triển web mạnh mẽ.

Cập nhật thông tin mới nhấtNhận các thông tin mới nhất về mối đe dọa, báo cáo an ninh mạng từ CyStack về hòm thư điện tử của bạn

Thảo luận (0)

Đăng nhập để thảo luận

Bài viết liên quan