Share

Quay lại
Trang chủ / Kiến thức / Công nghệ và xu hướng / Nâng cao bảo mật hệ thống với Spring Security

Nâng cao bảo mật hệ thống với Spring Security

15/12/2023
31/12/2021
Nâng cao bảo mật hệ thống với Spring Security

Cùng với sự bùng nổ của công nghệ thông tin trong việc phát triển của doanh nghiệp, bài toán về bảo mật thông tin đã được đặt ra. Các ứng dụng doanh nghiệp dần trở nên phổ biến, tất nhiên, rất dễ bị tấn công bởi các mối đe dọa qua môi trường Internet. 

Việc giới hạn quyền truy cập vào các trang web, tài nguyên tĩnh, API hay các thông tin nhạy cảm của khách hàng là rất quan trọng.

Ở cấp độ cơ sở hạ tầng, chúng ta có thể áp dụng một số phương pháp, ví dụ như tường lửa (firewall), proxy server, whitelist IP,... Tuy nhiên, vẫn cần phải xây dựng bảo mật ở cấp độ ứng dụng, đặc biệt với những ứng dụng có logic phân quyền người dùng phức tạp. Với Spring Security, mọi thứ sẽ đơn giản hơn rất nhiều.

Spring security là gì?

Spring Security, một phần của Spring Framework, là framework hỗ trợ lập trình viên triển khai các biện pháp bảo mật ở cấp độ ứng dụng. Cùng với Spring MVC, cả hai là bộ khung toàn diện để phát triển các hệ thống web an toàn và bảo mật cao. 

Spring Security hoạt động xoay quanh 2 vấn đề chính là xử lý xác thực và xử lý ủy quyền ở cấp độ Web request cũng như cấp độ method invocation. 

Spring Security rất mạnh mẽ và có khả năng tùy biến cao, lập trình viên có thể sử dụng cấu hình có sẵn của framework hoặc tùy chỉnh theo từng bài toán của hệ thống. 

Bài viết này sẽ tập trung giới thiệu về Spring Security và các tính năng chính của framework này trong việc xây dựng phát triển ứng dụng.

Áp dụng bảo mật trong hệ thống với Spring Security

Cơ chế hoạt động chính

Kiến trúc của Spring Security trong các ứng dụng web hoàn toàn dựa trên các Servlet Filter, nó không phụ thuộc sử dụng servlet cũng như không phụ thuộc vào bất kì một công nghệ web nào. 

Về cơ bản, Spring Security gồm nhiều filter khác nhau, được quản lý thông qua FilterChainProxy. Các filter này có trách nhiệm chặn yêu cầu, kiểm tra xác thực, kiểm tra uỷ quyền, điều hướng tới Controller để xử lý request. Sau đó ném ra ngoại lệ trong trường hợp thông tin xác thực không hợp lệ.

 

 

Spring Security FilterChainProxy

Spring Security cung cấp class SecurityContext, quản lý tất cả thông tin xác thực của ứng dụng. Thông tin xác thực của người dùng sẽ được lưu trong đối tượng Authentication, và được lấy thông qua SecurityContextHolder. SecurityContext sử dụng ThreadLocal để quản lý thông tin, do đó đảm bảo các phương thức thực thi trên cùng một luồng sẽ được chia sẻ thông tin xác thực như nhau.

Có thể bạn quan tâm: Những lỗ hổng bảo mật website cơ bản và cách phòng tránh?

Cơ chế xác thực

Xác thực là gì? 

Hiểu một cách đơn giản, xác thực là quá trình hệ thống nhận dạng và xác minh một người nào đó khi họ muốn truy cập tài nguyên của hệ thống. Nó giống như lúc bạn muốn vào facebook, bạn cần đăng nhập username và password của mình trước tiên. Nếu thông tin đăng nhập đúng, hệ thống sẽ tiếp tục xử lý yêu cầu. Nếu không, bạn sẽ không có quyền truy cập vào ứng dụng.

Spring hỗ trợ xác thực như thế nào?

