CNAP 클라우드 플랫폼 GitOps 대시보드를 직접 체험해보세요  —  실시간 CI/CD, 모니터링, 보안 관제를 한 곳에서     CNAP 클라우드 플랫폼 GitOps 대시보드를 직접 체험해보세요  —  실시간 CI/CD, 모니터링, 보안 관제를 한 곳에서     CNAP 클라우드 플랫폼 GitOps 대시보드를 직접 체험해보세요  —  실시간 CI/CD, 모니터링, 보안 관제를 한 곳에서     CNAP 클라우드 플랫폼 GitOps 대시보드를 직접 체험해보세요  —  실시간 CI/CD, 모니터링, 보안 관제를 한 곳에서    

Keycloak SPI 데모: OTP, 간편인증, 휴면 계정 관리 기능 구현 및 테스트

로컬 환경에서 Keycloak SPI 확장 기능을 손쉽게 실행하고 검증할 수 있는 데모 프로젝트입니다. OTP 인증, 간편인증, 약관 동의, 휴면 계정 관리 등 실제 서비스에서 자주 활용되는 기능들을 빠르게 구성하고 동작을 확인할 수 있도록 구성되어 있습니다.

설치 없이 바로 체험하려면 CNAPCloud의 GitOps 대시보드 로그인 페이지에서 동일한 구성을 확인할 수 있습니다. 로그인 후 Keycloak React 데모에 접속하면 SSO로 바로 연결되는 것도 확인할 수 있습니다. 이 서비스의 운영 시간은 09:30 ~ 21:00 KST입니다.


목차

  1. 실행 방법
  2. 서비스 접속 URL
  3. Keycloak React 데모
  4. Admin Console
  5. Docker Compose 구성
  6. 환경 변수 설정
  7. Make 명령어
  8. 참고 자료

1. 실행 방법

Docker Desktop만 설치되어 있으면 됩니다.

git clone https://github.com/cnapcloud/keycloak-extension-demo.git
cd keycloak-extension-demo
make up

처음 실행 시 Keycloak 기동까지 약 2~3분이 소요됩니다. 이 시간 동안 내부적으로 다음과 같은 작업이 순차적으로 진행됩니다.

postgres      → DB 준비
keycloak-init → SPI JAR 복사
keycloak      → 서버 기동
keycloak-cli  → cnap Realm 생성 + 초기 관리자 계정 등록
그 외          → rabbitmq, mailhog, keycloak-user-storage, react-keycloak-demo, inicis-mock-server

준비가 완료되면 아래 주소들로 접속할 수 있습니다.


2. 서비스 접속 URL

서비스주소설명
React 인증 데모http://localhost:5173로그인·회원가입·간편인증 E2E 체험
Keycloakhttp://localhost:8080Keycloak 서버
간편인증 Mockhttp://localhost:9091이니시스 인증 Mock 서버
Mailhoghttp://localhost:8025발송된 이메일 확인
RabbitMQhttp://localhost:15672사용자 이벤트 메시지 확인 (admin / password)
User Storagehttp://localhost:8090외부 사용자 저장소 REST API
User Storage DBhttp://localhost:8090/h2-consoleH2 DB 스키마·데이터 조회
JDBC URL: jdbc:h2:mem:testdb
ID: sa / PW: password

3. Keycloak React 데모

http://localhost:5173 을 열면 실제 로그인 화면이 나옵니다.

개발 환경에서는 OTP 입력란에 000000 을 입력하면 항상 통과됩니다. (OTP_DEV_MODE=true) 이메일로 OTP를 전송한 경우, Mailhog 수신함에서 확인한 번호를 사용할 수도 있습니다.

로그인

  1. 아이디 + 비밀번호 입력 (admin / password)
  2. OTP 인증 — SMS 또는 이메일 (000000)
  3. 약관 미동의 상태면 약관 동의 화면이 먼저 뜹니다

