Bảo mật ứng dụng Java web bởi Spring Security

Công Nghệ
Bảo mật ứng dụng Java web bởi Spring Security
Bài viết được sự cho phép của smartjob.vn Chúng mình xin chia sẻ với bạn kỹ thuật bảo mật tiên tiến, mạnh mẽ dành cho Java web sử dụng Spring Security. Bài viết hội tụ các best-practice, các kỹ thuật tối tân nhất hiện nay. Nội dung sẽ hay và khó. Công nghệ sử dụng (technology-stack) Spring Security Spring Boot Spring Web MVC Gradle (build system) Thymeleaf (template engine) Công cụ sử dụng IntelliJ IDEA 2016.1.3 Apache Tomcat 8.0.35 Trước khi bắt tay thực hiện, Bạn nên đọc các bài viết trên SmartJob: Giới thiệu Spring Boot (để hiểu về Spring Boot) Kiểm tra tính hợp lệ của dữ liệu đầu vào form Spring Web MVC bởi Hibernate Validator (để hiểu về luồng đi của Spring Web MVC) Spring Security [1] là bộ khung bảo mật ứng dụng Java web cung cấp cơ chế cấp phép quyền (authorization) và xác thực người dùng (authentication). Sức mạnh của Spring Security thể hiện ở sự dễ dùng, dễ cấu hình, khả năng mở rộng, và khả năng bảo mật ứng dụng mạnh mẽ. Spring Security chống được các kỹ thuật hacking tinh vi: Session fixation (Tấn công chiếm quyền điều khiển session của người dùng) [2] Clickjacking (click chuột tự động, ví dụ click vào nút Like Facebook mà không xin phép người dùng) CSRF (Cross-site request forgery: Tạo truy vấn (request) giả mạo truyền từ trang này sang trang khác) Mục tiêu Chúng ta sẽ xây dựng ứng dụng Java web có trang chủ, trang đăng nhập, khu vực bảo mật (chỉ truy cập được sau khi người dùng hợp lệ đăng nhập). Cấu trúc project sau khi hoàn tất sẽ như thế này Bạn sẽ phải tạo/chỉnh sửa 7 file: Application.java MvcConfig.java WebSecurityConfig.java dang_nhap.html khu_vuc_bao_mat.html trang_chu.html build.gradle Sử dụng IntelliJ...

Bài viết được sự cho phép của smartjob.vn

Chúng mình xin chia sẻ với bạn kỹ thuật bảo mật tiên tiến, mạnh mẽ dành cho Java web sử dụng Spring Security. Bài viết hội tụ các best-practice, các kỹ thuật tối tân nhất hiện nay. Nội dung sẽ hay và khó.

Công nghệ sử dụng (technology-stack)

  • Spring Security
  • Spring Boot
  • Spring Web MVC
  • Gradle (build system)
  • Thymeleaf (template engine)

Công cụ sử dụng

  • IntelliJ IDEA 2016.1.3
  • Apache Tomcat 8.0.35

Trước khi bắt tay thực hiện, Bạn nên đọc các bài viết trên SmartJob:

Spring Security [1] là bộ khung bảo mật ứng dụng Java web cung cấp cơ chế cấp phép quyền (authorization) và xác thực người dùng (authentication). Sức mạnh của Spring Security thể hiện ở sự dễ dùng, dễ cấu hình, khả năng mở rộng, và khả năng bảo mật ứng dụng mạnh mẽ. Spring Security chống được các kỹ thuật hacking tinh vi:

  • Session fixation (Tấn công chiếm quyền điều khiển session của người dùng) [2]
  • Clickjacking (click chuột tự động, ví dụ click vào nút Like Facebook mà không xin phép người dùng)
  • CSRF (Cross-site request forgery: Tạo truy vấn (request) giả mạo truyền từ trang này sang trang khác)

Mục tiêu

Chúng ta sẽ xây dựng ứng dụng Java web có trang chủ, trang đăng nhập, khu vực bảo mật (chỉ truy cập được sau khi người dùng hợp lệ đăng nhập). Cấu trúc project sau khi hoàn tất sẽ như thế này

Bảo mật ứng dụng Java web bởi Spring SecurityBảo mật ứng dụng Java web bởi Spring Security

Bạn sẽ phải tạo/chỉnh sửa 7 file:

  1. Application.java
  2. MvcConfig.java
  3. WebSecurityConfig.java
  4. dang_nhap.html
  5. khu_vuc_bao_mat.html
  6. trang_chu.html
  7. build.gradle

Sử dụng IntelliJ IDEA để khởi tạo project:

