ข้ามไปที่เนื้อหา

UAT Devphase2 — SSO Environment (Keycloak)

Active target ตั้งแต่ 20 ก.ค. 2569. VM UAT รวมที่รันครบทุกระบบ S1–S9 พร้อม Keycloak / MinIO / Postgres / MSSQL / Test-AD บนเครื่องเดียว (docker compose) — เป็นผลลัพธ์ที่ส่งมอบตาม คำขอ UAT Environment.

ค่าลับ (secrets) ไม่อยู่ในหน้านี้

หน้านี้บันทึกเฉพาะ โครงสร้างและการเชื่อมต่อ (endpoint, realm, clientId, ตำแหน่งไฟล์ config, โมเดล auth) ตามหลักการเดิมของ KB — ห้ามเก็บรหัสผ่าน / client secret / national ID ในรีโปนี้ เพราะไซต์ rlpd2.fragmentx.ai เป็น สาธารณะ. ค่าลับจริงเก็บที่ Project_RLPD/credentials/uat_devphase2_sso_secrets.md (นอก git) และดึงจาก Keycloak Admin Console ได้เสมอ (ดูหัวข้อ การดึง secret จริง ท้ายหน้า).

สรุปเครื่อง

หัวข้อ ค่า
VM name RLPD_UAT_Devphase2
Hostname rlpdustdevphase2
IP 10.136.27.155 (บน RLPD LAN จริง)
SSH rlpd@10.136.27.155 — user อยู่ใน group sudo + docker · (รหัสผ่าน → credential store)
Stack ~/rlpd-stack (docker compose project rlpd-stack)
SSO endpoint https://uat-sso.rlpd.go.th — realm rlpd
โมเดล Model B — clientId/secret เหมือน prod ทั้งหมด
TLS ใบรับรองจริง *.rlpd.go.th (fullchain) · SPA webOrigins = UAT เท่านั้น
เครื่องเดิม (deprecated) Hostinger 72.60.211.241 — SSH เข้าไม่ได้แล้ว

วิธีสลับระบบมาใช้ UAT นี้: แก้ hostname ใน .env ของระบบ → uat-sso.rlpd.go.th แล้วเติม /etc/hosts (uat-*10.136.27.155).

Containers (docker compose rlpd-stack)

Service Container URL / Port บทบาท Credential
nginx rlpd-nginx 80 / 443 reverse proxy, TLS *.rlpd.go.th
MinIO rlpd-minio uat-minio.rlpd.go.th (S3 API uat-s3.rlpd.go.th) object store, bucket rlpd → credential store
Keycloak rlpd-keycloak uat-sso.rlpd.go.th SSO / OIDC (realm rlpd) bootstrap + realm admin → credential store
PostgreSQL rlpd-postgres (internal) Keycloak backing store, db rlpd_uat (KC_DB=postgres) → credential store
MSSQL rlpd-mssql (internal) UAT app DB, db PSDBDEVDB (login = sa) · สถานะ schema ต่อระบบ → uat_db_schema_status.md → credential store
Test AD rlpd-test-ad domain test-ad.rlpd.go.th Samba AD stub (federated เข้า Keycloak) → credential store

Keycloak Admin Console: uat-sso.rlpd.go.th/admin/ — human realm admin rlpd-sso-administrator (รหัสผ่าน → credential store).

nginx vhosts และสถานะ endpoint

rlpd-nginx (nginx:alpine) เป็น reverse proxy หน้าเดียวของทุกระบบ. ชื่อ uat-*.rlpd.go.th ไม่อยู่ใน public DNS — resolve เข้า 10.136.27.155 ผ่าน /etc/hosts (หรือ curl --resolve ตอนทดสอบ). ตารางด้านล่างคือ vhost → backend container พร้อมผลการ probe ผ่าน nginx (127.0.0.1) เมื่อ 8 ส.ค. 2569.

Endpoint ระบบ Backend Probe (8 ส.ค. 2569)
uat-lcs.rlpd.go.th S1 rlpd-lcs-web ✅ 200
uat-pjos.rlpd.go.th S2 rlpd-pjos-web ✅ 200
uat-ar-crs.rlpd.go.th S3 rlpd-arcrs-web ✅ 200
uat-emediation.rlpd.go.th S4 rlpd-emediation-web ✅ 200
uat-ia.rlpd.go.th S5 rlpd-lcomp ✅ 302 → /th/application/login (app login)
uat-ocipa.rlpd.go.th S6 10.136.27.144:80 (external) ⚠️ 404 — backend ตอบ แต่ root ไม่มี route
uat-wpis.rlpd.go.th S7 rlpd-wps ✅ 302 → /Account/SsoLogin
uat-www.rlpd.go.th S8 rlpd-website-www ✅ 200
uat-ww2-admin.rlpd.go.th S8 rlpd-website-cms ✅ 302 → /Account/SsoLogin
uat-ww2-api.rlpd.go.th S8 rlpd-website-be ⚠️ 404 — backend up, ไม่มี root route (ปกติของ API)
uat-webportal.rlpd.go.th S9 rlpd-webportal-web / -be ✅ 200
uat-openapi.rlpd.go.th S9 Open Data rlpd-s9-openapi:8080 🔴 502 — backend container ไม่มี
openapi.rlpd.go.th (prod-map) S9 Open Data rlpd-s9-openapi-prod:8080 🔴 container ไม่มี (จะ 502 เช่นกัน — ไม่ใช่ prod จริง เป็นชื่อ container ในเครื่อง)
uat-sso.rlpd.go.th Keycloak rlpd-keycloak:8080 ✅ 302 → /admin/ · /realms/rlpd = 200
uat-minio.rlpd.go.th MinIO console rlpd-minio:9001 ✅ 200
uat-s3.rlpd.go.th MinIO S3 API rlpd-minio:9000 ✅ 403 ที่ root (ปกติ) · /minio/health/live = 200