간편인증 (KG Inicis)

  1. 로그인 화면에서 간편인증 버튼 클릭
  2. Mock 서버(http://localhost:9091) 인증 페이지로 이동
  3. 사용자(홍기동) 선택 후 인증 성공 버튼 클릭
  4. 동일 전화번호로 가입된 계정(admin)과 연계 확인 후 연계 추가 클릭
  5. 로그인 완료

간편인증은 이미 가입된 사용자와 연동하는 흐름입니다. 먼저 일반 회원가입을 완료한 후 연동하세요.

카카오 / 네이버 로그인

Admin Console → Identity Providers 에서 카카오·네이버 OAuth Client ID 및 Secret을 설정한 후에만 사용할 수 있습니다. 설정 방법은 docs/02-installation.md 10절을 참고하세요.

  1. 로그인 화면에서 카카오 또는 네이버 버튼 클릭
  2. 각 소셜 서비스 OAuth 인증 완료
  3. 가입 시 사용한 이메일과 일치하는 계정에 자동 연동

회원가입

  1. 약관 동의 (필수 / 선택 구분)
  2. 아이디 · 이메일 · 전화번호 · 비밀번호 입력
  3. 이메일 또는 SMS OTP 인증

ID 찾기

  1. 이메일 또는 전화번호 입력
  2. OTP 인증 후 아이디 확인

비밀번호 찾기

  1. 아이디(username) 입력
  2. OTP 인증 (이메일 / SMS 선택)
  3. 새 비밀번호 입력

사용자 프로파일

로그인 후 계정 페이지에서 커스텀 속성을 확인하고 수정할 수 있습니다. 속성 목록은 Admin Console → 사용자 프로파일을 참고하세요.


4. Admin Console

http://localhost:8080 → Administration Console → Realm: cnap

  • ID: admin / PW: password

이 데모의 핵심은 Admin Console에 등록된 Extension 설정들입니다.

Authentication Flow

Authentication → Flows 에서 아래 커스텀 플로우를 확인할 수 있습니다.

Flow적용 위치설명
browser-otpBrowser flow로그인 OTP + 휴면 계정 차단
registration-termRegistration flow회원가입 시 약관 동의 수집
reset credentials-otpReset credentials flow비밀번호 재설정 OTP

Required Actions

Authentication → Required Actions 에서 확인합니다.

  • Terms and Marketing Consent — 신규 사용자에게 자동으로 할당되는 약관·마케팅 동의 액션
  • Reactivate Dormant Account — 휴면 계정 재활성화 액션 (Dormant Check가 트리거)

이벤트 리스너

Realm Settings → Events → Event listeners 에 아래 리스너가 등록되어 있습니다.

  • last-login-tracker — 로그인 성공마다 lastLoginDate 속성 자동 업데이트
  • user-event-publisher — 사용자 생성·수정·삭제 이벤트를 RabbitMQ로 발행
  • metrics-listener — Keycloak 이벤트를 Prometheus 메트릭으로 노출

RabbitMQ에서 사용자 변경 이벤트를 수신하려면 RabbitMQ 관리 UIadmin / password 로 로그인합니다. user.account 큐를 생성하고, exchange에 user.account.* 라우팅 키로 바인딩하면 모든 사용자 관련 메시지가 user.account 큐로 수신됩니다.

User Federation

User Federation 에 세 가지 Provider가 등록되어 있습니다.

  • dormant-account-scheduler — 365일 미접속 시 휴면 전환, 90일 후 계정 삭제
  • terms-change-notifier — 약관 변경 사전 고지 스케줄러
  • REST — 외부 User Storage API 연동 (http://localhost:8090)

소셜 로그인 (Identity Provider)

Identity Providers 에서 카카오, 네이버, 이니시스 간편인증 설정을 볼 수 있습니다.

소셜 로그인은 기존 계정과의 연동 방식으로 동작합니다. 이메일(카카오·네이버) 또는 전화번호(이니시스)로 가입된 계정을 찾아 자동으로 연결합니다.

테마 (Theme)

Realm Settings → Themes 에서 로그인·계정 화면의 테마를 설정합니다.

항목기본값설명
Login themekeycloak.ext-dark로그인·회원가입·OTP 등 인증 화면
Account theme(기본값)사용자 계정 관리 페이지
Admin theme(기본값)Admin Console
Email themekeycloak.ext발송 이메일 템플릿

다국어 (Localization)

Realm Settings → Localization 에서 지원 언어와 기본 언어를 설정합니다.

  • Internationalization: Enabled
  • Supported locales: ko, en
  • Default locale: ko

사용자 프로파일 (User Profile)

Realm Settings → User profile 에서 커스텀 속성을 확인하고 편집할 수 있습니다.

속성설명
phoneNumber전화번호 — OTP 및 간편인증 연동에 사용
otpMethodOTP 수신 방식 (sms / email)
termsAgreed필수 약관 동의 여부
marketingAgreed마케팅 수신 동의 여부
lastLoginDate마지막 로그인 일시 (last-login-tracker 자동 갱신)
dormant휴면 계정 여부 (dormant-account-scheduler 자동 설정)

5. Docker Compose 구성

compose 구성 파일은 docker/compose.yaml에 있습니다.

서비스 구성

서비스포트역할
postgresKeycloak DB
keycloak-initSPI JAR를 Keycloak 컨테이너로 복사
keycloak8080, 9000, 8000Keycloak 서버 (HTTP / Health / Debug)
keycloak-clicnap Realm 생성 및 초기 관리자 계정 등록
rabbitmq5672, 15672사용자 이벤트 메시지 브로커 (AMQP / Management UI)
mailhog1025, 8025이메일 수신 Mock (SMTP / Web UI)
keycloak-user-storage8090외부 User Storage REST API (H2 in-memory DB)
react-keycloak-demo5173React 인증 데모 앱
inicis-mock-server9091이니시스 간편인증 Mock 서버 (keycloak 네트워크 공유)

기동 순서

depends_on 조건에 따라 아래 순서로 기동됩니다. 처음 실행 시 Keycloak이 완전히 뜨기까지 약 2~3분이 소요됩니다.

postgres ──────────────────────────┐
keycloak-init ─────────────────────+──→ keycloak ──────────┐
                                                           ├──→ keycloak-cli
keycloak-user-storage ─────────────────────────────────────┘

rabbitmq / mailhog / react-keycloak-demo / inicis-mock-server   (독립 기동)

볼륨 및 설정 파일

경로설명
docker/compose.yaml서비스 전체 구성
docker/config/realm-export.jsoncnap Realm 초기 설정 (keycloak-cli가 import)
docker/terms-content/이용약관 HTML 파일 (Realm / 버전 / 언어 경로 구조)
docker/data/런타임 데이터 (postgres, rabbitmq 영속성)

약관 파일은 수정 후 Keycloak을 재시작하면 반영됩니다.

docker/terms-content/
  cnap/
    1.0/ko/
      service.html
      privacy_required.html
      privacy_optional.html
      marketing.html
    2026-04-10/ko/
      service.html
    2026-04-11/ko/
      service.html

6. 환경 변수 설정

docker/compose.yaml keycloak 서비스의 environment 블록입니다.

변수기본값설명
OTP_DEV_MODEtrue000000으로 OTP 통과 — 운영에서는 반드시 제거
OTP_CODE_LIFESPAN_SECONDS300인증코드 유효 시간(초)
OTP_RATE_LIMIT_MAX_ATTEMPTS5OTP 최대 시도 횟수
OTP_RATE_LIMIT_LOCKOUT_MINUTES30초과 시 잠금 시간(분)
SMS_PROVIDERaws_sns_x실 SMS: aws_sns / 현재는 더미(fallback)
USER_EVENT_CHANNELrabbitmq이벤트 채널 (rabbitmq | kafka | redis | 미설정 시 log-only)

7. Make 명령어

make up                      # 전체 서비스 시작 (백그라운드)
make down                    # 전체 서비스 중지 및 컨테이너 제거
make clean                   # 컨테이너 + 볼륨 + 이미지 + data/ 전체 삭제

make up-svc SVC=keycloak     # 단일 서비스만 시작 (의존성 제외)
make down-svc SVC=keycloak   # 단일 서비스만 중지 및 제거

make restart                 # 전체 재시작
make logs                    # 전체 로그 스트리밍
make ps                      # 서비스 상태 확인

8. 참고 자료

문서

문서내용
docs/01-features.md주요 기능 소개
docs/02-installation.mdSPI 상세 설치 및 Admin Console 설정 가이드
docs/03-user_guide.md사용자 가이드
docs/04-developer_guide.md개발자 가이드
docs/05-dormant-account-test-runbook.md휴면 계정 테스트 런북
docs/06-usp-integration-guide.mdUser Storage REST API 연동 가이드
docs/07-terms-guide.md이용약관 운영 가이드

관련 저장소

저장소설명
cnapcloud/keycloak-user-storage외부 User Storage REST API 구현체
cnapcloud/react-keycloak-demoReact 인증 데모 앱
cnapcloud/inicis-mockup-server이니시스 간편인증 Mock 서버