Bảo mật ứng dụng Java web bởi Spring SecurityBảo mật ứng dụng Java web bởi Spring Security

Bộ khung project được dựng trên nền Spring Boot. Bấm chọn Spring Initializr, rồi bấm Next.

Bảo mật ứng dụng Java web bởi Spring SecurityBảo mật ứng dụng Java web bởi Spring Security

Bạn điền thông tin, các tùy chọn vào 10 mục như ảnh chụp màn hình. Bước thứ 11 là bấm nút Next

Bảo mật ứng dụng Java web bởi Spring SecurityBảo mật ứng dụng Java web bởi Spring Security

Chọn và nhặt vào thư viện cần dùng. 3 thành phần tham gia mở rộng ứng dụng Spring Boot là:

  • Security
  • Web
  • Thymeleaf

Phiên bản Spring Boot ổn định, mới nhất tại thời điểm viết bài là 1.3.5.RELEASE

Bảo mật ứng dụng Java web bởi Spring SecurityBảo mật ứng dụng Java web bởi Spring Security

Đặt tên project, chọn vị trí lưu mã nguồn project

Bảo mật ứng dụng Java web bởi Spring SecurityBảo mật ứng dụng Java web bởi Spring Security

Cấu hình cho Gradle build system

Bảo mật ứng dụng Java web bởi Spring SecurityBảo mật ứng dụng Java web bởi Spring Security

InteliJ IDEA và Spring Initializer tự động sinh ra cho bạn cấu trúc thư mục của project. Tìm file build.gradle sửa lại nội dung như sau:

buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.5.RELEASE")
}
}

apply plugin: 'war'
apply plugin: 'idea'
apply plugin: 'spring-boot'

jar {
baseName = 'demo_spring_security'
version = '1.0.0'
}

repositories {
mavenCentral()
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
compile("org.springframework.boot:spring-boot-starter-thymeleaf")
compile("org.springframework.boot:spring-boot-starter-security")
providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
testCompile("junit:junit")
}

Dòng 10, 29 cho phép chúng ta đóng gói ứng dụng Spring Boot thành file WAR truyền thống. (Nếu để theo mặc định, Spring Boot sẽ đóng gói ứng dụng web thành file JAR thực thi dùng Apache Tomcat nhúng, run trực tiếp, rất đặc sắc. Tuy nhiên theo cách này việc deploy sẽ quá đơn giản đến mức khiến bạn đọc khó hiểu, tại sao không có file WAR mà ứng dụng Java web vẫn chạy).

Tìm Java job lương cao trên Station D ngay!

Tạo thêm thư mục java trong thư mục src/main, rồi tạo thêm package vn.smartjob.demo_spring.demo_security . Tạo class Application.java

package vn.smartjob.demo_spring.demo_security;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;

/**
* Điểm đi vào của ứng dụng Spring Boot.
*/
@SpringBootApplication
public class Application extends SpringBootServletInitializer {

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(Application.class);
}

public static void main(String[] args) throws Throwable {
SpringApplication.run(Application.class, args);
}

}

Mã nguồn dưới đây thực chất đã chuyển đổi (convert) ứng dụng Spring Boot nguyên bản (tạo ra file JAR có thể run được) thành ứng dụng web Java truyền thống (đóng gói thành file WAR) bằng cách:

– Dòng 12, class Application  được extends từ class org.springframework.boot.context.web.SpringBootServletInitializer
– Dòng 14 đến 17, phải Override method configure  để đóng gói ứng dụng Spring Boot thành file WAR truyền thống.

Tạo thêm thư mục resources bên trong thư mục srcmain. Tạo thư mục templates bên trong thư mục resources.. Sau đó tạo 3 tập tin giao diện (sử dụng Thymeleaf template engine). Các file giao diện sử dụng Thymeleaf. Ở đâu Thymeleaf xử lý (render) ra giao diện, sẽ sử dụng HTML element mà trong đó chứa thuộc tính th:____  . Các thẻ security chèn vào trong giao diện sẽ do Spring Security xử lý.

File trang_chu.html

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://wwww.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>Trang chủ</title>
</head>
<body>
<h1>Ứng dụng minh họa Spring Security</h1>

<p>Bấm vào <a th:href="@{/hello}">link này</a> để đăng nhập.</p>

</body>

</html>

File dang_nhap.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">

<head>
<title>Đăng nhập</title>
</head>

<body>
<div th:if="${param.logout}">Bạn đã đăng xuất.</div>
<form th:action="@{/login}" method="post">
<th:block>Tên đăng nhập</th:block>
<th:block><input type="text" name="username"/></th:block>