การอ่านผล: 200 หรือ 302 ไปหน้า login ของแอป/SSO = vhost + backend ปกติ (redirect ของ S5/S7/S8-CMS คือ auth flow ทำงาน ไม่ใช่ error). 404 ที่ root ของ S6/S8-API = backend รันอยู่แต่ไม่มี route ที่ /.

Known issue — uat-openapi 502 (S9 Open Data API)

uat-openapi.rlpd.go.th proxy ไป rlpd-s9-openapi:8080 แต่ ไม่มี container ชื่อนี้ บนเครื่อง (S9 มีแค่ rlpd-webportal-web + rlpd-webportal-be). nginx resolver หา upstream ไม่เจอ → 502. vhost openapi.rlpd.go.th ก็ชี้ไป rlpd-s9-openapi-prod:8080 ที่ไม่มีเช่นกัน. แก้: deploy/start container rlpd-s9-openapi (ดู compose ที่ ~/rlpd-stack) หรือชี้ vhost ไป service ที่ให้บริการ Open Data API จริง.

การเชื่อม SSO ต่อระบบ (realm rlpd)

ทุกระบบชี้ไป https://uat-sso.rlpd.go.th realm rlpd. Endpoint ของ dev/staging ใช้ URL เครื่องนี้ร่วมกัน; prod = https://sso.rlpd.go.th.

ระบบ clientId โมเดล Auth ไฟล์ config มี secret?
S1 lcs lcs SPA public/PKCE + resource-server backend lcs/frontend/.env, lcs/backend/.env ไม่มี
S2 pjos pjos SPA public/PKCE + resource-server backend pjos/frontend/.env, pjos/backend/.env ไม่มี
S3 ar_and_crs ar-crs SPA public/PKCE + resource-server backend ar_and_crs/frontend/.env, ar_and_crs/backend/.env ไม่มี
S4 emediation emediation SPA public/PKCE + resource-server backend emediation/frontend/.env, emediation/backend/.env ไม่มี
S5 lcomp lcomp PHP/CI3, confidential lawyer_compensation_system/htdocs/application/config/keycloak.php · ENV KC_CLIENT_SECRET
S6 ocipa ocipa .NET Framework OWIN, confidential ocipa/RLPD.Megazy.MilkyWaySolution.Web/Web.config · ENV KC_CLIENT_SECRET
S7 wps wps .NET Core, confidential wps/RLPD/appsettings.json (Keycloak:Authority/ClientId) · ENV KC_CLIENT_SECRET หรือ Keycloak__ClientSecret
S8 rlpd-website rlpd-website .NET Core, confidential rlpd_offcial_website/CMS.ADMIN/appsettings.json · ENV Keycloak__ClientSecret
S9 web_portal FE rlpd-frontend · BFF web-portal-proxy SPA public FE + BFF confidential (backend จัดการ Keycloak ผ่าน Admin API จึงถือ secret) web_portal/frontend/.env, web_portal/backend/.env (อ่านผ่าน backend/src/providers/Locals.ts) ✅ (FE ไม่มี)

ค่า config (ไม่ลับ) ที่ใช้ร่วมกัน:

  • SPA (S1–S4, S9 FE): VITE_SSO_AUTH_URL=https://uat-sso.rlpd.go.th · VITE_SSO_AUTH_REALM=rlpd · VITE_SSO_AUTH_CLIENT_ID=<clientId>
  • Backend Node (S1–S4, S9): KEYCLOAK_BASE_URL=https://uat-sso.rlpd.go.th · KEYCLOAK_REALM=rlpd · KEYCLOAK_CLIENT_ID=<clientId>
  • Confidential .NET (S6–S8): KeycloakAuthority / Keycloak__Authority = https://uat-sso.rlpd.go.th/realms/rlpd

Test users: wisit.i, sorakrit.b, pongsiri.t, woraprat.m (realm rlpd, AD-federated, role SuperAdminIT). รหัสผ่าน + national ID → credential store.

การดึง secret จริง

  1. Keycloak Admin Console → realm rlpdClients<clientId>CredentialsClient secret
  2. หรือ REST: GET /admin/realms/rlpd/clients/{id}/client-secret
  3. หรือไฟล์ต้นทาง (นอก git): Project_RLPD/credentials/uat_devphase2_sso_secrets.md

ค่า leaked ที่ต้อง rotate

DXC SSO (sso.dxc.go.th, realm DXC) client rlpd-wpo ถูก hardcode secret ไว้ใน wps/RLPD/appsettings.json (tracked ใน git) — ต้อง rotate ที่ DXC → ย้ายเป็น ENV → scrub git history. รายละเอียดใน ความปลอดภัยและการปฏิบัติตามกฎเกณฑ์.