로컬 환경에서 Keycloak SPI 확장 기능을 손쉽게 실행하고 검증할 수 있는 데모 프로젝트입니다. OTP 인증, 간편인증, 약관 동의, 휴면 계정 관리 등 실제 서비스에서 자주 활용되는 기능들을 빠르게 구성하고 동작을 확인할 수 있도록 구성되어 있습니다.
설치 없이 바로 체험하려면 CNAPCloud의 GitOps 대시보드 로그인 페이지에서 동일한 구성을 확인할 수 있습니다. 로그인 후 Keycloak React 데모에 접속하면 SSO로 바로 연결되는 것도 확인할 수 있습니다. 이 서비스의 운영 시간은 09:30 ~ 21:00 KST입니다.
목차
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 체험 |
| Keycloak | http://localhost:8080 | Keycloak 서버 |
| 간편인증 Mock | http://localhost:9091 | 이니시스 인증 Mock 서버 |
| Mailhog | http://localhost:8025 | 발송된 이메일 확인 |
| RabbitMQ | http://localhost:15672 | 사용자 이벤트 메시지 확인 (admin / password) |
| User Storage | http://localhost:8090 | 외부 사용자 저장소 REST API |
| User Storage DB | http://localhost:8090/h2-console | H2 DB 스키마·데이터 조회 JDBC URL: jdbc:h2:mem:testdbID: sa / PW: password |
3. Keycloak React 데모
http://localhost:5173 을 열면 실제 로그인 화면이 나옵니다.
개발 환경에서는 OTP 입력란에
000000을 입력하면 항상 통과됩니다. (OTP_DEV_MODE=true) 이메일로 OTP를 전송한 경우, Mailhog 수신함에서 확인한 번호를 사용할 수도 있습니다.
로그인
- 아이디 + 비밀번호 입력 (
admin/password) - OTP 인증 — SMS 또는 이메일 (
000000) - 약관 미동의 상태면 약관 동의 화면이 먼저 뜹니다
간편인증 (KG Inicis)
- 로그인 화면에서 간편인증 버튼 클릭
- Mock 서버(http://localhost:9091) 인증 페이지로 이동
- 사용자(홍기동) 선택 후 인증 성공 버튼 클릭
- 동일 전화번호로 가입된 계정(admin)과 연계 확인 후 연계 추가 클릭
- 로그인 완료
간편인증은 이미 가입된 사용자와 연동하는 흐름입니다. 먼저 일반 회원가입을 완료한 후 연동하세요.
카카오 / 네이버 로그인
Admin Console → Identity Providers 에서 카카오·네이버 OAuth Client ID 및 Secret을 설정한 후에만 사용할 수 있습니다. 설정 방법은 docs/02-installation.md 10절을 참고하세요.
- 로그인 화면에서 카카오 또는 네이버 버튼 클릭
- 각 소셜 서비스 OAuth 인증 완료
- 가입 시 사용한 이메일과 일치하는 계정에 자동 연동
회원가입
- 약관 동의 (필수 / 선택 구분)
- 아이디 · 이메일 · 전화번호 · 비밀번호 입력
- 이메일 또는 SMS OTP 인증
ID 찾기
- 이메일 또는 전화번호 입력
- OTP 인증 후 아이디 확인
비밀번호 찾기
- 아이디(username) 입력
- OTP 인증 (이메일 / SMS 선택)
- 새 비밀번호 입력
사용자 프로파일
로그인 후 계정 페이지에서 커스텀 속성을 확인하고 수정할 수 있습니다. 속성 목록은 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-otp | Browser flow | 로그인 OTP + 휴면 계정 차단 |
registration-term | Registration flow | 회원가입 시 약관 동의 수집 |
reset credentials-otp | Reset 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 관리 UI에
admin/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 theme | keycloak.ext-dark | 로그인·회원가입·OTP 등 인증 화면 |
| Account theme | (기본값) | 사용자 계정 관리 페이지 |
| Admin theme | (기본값) | Admin Console |
| Email theme | keycloak.ext | 발송 이메일 템플릿 |
다국어 (Localization)
Realm Settings → Localization 에서 지원 언어와 기본 언어를 설정합니다.
- Internationalization:
Enabled - Supported locales:
ko,en - Default locale:
ko
사용자 프로파일 (User Profile)
Realm Settings → User profile 에서 커스텀 속성을 확인하고 편집할 수 있습니다.
| 속성 | 설명 |
|---|---|
phoneNumber | 전화번호 — OTP 및 간편인증 연동에 사용 |
otpMethod | OTP 수신 방식 (sms / email) |
termsAgreed | 필수 약관 동의 여부 |
marketingAgreed | 마케팅 수신 동의 여부 |
lastLoginDate | 마지막 로그인 일시 (last-login-tracker 자동 갱신) |
dormant | 휴면 계정 여부 (dormant-account-scheduler 자동 설정) |
5. Docker Compose 구성
compose 구성 파일은 docker/compose.yaml에 있습니다.
서비스 구성
| 서비스 | 포트 | 역할 |
|---|---|---|
postgres | — | Keycloak DB |
keycloak-init | — | SPI JAR를 Keycloak 컨테이너로 복사 |
keycloak | 8080, 9000, 8000 | Keycloak 서버 (HTTP / Health / Debug) |
keycloak-cli | — | cnap Realm 생성 및 초기 관리자 계정 등록 |
rabbitmq | 5672, 15672 | 사용자 이벤트 메시지 브로커 (AMQP / Management UI) |
mailhog | 1025, 8025 | 이메일 수신 Mock (SMTP / Web UI) |
keycloak-user-storage | 8090 | 외부 User Storage REST API (H2 in-memory DB) |
react-keycloak-demo | 5173 | React 인증 데모 앱 |
inicis-mock-server | 9091 | 이니시스 간편인증 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.json | cnap 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_MODE | true | 000000으로 OTP 통과 — 운영에서는 반드시 제거 |
OTP_CODE_LIFESPAN_SECONDS | 300 | 인증코드 유효 시간(초) |
OTP_RATE_LIMIT_MAX_ATTEMPTS | 5 | OTP 최대 시도 횟수 |
OTP_RATE_LIMIT_LOCKOUT_MINUTES | 30 | 초과 시 잠금 시간(분) |
SMS_PROVIDER | aws_sns_x | 실 SMS: aws_sns / 현재는 더미(fallback) |
USER_EVENT_CHANNEL | rabbitmq | 이벤트 채널 (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.md | SPI 상세 설치 및 Admin Console 설정 가이드 |
| docs/03-user_guide.md | 사용자 가이드 |
| docs/04-developer_guide.md | 개발자 가이드 |
| docs/05-dormant-account-test-runbook.md | 휴면 계정 테스트 런북 |
| docs/06-usp-integration-guide.md | User Storage REST API 연동 가이드 |
| docs/07-terms-guide.md | 이용약관 운영 가이드 |
관련 저장소
| 저장소 | 설명 |
|---|---|
| cnapcloud/keycloak-user-storage | 외부 User Storage REST API 구현체 |
| cnapcloud/react-keycloak-demo | React 인증 데모 앱 |
| cnapcloud/inicis-mockup-server | 이니시스 간편인증 Mock 서버 |