<th:block>Mật khẩu</th:block>
<th:block><input type="password" name="password"/></th:block>

<th:block><input type="submit" value="Đăng nhập"/></th:block>
</form>

<div th:if="${param.error}" style="color: red;">Sai tên đăng nhập hoặc sai mật khẩu.</div>

</body>
</html>

File khu_vuc_bao_mat.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>Đây là khu vực bảo mật</title>
</head>
<body>

<h2>Đây là khu vực chỉ dành cho thành viên đã đăng nhập</h2>

Bí quyết công nghệ sử dụng trong ứng dụng này:<br/>
<ol>
<li>Spring Web MVC</li>
<li>Spring Boot</li>
<li>Spring Security</li>
</ol>

<h1 th:inline="text">Xin chào bạn [[${#httpServletRequest.remoteUser}]]!</h1>
<form th:action="@{/logout}" method="post">
<input type="submit" value="Đăng xuất"/>
</form>
</body>
</html>

File MvcConfig.java . 4 dòng code từ 12 đến 15, là việc ánh xạ (mapping) đường dẫn truy cập với file giao diện tương ứng (đó chính là tên các file html không bao gồm đuôi file).

package vn.smartjob.demo_spring.demo_security;

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

@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {

@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/home").setViewName("trang_chu");
registry.addViewController("/").setViewName("trang_chu");
registry.addViewController("/hello").setViewName("khu_vuc_bao_mat");
registry.addViewController("/login").setViewName("dang_nhap");
}

}

File WebSecurityConfig.java . Cấu hình bảo mật sử dụng hoàn toàn bằng method và class Java. Bạn để ý bên trên class có annotation @Configuration  và @EnableWebSecurity  để ứng dụng nhận diện thông số bảo mật nằm trong đoạn mã nguồn này. Để cho đơn giản, chúng ta cấp phép 1 người dùng có tên smartjob cùng mật khẩu 4321 . Chúng ta có thể cấu hình các quy tắc bảo mật tinh tế sau này trong các ví dụ sau.

package vn.smartjob.demo_spring.demo_security;

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;

/**
* Cấu hình bảo mật
*/
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

/**
* Cấu hình xác thực người dùng (authentication).
*
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}

/**
* Cấu hình cấp phép (quyền) người dùng (authorization).
*
* @param auth
* @throws Exception
*/
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("smartjob").password("4321").roles("USER");
}

}

Dòng 26: Cấp phép truy cập, khởi tạo luồng lo-gic bảo mật.
Dòng 27: Cho phép tất cả người dùng (đã đăng nhập, hay chưa đăng nhập) đều được truy cập trang chủ.
Dòng 30: Nếu người dùng có nhu cầu, đưa người dùng đến trang Đăng nhập.
Dòng 31: Tất cả mọi người dùng đều có quyền tiếp cận (truy cập) trang Đăng nhập.
Dòng 34: Sau khi đăng nhập, người dùng đã được xác thực có thể Đăng xuất.

Dòng 48: Cấp phép người dùng có tên đăng nhập smartjob, mật khẩu 4321, với vai trò (role) là người dùng thông thường (USER). Trên một hệ thống sẽ có nhiều role khác nhau.

Chạy ứng dụng trên Apache Tomcat 8

Bảo mật ứng dụng Java web bởi Spring SecurityBảo mật ứng dụng Java web bởi Spring Security

Chúng ta cố tình nhập sai tên đăng nhập hoặc mật khẩu để kiểm tra thông báo lỗi và kiểm tra khả năng ngăn chặn của Spring Security:
Bảo mật ứng dụng Java web bởi Spring SecurityBảo mật ứng dụng Java web bởi Spring Security

Khi nhập đúng tên đăng nhập: smartjob và mật khẩu: 4321 thì người dùng sẽ truy cập được khu vực bảo mật:

Bảo mật ứng dụng Java web bởi Spring SecurityBảo mật ứng dụng Java web bởi Spring Security

Đăng nhập thành công, người dùng truy cập được khu vực đặc quyền riêng. Thậm chí Trình duyệt web còn hỏi bạn có muốn lưu tên đăng nhập, mật khẩu ứng dụng trong trình duyệt hay không. Để sử dụng tính năng đăng xuất (do Spring Security cung cấp), bạn bấm nút Đăng xuất để kiểm tra việc vận hành của việc xóa thông tin người dùng trên trình duyệt.