Trước khi truy cập các tài nguyên giới hạn quyền của hệ thống, người dùng phải đăng nhập. Spring Security có cơ chế xử lý đăng nhập cho các bài toán từ đơn giản tới phức tạp, ví dụ:

  • Thông tin đăng nhập được quản lý bởi chính hệ thống;

  • Thông tin đăng nhập được quản lý bởi bên thứ 3;

  • Cơ chế xác thực SSO (Oauth2, SAML);

  • Cơ chế xác thực LDAP;

Spring Security cung cấp interface AuthenticationProvider để xử lý các bài toán nêu trên một cách đơn giản, hiệu quả, an toàn và dễ mở rộng. Lập trình viên có thể sử dụng các phương thức có sẵn của Spring Security, hoặc là triển khai các tuỳ chỉnh AuthenticationProvider cho từng bài toán cụ thể. 

Ví dụ về cấu hình login/logout spring security

Như ví dụ trên, lập trình viên có thể cấu hình các thông tin về form đăng nhập/đăng xuất, logic xử lý khi thành công/thất bại cũng như logic xử lý khi các ngoại lệ xảy ra.

Trạng thái và phi trạng thái (Stateful vs Stateless)

Trong các ứng dụng web, việc tương tác giữa client và server có 2 mô hình: trạng thái và phi trạng thái.

Trạng thái nghĩa là server lưu thông tin của client để có thể xác định danh tính của client. Điển hình là giống như Session trong Tomcat của Java. Cơ chế xác thực theo mô hình này này được gọi là xác thực dựa trên phiên (session-based authentication).

Ví dụ, sau khi người dùng đăng nhập, ứng dụng lưu thông tin của người dùng trong phiên server và cung cấp cho client một giá trị cookie ghi lại phiên tương ứng. Với các yêu cầu tiếp theo, client đính kèm giá trị cookie đó (bước này là do trình duyệt tự động hoàn thành). Server sẽ đối chiếu cookie với session để có thể xác định được được yêu cầu đó là từ đâu và do ai.

Xác thực dựa trên phiên là đơn giản và thuận tiện nhất. Nó phù hợp với các dự án quy mô nhỏ. Tuy nhiên mô hình này khiến server phải lưu trữ một lượng lớn dữ liệu để quản lý phiên, cũng khi gặp khó khăn trong các trường hợp cần mở rộng ứng dụng theo cụm cũng như khó đáp ứng lượng người dùng đồng thời lớn.

 

Session-based authentication

Spring Security hỗ trợ rất tốt cơ chế xác thực dựa trên phiên nêu trên. Ngoài ra Spring Security cũng hỗ trợ các thẻ tùy chỉnh với các template engine của Java như Thymeleaf, JSP,... Trong trường hợp triển khai ứng dụng theo cụm, Spring Security cũng có thể kết hợp với Spring Session để quản lý phiên phân tán.

Phi trạng thái hiểu đơn giản là server không lưu trữ thông tin của client. Các yêu cầu từ client tới server là độc lập với nhau. Để server có thể xác định được những yêu cầu này đến từ đâu và do ai, client sẽ phải đính kèm thông tin mô tả cho các yêu cầu đó. 

Cơ chế xác thực dựa trên mô hình phi trạng thái còn được gọi là xác thực dựa trên mã thông báo (token-based authentication).

Ví dụ, bước đầu tiên, người dùng gửi username/password đến server để xác thực. Nếu thông tin chính xác, server sẽ mã hóa thông tin và xử lý, sau đó trả về một mã thông báo cho client. Client sẽ lưu trữ mã thông báo, với mỗi yêu cầu sau đó, client đính kèm mã thông báo đó trên header. Server sẽ xử lý xác thực dựa trên mã thông báo đó.

Cơ chế xác thực qua mã thông báo khắc phục được những nhược điểm của cơ chế xác thực qua phiên. Giảm một lượng lớn dữ liệu cần lưu trữ ở server, phù hợp với các hệ thống sử dụng RESTful API, dễ dàng mở rộng và phân cụm. Tuy nhiên phương pháp này cũng cần xử lý phức tạp hơn.

