Search K
OIDC / Single Sign-On
SnapOtter รองรับ OpenID Connect (OIDC) สำหรับ single sign-on ผู้ใช้สามารถเข้าสู่ระบบด้วยผู้ให้บริการข้อมูลประจำตัวภายนอกอย่าง Keycloak, Authentik, Google หรือ Microsoft Entra ID แทน (หรือควบคู่ไปกับ) การยืนยันตัวตนด้วยชื่อผู้ใช้/รหัสผ่านในเครื่อง
ดูเพิ่มเติม
เริ่มต้นอย่างรวดเร็ว
เพิ่มตัวแปรสภาพแวดล้อมเหล่านี้ลงใน docker-compose.yml ของคุณ:
yaml
services:
SnapOtter:
image: snapotter/snapotter:latest
environment:
EXTERNAL_URL: "https://photos.example.com"
OIDC_ENABLED: "true"
OIDC_ISSUER_URL: "https://auth.example.com/realms/myrealm"
OIDC_CLIENT_ID: "snapotter"
OIDC_CLIENT_SECRET: "your-secret-here"redirect URI สำหรับผู้ให้บริการของคุณจะเป็นแบบนี้เสมอ:
${EXTERNAL_URL}/api/auth/oidc/callbackตัวอย่างเช่น หาก EXTERNAL_URL คือ https://photos.example.com ให้กำหนด redirect URI ของผู้ให้บริการเป็น https://photos.example.com/api/auth/oidc/callback
เอกสารอ้างอิงการกำหนดค่า
| ตัวแปร | ค่าเริ่มต้น | คำอธิบาย |
|---|---|---|
OIDC_ENABLED | false | เปิดใช้งานการเข้าสู่ระบบ OIDC ปุ่ม "Sign in with SSO" จะปรากฏบนหน้าเข้าสู่ระบบ |
OIDC_ISSUER_URL | URL ผู้ออก (issuer) ของผู้ให้บริการ ต้องรองรับ OIDC Discovery (/.well-known/openid-configuration) | |
OIDC_CLIENT_ID | OAuth client ID ที่ลงทะเบียนกับผู้ให้บริการของคุณ | |
OIDC_CLIENT_SECRET | OAuth client secret | |
OIDC_SCOPES | openid profile email | รายการ scope ที่คั่นด้วยช่องว่างเพื่อร้องขอ |
OIDC_AUTO_CREATE_USERS | true | สร้างบัญชีผู้ใช้ในเครื่องโดยอัตโนมัติเมื่อเข้าสู่ระบบ OIDC ครั้งแรก |
OIDC_DEFAULT_ROLE | user | บทบาทที่กำหนดให้ผู้ใช้ OIDC ที่สร้างอัตโนมัติ หนึ่งใน admin, editor หรือ user |
OIDC_AUTO_LINK_USERS | false | เชื่อมโยงข้อมูลประจำตัว OIDC กับผู้ใช้ในเครื่องที่มีอยู่หากที่อยู่อีเมลตรงกัน |
OIDC_PROVIDER_NAME | ชื่อที่แสดงบนปุ่มเข้าสู่ระบบ (เช่น "Keycloak", "Google") หากว่างเปล่า ปุ่มจะแสดง "SSO" | |
OIDC_CLOCK_TOLERANCE | 30 | ความคลาดเคลื่อนของนาฬิกาที่ยอมรับได้เป็นวินาทีสำหรับการตรวจสอบ token |
OIDC_USERNAME_CLAIM | preferred_username | claim ของ ID token ที่ใช้เป็นชื่อผู้ใช้สำหรับบัญชีใหม่ |
EXTERNAL_URL | URL สาธารณะที่เข้าถึง SnapOtter ได้ จำเป็นสำหรับ OIDC เพื่อสร้าง redirect URI ที่ถูกต้อง | |
COOKIE_SECRET | สร้างอัตโนมัติ | secret สำหรับเซ็นชื่อคุกกี้เซสชัน ตั้งค่านี้อย่างชัดเจนเมื่อรันหลาย replica |
คู่มือผู้ให้บริการ
Keycloak
- สร้าง realm ใหม่ (หรือใช้ที่มีอยู่)
- ไปที่ Clients และสร้าง client ใหม่:
- Client ID:
snapotter - Client authentication: เปิด (confidential)
- Authentication flow: Standard flow (Authorization Code)
- Client ID:
- ใต้แท็บ Settings ของ client ให้ตั้งค่า Valid redirect URIs เป็น callback URL ของคุณ (เช่น
https://photos.example.com/api/auth/oidc/callback) - คัดลอก Client secret จากแท็บ Credentials
- ตั้งค่า
OIDC_ISSUER_URLเป็นhttps://keycloak.example.com/realms/your-realm
Authentik
- ในหน้าจอผู้ดูแลระบบ ไปที่ Applications > Providers และสร้าง OAuth2/OpenID Provider ใหม่
- Client type: Confidential
- Redirect URIs: callback URL ของคุณ
- Signing key: เลือกคีย์ที่มีอยู่หรือสร้างขึ้นใหม่
- สร้าง Application และเชื่อมโยงกับ provider
- คัดลอก Client ID และ Client Secret จากการตั้งค่า provider
- ตั้งค่า
OIDC_ISSUER_URLเป็นhttps://authentik.example.com/application/o/snapotter/(เครื่องหมายทับท้ายมีความสำคัญ)
Google
- ไปที่ Google Cloud Console
- สร้างโปรเจกต์ (หรือเลือกที่มีอยู่)
- ไปที่ APIs & Services > OAuth consent screen และกำหนดค่า
- ไปที่ APIs & Services > Credentials และสร้าง OAuth 2.0 Client ID:
- Application type: Web application
- Authorized redirect URIs: callback URL ของคุณ
- คัดลอก Client ID และ Client secret
- ตั้งค่า
OIDC_ISSUER_URLเป็นhttps://accounts.google.com - ตั้งค่า
OIDC_USERNAME_CLAIMเป็นemail(Google ไม่ให้preferred_username)
Azure AD / Entra ID
- ในพอร์ทัล Azure ไปที่ Microsoft Entra ID > App registrations > New registration
- ตั้งชื่อแอปว่า "SnapOtter" ใต้ Redirect URI ให้เลือกแพลตฟอร์ม Web และป้อน callback URL ของคุณ (เช่น
https://photos.example.com/api/auth/oidc/callback) อย่าเลือก Single-page application เพราะ SnapOtter ยืนยันตัวตนด้วย client secret ซึ่ง Entra ID ไม่ยอมรับสำหรับการลงทะเบียนแบบ SPA - คัดลอก Application (client) ID และ Directory (tenant) ID จากหน้า Overview
- ไปที่ Certificates & secrets > New client secret และคัดลอก Value ของ secret ทันที ค่านี้แสดงเพียงครั้งเดียว และ Secret ID ที่อยู่ข้าง ๆ ไม่ใช่ตัว secret
- ตั้งค่า
OIDC_ISSUER_URLเป็นhttps://login.microsoftonline.com/<tenant-id>/v2.0โดยใช้ Directory (tenant) ID จากขั้นตอนที่ 3 - ปล่อย
OIDC_USERNAME_CLAIMไว้ที่ค่าเริ่มต้น Entra ID ให้preferred_usernameมาอยู่แล้ว จึงไม่ต้องตั้งค่าทับเป็นemailแบบในคู่มือ Google
ใช้ tenant ID ของคุณใน issuer URL เสมอ ไม่ใช่ common หรือ organizations เพราะ endpoint แบบ multi-tenant เหล่านั้นประกาศเทมเพลตตามตัวอักษร {tenantid} เป็น issuer ซึ่งทำให้การตรวจสอบ OIDC discovery ล้มเหลว
WARNING
preferred_username ของ Entra ID อิงตาม user principal name ซึ่งจะเปลี่ยนเมื่อผู้ใช้ถูกเปลี่ยนชื่อหรือถูกย้ายไปยัง tenant อื่น SnapOtter อ่าน claim นี้เพียงครั้งเดียวตอนเข้าสู่ระบบครั้งแรก บัญชีจึงคงชื่อผู้ใช้เดิมไว้หลังจากนั้น การเข้าสู่ระบบยังใช้งานได้ในทุกกรณี เพราะผู้ใช้ที่กลับมาจะถูกจับคู่ด้วย subject ที่คงที่ของ token ไม่ใช่ด้วยชื่อผู้ใช้
การเปลี่ยนไปใช้ Entra ID ไม่ปิดการเข้าสู่ระบบด้วยรหัสผ่าน ดู การปิดการเข้าสู่ระบบในเครื่อง
Okta และผู้ให้บริการอื่น ๆ
ผู้ให้บริการรายใดก็ตามที่รองรับ OIDC Discovery ใช้งานได้ในแบบเดียวกัน: สร้าง web client แบบ confidential พร้อม callback URL ของคุณ แล้วชี้ OIDC_ISSUER_URL ไปที่ issuer สำหรับ Okta ให้สร้างแอปด้วยวิธีเข้าสู่ระบบ OIDC - OpenID Connect และประเภท Web Application จากนั้นใช้โดเมน Okta ของคุณเป็น issuer (เช่น https://your-company.okta.com)
SnapOtter ไม่จับคู่กลุ่มจากผู้ให้บริการข้อมูลประจำตัวเข้ากับบทบาท ผู้ใช้ SSO ใหม่จะได้รับ OIDC_DEFAULT_ROLE ผู้ดูแลระบบเปลี่ยนบทบาทได้ที่ Settings > Users และการร้องขอ claim ของกลุ่มผ่าน OIDC_SCOPES ไม่มีผล
การจัดสรรผู้ใช้
สร้างอัตโนมัติ
เมื่อ OIDC_AUTO_CREATE_USERS เป็น true (ค่าเริ่มต้น) บัญชีผู้ใช้ในเครื่องจะถูกสร้างขึ้นในครั้งแรกที่มีคนเข้าสู่ระบบผ่าน OIDC ชื่อผู้ใช้จะดึงมาจาก claim ที่ระบุโดย OIDC_USERNAME_CLAIM และบทบาทจะถูกตั้งเป็น OIDC_DEFAULT_ROLE
หากเกิดชื่อผู้ใช้ซ้ำกัน จะมีการต่อท้ายด้วยตัวเลข (เช่น jane กลายเป็น jane_2)
เชื่อมโยงอัตโนมัติ
เมื่อ OIDC_AUTO_LINK_USERS เป็น true SnapOtter จะเชื่อมโยงข้อมูลประจำตัว OIDC กับบัญชีในเครื่องที่มีอยู่หากที่อยู่อีเมลตรงกัน สิ่งนี้มีประโยชน์เมื่อคุณมีบัญชีผู้ใช้ที่สร้างไว้ล่วงหน้าและต้องการให้พวกเขาเริ่มใช้ SSO โดยไม่สูญเสียข้อมูล
WARNING
เปิดใช้งานการเชื่อมโยงอัตโนมัติเฉพาะเมื่อคุณไว้ใจผู้ให้บริการ OIDC ของคุณในการตรวจสอบที่อยู่อีเมล อีเมลที่ไม่ได้รับการยืนยันอาจทำให้ใครบางคนเข้ายึดบัญชีของผู้ใช้อื่นได้
การปิดการเข้าสู่ระบบในเครื่อง
OIDC ไม่ปิดการเข้าสู่ระบบด้วยชื่อผู้ใช้/รหัสผ่านในเครื่อง ทั้งสองวิธียังคงใช้งานได้ ผู้ดูแลระบบยังสามารถเข้าสู่ระบบด้วยข้อมูลประจำตัวในเครื่องได้หากผู้ให้บริการ OIDC ไม่สามารถเข้าถึงได้
ใบรับรองที่เซ็นด้วยตนเอง
หากผู้ให้บริการ OIDC ของคุณใช้ใบรับรองที่เซ็นด้วยตนเองหรือใบรับรอง CA ส่วนตัว ให้ mount CA bundle เข้าไปในคอนเทนเนอร์และชี้ NODE_EXTRA_CA_CERTS ไปที่มัน:
yaml
services:
SnapOtter:
image: snapotter/snapotter:latest
volumes:
- ./my-ca.pem:/etc/ssl/certs/custom-ca.pem:ro
environment:
NODE_EXTRA_CA_CERTS: /etc/ssl/certs/custom-ca.pem
OIDC_ENABLED: "true"
OIDC_ISSUER_URL: "https://auth.internal.example.com/realms/myrealm"
OIDC_CLIENT_ID: "snapotter"
OIDC_CLIENT_SECRET: "your-secret-here"DANGER
อย่าตั้งค่า NODE_TLS_REJECT_UNAUTHORIZED=0 สิ่งนี้จะปิดการตรวจสอบ TLS ทั้งหมดและเป็นความเสี่ยงด้านความปลอดภัย
ผู้ออกโทเค็นที่ใช้ http แบบไม่เข้ารหัส
SnapOtter ยอมรับ URL ของผู้ออกโทเค็นที่เป็น http:// ก็ต่อเมื่อ EXTERNAL_URL เป็น http แบบไม่เข้ารหัสด้วย ซึ่งเหมาะกับการตั้งค่าทดสอบในเครื่องหรือใน LAN ในกรณีนี้ การค้นหา (discovery) การแลกเปลี่ยนรหัสเข้าสู่ระบบ และโทเค็นจะส่งผ่านเครือข่ายโดยไม่เข้ารหัส SnapOtter จึงบันทึกคำเตือนเมื่อเริ่มทำงานโดยระบุโฮสต์ของผู้ออกโทเค็น หาก EXTERNAL_URL เป็น https:// ผู้ออกโทเค็นที่ใช้ http จะถูกปฏิเสธเมื่อเข้าสู่ระบบ และคำเตือนตอนเริ่มทำงานจะแจ้งเรื่องนี้ ไม่ว่ากรณีใด วิธีแก้คือให้บริการผู้ให้บริการข้อมูลประจำตัวผ่าน https
การแก้ไขปัญหา
redirect URI ไม่ตรงกัน
ข้อผิดพลาดที่พบบ่อยที่สุด ตรวจสอบความแตกต่างเหล่านี้ระหว่างสิ่งที่ผู้ให้บริการคาดหวังกับสิ่งที่ SnapOtter ส่ง:
httpกับhttpsscheme ต้องตรงกันทุกประการ- เครื่องหมายทับท้าย ผู้ให้บริการบางรายเข้มงวดเรื่องนี้
- หมายเลขพอร์ต ระบุพอร์ตหากไม่ใช่ค่ามาตรฐาน
- Path ต้องเป็น
/api/auth/oidc/callback
ตรวจสอบ EXTERNAL_URL อีกครั้ง มันต้องตรงกับ URL ที่ผู้ใช้พิมพ์ในเบราว์เซอร์
UNABLE_TO_VERIFY_LEAF_SIGNATURE
ผู้ให้บริการ OIDC กำลังใช้ใบรับรองที่ Node.js ไม่ไว้ใจ ดู ใบรับรองที่เซ็นด้วยตนเอง ด้านบน
ข้อผิดพลาดความคลาดเคลื่อนของนาฬิกา
หากนาฬิกาเซิร์ฟเวอร์และนาฬิกาผู้ให้บริการ OIDC ไม่ตรงกัน การตรวจสอบ token อาจล้มเหลว เพิ่มค่า OIDC_CLOCK_TOLERANCE (ค่าเริ่มต้นคือ 30 วินาที) วิธีแก้ที่ดีกว่าคือรัน NTP บนทั้งสองเครื่อง
"OIDC provider unreachable"
SnapOtter ดึงเอกสาร discovery ของผู้ให้บริการเมื่อเริ่มต้นและระหว่างการเข้าสู่ระบบ ตรวจสอบ:
- การแปลง DNS จากภายในคอนเทนเนอร์ Docker (
docker exec snapotter nslookup auth.example.com) - กฎไฟร์วอลล์ระหว่างคอนเทนเนอร์และผู้ให้บริการ
- ค่า
OIDC_ISSUER_URLต้องเข้าถึงได้จากเซิร์ฟเวอร์ ไม่ใช่แค่จากเบราว์เซอร์ของคุณ
claim ที่ขาดหายไป
หากชื่อผู้ใช้หรืออีเมลว่างเปล่าหลังจากเข้าสู่ระบบ ผู้ให้บริการของคุณอาจไม่ได้ส่ง claim ที่คาดหวังกลับมา ตรวจสอบ:
- scope ที่กำหนดค่าใน
OIDC_SCOPESมีprofileและemail - ผู้ให้บริการถูกกำหนดค่าให้รวม claim ที่ระบุใน
OIDC_USERNAME_CLAIMไว้ใน ID token - ผู้ให้บริการบางรายต้องการการกำหนดค่า mapper/scope อย่างชัดเจนเพื่อปล่อย claim