Mẹo: Trong quá trình phát triển ứng dụng, có thể bạn phải xóa thông tin đăng nhập lưu trong trình duyệt đi để test khả năng bảo mật. Bạn làm như sau: Trình duyệt Google Chrome, chọn Setting, gõ từ khóa tìm kiếm pri (privacy)

Bảo mật ứng dụng Java web bởi Spring SecurityBảo mật ứng dụng Java web bởi Spring Security

Chọn Content settings… rồi tìm

Bảo mật ứng dụng Java web bởi Spring SecurityBảo mật ứng dụng Java web bởi Spring Security

Chọn All cookies and site data… 

Bảo mật ứng dụng Java web bởi Spring SecurityBảo mật ứng dụng Java web bởi Spring Security

Nhớ bấm nút X rồi sau đó Done để xóa thông tin bảo mật lưu trên trình duyệt, nhằm mục đích chuẩn bị môi trường test ứng dụng Spring Security.

Tải về mã nguồn từ server SmartJob: spring_security hoặc clone/fork từ GitHub: https://github.com/SmartJobVN/spring_security

 Bài viết gốc được đăng tải tại smartjob.vn

Có thể bạn quan tâm:

Xem thêm Việc làm lập trình Java hấp dẫn trên Station D

Bài viết liên quan

Bộ cài đặt Laravel Installer đã hỗ trợ tích hợp Jetstream

Bộ cài đặt Laravel Installer đã hỗ trợ tích hợp Jetstream

Bài viết được sự cho phép của tác giả Chung Nguyễn Hôm nay, nhóm Laravel đã phát hành một phiên bản chính mới của “ laravel/installer ” bao gồm hỗ trợ khởi động nhanh các dự án Jetstream. Với phiên bản mới này khi bạn chạy laravel new project-name , bạn sẽ nhận được các tùy chọn Jetstream. Ví dụ: API Authentication trong Laravel-Vue SPA sử dụng Jwt-auth Cách sử dụng Laravel với Socket.IO laravel new foo --jet --dev Sau đó, nó sẽ hỏi bạn thích stack Jetstream nào hơn: Which Jetstream stack do you prefer? [0] Livewire [1] inertia > livewire Will your application use teams? (yes/no) [no]: ... Nếu bạn đã cài bộ Laravel Installer, để nâng cấp lên phiên bản mới bạn chạy lệnh: composer global update Một số trường hợp cập nhật bị thất bại, bạn hãy thử, gỡ đi và cài đặt lại nha composer global remove laravel/installer composer global require laravel/installer Bài viết gốc được đăng tải tại chungnguyen.xyz Có thể bạn quan tâm: Cài đặt Laravel Làm thế nào để chạy Sql Server Installation Center sau khi đã cài đặt xong Sql Server? Quản lý các Laravel route gọn hơn và dễ dàng hơn Xem thêm Tuyển dụng lập trình Laravel hấp dẫn trên Station D

By stationd
Principle thiết kế của các sản phẩm nổi tiếng

Principle thiết kế của các sản phẩm nổi tiếng

Tác giả: Lưu Bình An Phù hợp cho các bạn thiết kế nào ko muốn làm code dạo, design dạo nữa, bạn muốn cái gì đó cao hơn ở tầng khái niệm Nếu lập trình chúng ta có các nguyên tắc chung khi viết code như KISS , DRY , thì trong thiết kế cũng có những nguyên tắc chính khi làm việc. Những nguyên tắc này sẽ là kim chỉ nam, nếu có tranh cãi giữa các member trong team, thì cứ đè nguyên tắc này ra mà giải quyết (nghe hơi có mùi cứng nhắc, mình thì thích tùy cơ ứng biến hơn) Tìm các vị trí tuyển dụng designer lương cao cho bạn Nguyên tắc thiết kế của GOV.UK Đây là danh sách của trang GOV.UK Bắt đầu với thứ user cần Làm ít hơn Thiết kế với dữ liệu Làm mọi thứ thật dễ dàng Lặp. Rồi lặp lại lần nữa Dành cho tất cả mọi người Hiểu ngữ cảnh hiện tại Làm dịch vụ digital, không phải làm website Nhất quán, nhưng không hòa tan (phải có chất riêng với thằng khác) Cởi mở, mọi thứ tốt hơn Bao trừu tượng luôn các bạn, trang Gov.uk này cũng có câu tổng quát rất hay Thiết kế tốt là thiết kế có thể sử dụng. Phục vụ cho nhiều đối tượng sử dụng, dễ đọc nhất nhất có thể. Nếu phải từ bỏ đẹp tinh tế – thì cứ bỏ luôn . Chúng ta tạo sản phẩm cho nhu cầu sử dụng, không phải cho người hâm mộ . Chúng ta thiết kế để cả nước sử dụng, không phải những người đã từng sử dụng web. Những người cần dịch vụ của chúng ta nhất là những người đang cảm thấy khó sử dụng dịch...