Có một số kiểu mã thông báo phổ biến như

  • Basic token: Khi người dùng đăng nhập, server sẽ trả về cho client mã thông báo. Server sẽ lưu mã thông báo trong database hoặc cache storage. Với mỗi request gửi kèm token, server sẽ kiểm tra token đó còn hiệu lực hay không và đang được gắn với người dùng nào trong database. Với kiểu này, server vẫn phải hoạt động khá nhiều.

  • Json web token (JWT): Giống như basic token, server sẽ trả về mã JWT cho client khi người dùng đăng nhập. Nhưng thay vì lưu ở cả server và client, JWT này sẽ lưu trữ ở client, và được server giải mã thông qua secret key. JWT có thể được sử dụng như một cơ chế xác thực không yêu cầu database.

Token-based Authentication via JWT

Spring cung cấp thư viện JWT cũng như các thư viện mã hoá phục vụ cho cơ chế xác thực dựa trên mã thông báo. Với việc xử lý mã thông báo, để đảm bảo việc xử lý chỉ diễn ra một lần duy nhất cho từng yêu cầu, Spring cung cấp filter OncePerRequestFilter để lập trình viên có thể triển khai cơ chế trên một cách nhanh chóng và chính xác.

Cơ chế uỷ quyền: Authorization

Ủy quyền là gì?

Nếu xác thực là quá trình kiểm tra người dùng hợp lệ thì ủy quyền là quá trình kiểm tra người dùng có được phép tiếp cận tài nguyên hay không. Đối với ứng dụng đơn giản, người dùng chỉ cần đăng nhập là có thể truy cập hết tài nguyên của ứng dụng. Tuy nhiên, với các ứng dụng lớn và phức tạp, dữ liệu chia theo từng nhóm người dùng với nhiều vai trò khác nhau. Ủy quyền giúp đảm bảo kiểm soát truy cập các tài nguyên an toàn và bảo mật hơn.

Ví dụ trong một ứng dụng doanh nghiệp, tài khoản của mỗi phòng ban sẽ chỉ có thể quản lý thông tin của phòng ban đó. Có những tài khoản chỉ được cấp quyền xem và không được thêm, sửa, xóa thông tin. Có những tài khoản được cấp quyền thao tác tất cả.

Phân quyền ứng dụng web với Spring Security

Spring Security hỗ trợ rất tốt trong việc phân quyền ứng dụng, cả ở 2 cấp độ: request level và method invocation level.

Spring Security cung cấp interface GrantedAuthority để đại diện cho các quyền của người dùng. Nếu một hệ thống phức tạp, cần kiểm tra ủy quyền dựa trên nhiều yếu tố khác, Spring Security cũng cung cấp thêm đối tượng User để lập trình viên có thể tùy chỉnh theo ý muốn.

 

Ví dụ cấu hình ủy quyền theo url 

Spring Security cung cấp tính năng ủy quyền ở cấp độ request bằng việc kế thừa class WebSecurityConfigurerAdapter. Như ví dụ trên, các url bắt đầu với api/v1/app thì không giới hạn quyền, trong khi các url bắt đầu với  api/v1/system thì chỉ những người dùng có quyền SYSTEM_ADMIN mới có thể truy cập. Việc cấu hình khá dễ hiểu và ngắn gọn.

Tuy nhiên, đối với một hệ thống phức tạp, việc kiểm soát truy cập đến tận cấp độ phương thức (method) là điều cần thiết. 

Giống như bảo mật ở cấp độ request trong ứng dụng web nêu trên, Spring cũng cung cấp cả các tính năng bảo mật ở cấp độ Class và Method. Điều đặc biệt là việc này rất dễ dàng thực hiện bằng cách sử dụng các annotation của Spring Security: @PreAuthorize, @PostAuthorize. 

