phucbui2it
Java SoftwareEngineer
Trang chủVề tôi
HomeBlogTích Hợp Keycloak Bảo Mật Ứng Dụng Java Spring Boot

Tích Hợp Keycloak Bảo Mật Ứng Dụng Java Spring Boot

9 tháng 2, 2026•
#spring#java#security
•33 views
Tích Hợp Keycloak Bảo Mật Ứng Dụng Java Spring Boot

Trong kiến trúc Microservices hiện đại, việc quản trị định danh và truy cập (IAM) tập trung là yêu cầu bắt buộc để đảm bảo tính bảo mật và khả năng mở rộng. Thay vì tự xây dựng hệ thống Auth phức tạp, chúng ta sẽ sử dụng Keycloak — một giải pháp mã nguồn mở mạnh mẽ dựa trên các tiêu chuẩn OIDC và OAuth 2.0.

1. Chuẩn Bị Hạ Tầng Với Docker Compose

Để đảm bảo tính bền vững (Persistence) và nhất quán dữ liệu (ACID), chúng ta sẽ chạy Keycloak cùng với PostgreSQL thay vì sử dụng cơ sở dữ liệu in-memory mặc định.

Tệp tin docker-compose.yml:

YAML

version: '3.8'
services:
  postgres_db:
    image: postgres:15
    environment:
      POSTGRES_DB: keycloak_db
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: password
    volumes:
      - postgres_data:/var/lib/postgresql/data

  keycloak:
    image: quay.io/keycloak/keycloak:latest
    command: start-dev
    environment:
      KC_DB: postgres
      KC_DB_URL: jdbc:postgresql://postgres_db:5432/keycloak_db
      KC_DB_USERNAME: admin
      KC_DB_PASSWORD: password
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: admin
    ports:
      - "8080:8080"
    depends_on:
      - postgres_db

volumes:
  postgres_data:

2. Cấu Hình Keycloak Admin Console

Sau khi khởi chạy bằng lệnh docker-compose up -d, hãy truy cập http://localhost:8080/admin:

  1. Tạo Realm: Tạo một Realm mới (ví dụ: phucbui2it-realm) để cô lập môi trường ứng dụng.

  2. Tạo Client: * Client ID: springboot-app.

    • Capability Config: Bật Client authentication nếu ứng dụng là Backend (Confidential).

  3. Tạo Roles & Users:

    • Tạo Role: ROLE_USER, ROLE_ADMIN.

    • Tạo User và gán Role tương ứng trong tab Role Mappings.


3. Tích Hợp Vào Ứng Dụng Spring Boot

Chúng ta sẽ biến Spring Boot API thành một OAuth2 Resource Server. Điều này có nghĩa là ứng dụng sẽ không trực tiếp yêu cầu username/password mà chỉ kiểm tra tính hợp lệ của JWT (JSON Web Token) do Keycloak cấp phát.

A. Dependencies (Maven)

Sử dụng thư viện chuẩn của Spring Security để đảm bảo tính hiện đại và ổn định:

XML

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>

B. Cấu Hình application.yml

Ứng dụng cần biết địa chỉ của Keycloak để tự động tải Public Key nhằm xác thực chữ ký số ($Digital Signature$) của Token.

YAML

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: http://localhost:8080/realms/phucbui2it-realm

4. Xử Lý Phân Quyền (Custom Role Converter)

Keycloak lưu trữ vai trò người dùng trong claim realm_access. Chúng ta cần một Converter để Spring Security có thể đọc được các vai trò này.

Java

public class KeycloakRoleConverter implements Converter<Jwt, Collection<GrantedAuthority>> {
    @Override
    public Collection<GrantedAuthority> convert(Jwt jwt) {
        Map<String, Object> realmAccess = (Map<String, Object>) jwt.getClaims().get("realm_access");
        if (realmAccess == null || realmAccess.isEmpty()) return List.of();

        return ((List<String>) realmAccess.get("roles")).stream()
                .map(roleName -> new SimpleGrantedAuthority("ROLE_" + roleName))
                .collect(Collectors.toList());
    }
}

5. Security Configuration & Controller

Thiết lập bộ lọc bảo mật để áp dụng Converter và kiểm soát các endpoint.

SecurityConfig.java:

Java

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/public/**").permitAll()
                .anyRequest().authenticated()
            )
            .oauth2ResourceServer(oauth2 -> oauth2
                .jwt(jwt -> jwt.jwtAuthenticationConverter(jwtAuthenticationConverter()))
            );
        return http.build();
    }

    private JwtAuthenticationConverter jwtAuthenticationConverter() {
        JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
        converter.setJwtGrantedAuthoritiesConverter(new KeycloakRoleConverter());
        return converter;
    }
}

Controller Kiểm Thử:

Java

@RestController
@RequestMapping("/api")
public class TestController {
    @GetMapping("/admin")
    @PreAuthorize("hasRole('ADMIN')")
    public String adminAccess() { return "Chào Admin của ndthuy!"; }
}

Tổng Kết

Bằng cách tích hợp Keycloak, ứng dụng Java của bạn giờ đây đã đạt được trạng thái Stateless hoàn toàn. Mọi gánh nặng về quản lý mật khẩu, mã hóa, và phiên đăng nhập đều được chuyển giao cho Keycloak xử lý, giúp mã nguồn ứng dụng trở nên sạch sẽ và an toàn hơn theo đúng chuẩn System Architecture hiện đại.

DANH MỤC

SERIES

TỪ KHÓA

MỚI NHẤT

Built by PhucBui2. The source code is available on GitHub.

security7Database5database4backend3indexing1performance-tuning1spring1java1System Design1Backend1
Database5Security4
01

[OAuth] Bài 2: Khóa chặt Access Token với DPoP và Refresh Token Rotation

1/3/2026
02

[OAuth] Bài 1: Khai tử Implicit Grant & Kỷ nguyên bắt buộc của PKCE

1/3/2026
03

[OAuth] Bài 0: Vì sao những kiến thức bảo mật bạn biết có thể đã lỗi thời?

1/3/2026
04

[Series] Database Internals - Bài 2: Giải mã "Thùng sách" – Nghệ thuật sắp xếp Slotted Page Layout

24/2/2026
05

[Series] Database Internals - Bài 1: Tại sao RDBMS lưu dữ liệu khác với File thông thường?

23/2/2026
The Database Internals5Mastering Modern OAuth3Modern Identity Architecture1