By stationd
Hiểu về trình duyệt – How browsers work

Hiểu về trình duyệt – How browsers work

Bài viết được sự cho phép của vntesters.com Khi nhìn từ bên ngoài, trình duyệt web giống như một ứng dụng hiển thị những thông tin và tài nguyên từ server lên màn hình người sử dụng, nhưng để làm được công việc hiển thị đó đòi hỏi trình duyệt phải xử lý rất nhiều thông tin và nhiều tầng phía bên dưới. Việc chúng ta (Developers, Testers) tìm hiểu càng sâu tầng bên dưới để nắm được nguyên tắc hoạt động và xử lý của trình duyệt sẽ rất hữu ích trong công việc viết code, sử dụng các tài nguyên cũng như kiểm thử ứng dụng của mình. Cách để npm packages chạy trong browser Câu hỏi phỏng vấn mẹo về React: Component hay element được render trong browser? Khi hiểu được cách thức hoạt động của trình duyệt chúng ta có thể trả lời được rất nhiều câu hỏi như: Tại sao cùng một trang web lại hiển thị khác nhau trên hai trình duyệt? Tại sao chức năng này đang chạy tốt trên trình duyệt Firefox nhưng qua trình duyệt khác lại bị lỗi? Làm sao để trang web hiển thị nội dung nhanh và tối ưu hơn một chút?… Hy vọng sau bài này sẽ giúp các bạn có một cái nhìn rõ hơn cũng như giúp ích được trong công việc hiện tại. 1. Cấu trúc của một trình duyệt Trước tiên chúng ta đi qua cấu trúc, thành phần chung và cơ bản nhất của một trình duyệt web hiện đại, nó sẽ gồm các thành phần (tầng) như sau: Thành phần nằm phía trên là những thành phần gần với tương tác của người dùng, càng phía dưới thì càng sâu và nặng về xử lý dữ liệu hơn tương tác. Nhiệm...

By stationd
Thị trường EdTech Vietnam- Nhiều tiềm năng nhưng còn bị bỏ ngỏ tại Việt Nam

Thị trường EdTech Vietnam- Nhiều tiềm năng nhưng còn bị bỏ ngỏ tại Việt Nam

Lĩnh vực EdTech (ứng dụng công nghệ vào các sản phẩm giáo dục) trên toàn cầu hiện nay đã tương đối phong phú với nhiều tên tuổi lớn phân phối đều trên các hạng mục như Broad Online Learning Platforms (nền tảng cung cấp khóa học online đại chúng – tiêu biểu như Coursera, Udemy, KhanAcademy,…) Learning Management Systems (hệ thống quản lý lớp học – tiêu biểu như Schoology, Edmodo, ClassDojo,…) Next-Gen Study Tools (công cụ hỗ trợ học tập – tiểu biểu như Kahoot!, Lumosity, Curriculet,…) Tech Learning (đào tạo công nghệ – tiêu biểu như Udacity, Codecademy, PluralSight,…), Enterprise Learning (đào tạo trong doanh nghiệp – tiêu biểu như Edcast, ExecOnline, Grovo,..),… Hiện nay thị trường EdTech tại Việt Nam đã đón nhận khoảng đầu tư khoảng 55 triệu đô cho lĩnh vực này nhiều đơn vị nước ngoài đang quan tâm mạnh đến thị trường này ngày càng nhiều hơn. Là một trong những xu hướng phát triển tốt, và có doanh nghiệp đã hoạt động khá lâu trong ngành nêu tại infographic như Topica, nhưng EdTech vẫn chỉ đang trong giai đoạn sơ khai tại Việt Nam. Tại Việt Nam, hệ sinh thái EdTech trong nước vẫn còn rất non trẻ và thiếu vắng nhiều tên tuổi trong các hạng mục như Enterprise Learning (mới chỉ có MANA), School Administration (hệ thống quản lý trường học) hay Search (tìm kiếm, so sánh trường và khóa học),… Với chỉ dưới 5% số dân công sở có sử dụng một trong các dịch vụ giáo dục online, EdTech cho thấy vẫn còn một thị trường rộng lớn đang chờ được khai phá. *** Vừa qua Station D đã công bố Báo cáo Vietnam IT Landscape 2019 đem đến cái nhìn toàn cảnh về các ứng dụng công...

By stationd