Phạm vi ảnh hưởng của annotation phụ thuộc vào vị trí mà nó được đánh dấu. Nếu đánh dấu các annotation ở đầu class, nó sẽ áp dụng cho tất cả các phương thức của class đó. Trong trường hợp sử dụng riêng lẻ, nó chỉ ảnh hưởng với phương thức được đánh dấu. Đối với các phương thức bên trong annotation, lập trình viên có thể sử dụng các phương thức có sẵn của Spring Security, cũng như có thể tùy chỉnh theo các bài toán cụ thể.

 

Ví dụ cấu hình ủy quyền ở cấp độ phương thức

Ví dụ như dưới đây, chỉ những user có quyền SYSTEM admin mới có thể truy cập API api/v1/system. Đối với API api/v1/{companyId}/greeting,  việc kiểm tra ủy quyền được tùy chỉnh để giới hạn quyền truy cập theo companyId.

 

Ngoài các tính năng chính nêu trên, Spring Security còn hỗ trợ nhiều tính năng khác như: 

  • Hỗ trợ nhiều password encoder;

  • Dễ dàng xử lý các exceptions;

  • Cấu hình CSRF, CORS đơn giản;

  • Tương thích dễ dàng với các template engine của Java như Thymeleaf;

Kết luận

Bài viết đã hoàn thành vai trò giới thiệu và tóm tắt những tính năng chính của Spring Security trong việc phát triển ứng dụng Web. 

Với Spring Security, lập trình viên có thể tùy chỉnh bảo mật cho hệ thống của mình theo cách đơn giản nhất, thông qua các cấu hình và annotation. Điều này giúp lập trình viên có thể dễ dàng tiếp cận những khía cạnh bảo mật, rút ngắn thời gian phát triển cũng như chi phí vận hành và bảo trì hệ thống.

Bạn đang cần hợp tác cùng chuyên gia về phát triển web app?

Rabiloo là công ty công nghệ có 5 năm kinh nghiệm phát triển web app. Chúng tôi đã nghiên cứu và phát triển thành công ứng dụng nhắn tin, ứng dụng đặt chỗ, ứng dụng học tiếng Anh,... tại Nhật Bản. Chúng tôi lấy việc nghiên cứu nhu cầu người dùng và ứng dụng trí tuệ nhân tạo vào sản phẩm làm sự khác biệt. 

Kiến thức miền của chúng tôi không quá rộng nhưng đủ sâu về giáo dục, bán lẻ, thương mại điện tử. Nếu bạn đang kinh doanh trong nhóm lĩnh vực trên, chúng tôi tự tin có đủ kiến thức và kinh nghiệm để đồng hành cùng bạn. Nếu không, chúng tôi sẵn sàng nghiên cứu những kiến thức mới và làm tốt nhất có thể trong phạm vi năng lực.

80% dự án của chúng tôi đến từ nhóm khách hàng có tiêu chuẩn cao nhất về chất lượng trên thế giới - Nhật Bản. 

Chúng tôi đã xây dựng thành công hơn 150 dự án thành công, dài hạn, cho khách hàng tại Nhật Bản, Mỹ, Châu Âu, Singapore, Việt Nam, và hơn thế nữa.

Hãy cho Rabiloo biết chúng tôi có thể đóng góp gì cho sự thành công của dự án công nghệ sắp tới của bạn. Nếu bạn vẫn chưa chắc chắn về khả năng của nhóm lập trình viên, hãy để chúng tôi chứng minh.

 

ĐẶT LỊCH TƯ VẤN & KIỂM TRA NĂNG LỰC MIỄN PHÍ

Share


Cập nhật bài viết mới nhất từ chuyên gia

Không được để trống
Không được để trống
Không được để trống
Không được để trống
Tìm kiếm
Tags
Website là gì? Khái niệm, cấu tạo, phân loại các Website hiện nay
24/11/2023
21/12/2023
Website là gì? Khái niệm, cấu tạo, phân loại các Website hiện nay

Gặp gỡ và lắng nghe

Không được để trống
Không được để trống
Không được để trống
Không được để trống