การยืนยันตัวตนแบบ Bearer ของ Okta API
ยืนยันตัวตนการเข้าถึง Halo API แบบโปรแกรมโดยใช้โทเค็น OAuth 2.0 Bearer ที่ออกโดย Okta.
ภาพรวม
Halo เปิดเผย REST API ผ่านบริการ API-Access คำขอ API ทั้งหมดต้องมีโทเค็น Bearer ที่ถูกต้องในส่วนหัว Authorization โทเค็นจะได้รับจาก Okta โดยใช้โฟลว์ OAuth 2.0 Client Credentials (machine-to-machine).
คู่มือนี้จะแนะนำการกำหนดค่า Okta ให้เป็นผู้ให้บริการข้อมูลประจำตัวสำหรับบริการ Halo API-Access จากนั้นทดสอบการผสานรวมด้วยการยืนยันตัวตนด้วยโทเค็น Bearer.
ข้อกำหนดเบื้องต้น
- การติดตั้งใช้งาน Halo ที่กำลังทำงานอยู่พร้อมกำหนดค่าบริการ API-Access แล้ว
- องค์กร Okta ที่มีสิทธิ์เข้าถึงระดับผู้ดูแลระบบ
- เซิร์ฟเวอร์การให้สิทธิ์ Okta ที่กำหนดค่าสำหรับ Halo แล้ว (ดู Okta Authorization Server)
- การเข้าถึงเครือข่ายจาก API client ไปยังทั้ง Okta และ Halo API endpoint
การตั้งค่า
ลงทะเบียน API client ใน Okta
สร้างแอปพลิเคชันแบบ machine-to-machine
- เข้าสู่ระบบ Okta Admin Console
- ไปที่
Applications->Applications->Create App Integration->API Services.

- ระบุชื่อ App integration ที่เหมาะสม เช่น
Glasswall Halo API

ปิดใช้งาน DPoP (proof of possession)
- ไปที่แท็บ
Generalของแอปพลิเคชัน -> ส่วนGeneral Settings-> คลิกEdit. - ภายใต้ Proof of possession ให้เอาเครื่องหมายถูกออกจาก
Require Demonstrating Proof of Possession (DPoP) header in token requests. - บันทึก
หมายเหตุ: Okta เปิดใช้งาน DPoP เป็นค่าเริ่มต้นสำหรับแอปพลิเคชัน API Services โดย DPoP จะผูกโทเค็นเข้ากับคีย์เข้ารหัสของ client เพื่อป้องกันการโจมตีแบบนำโทเค็นกลับมาใช้ซ้ำ อย่างไรก็ตาม บริการ Halo API-Access ยังไม่รองรับการตรวจสอบความถูกต้องของโทเค็น DPoP ในขณะนี้ ดังนั้นจึงต้องปิดใช้งานฟีเจอร์นี้เพื่อให้การยืนยันตัวตนด้วย Bearer token ทำงานได้

กำหนดค่า client credentials
-
จดบันทึก
Client IDและสร้างClient Secret.export CLIENT_ID="<your-client-id>"
export CLIENT_SECRET="<your-client-secret>"
หมายเหตุด้านความปลอดภัย: จัดเก็บ client secret อย่างปลอดภัยโดยใช้ secrets manager (เช่น Azure KeyVault) ห้าม commit secrets ลงใน source control โดยเด็ดขาด

กำหนดค่า roles (ไม่บังคับ)
- หาก API client ของคุณต้องการสิทธิ์เขียนไปยัง endpoints การจัดการไลเซนส์ โปรดตรวจสอบให้แน่ใจว่าได้กำหนดค่า claim
roleบน authorization server โดยแมปค่าAdminไปยัง client ของคุณ (ดู API Roles)
หมายเหตุ: หากไม่มี claim
roleAPI จะใช้ roleUserเป็นค่าเริ่มต้น ดู API Roles to Action Mapping สำหรับรายละเอียดเกี่ยวกับสิ่งที่แต่ละ role สามารถเข้าถึงได้
จดบันทึก issuer URI และ audience
-
จาก authorization server ที่กำหนดค่าไว้ในขั้นตอนข้อกำหนดเบื้องต้น:
export OKTA_ISSUER_URI="https://<your-okta-domain>/oauth2/<authorization-server-id>"
export VALID_AUDIENCE="api://halo"
เพิ่ม access policy สำหรับ API client
- ไปที่แท็บ
Access Policiesของ authorization server (Security->API-> เลือก authorization server ของคุณ ->Access Policies) - Add a new access policy:
- ชื่อ: เช่น
API Client Access - คำอธิบาย: เช่น
Access policy for Halo API clients - กำหนดให้กับ: API Services client ที่สร้างไว้ด้านบน (ค้นหาด้วยชื่อแอปพลิเคชัน
glasswall-halo-apiจากขั้นตอนที่ 2)
- ชื่อ: เช่น
- Add a rule:
- ชื่อ: เช่น
Allow API Clients - ประเภทการให้สิทธิ์:
Client Credentials - ปล่อยการตั้งค่าอื่น ๆ ไว้เป็นค่าเริ่มต้น หรือปรับอายุการใช้งานของโทเค็นตามต้องการ
- ชื่อ: เช่น
หมายเหตุ: access policies สำหรับ grant แบบ Client Credentials ใช้ควบคุมว่า clients ใด (ตาม
client_id) ที่สามารถขอโทเค็นได้ การเป็นสมาชิกกลุ่มไม่มีผล เนื่องจากไม่มีบริบทของผู้ใช้ใน flow นี้ รักษาความปลอดภัยในการเข้าถึง API โดยจำกัดผู้ที่มีclient_idและclient_secretผ่าน secrets manager ของคุณ

กำหนดค่า service API-Access สำหรับ Okta
ต้องกำหนดค่า Helm chart cdrplatform-api-access เพื่อให้ตรวจสอบความถูกต้องของ Bearer tokens ที่ออกโดย authorization server ของ Okta ของคุณ chart นี้เปิดเผยการตั้งค่าการยืนยันตัวตนภายใต้คีย์ values configuration
ปรับใช้การกำหนดค่า
หมายเหตุ: ต้องตั้งค่า
AuthorityและValidIssuerให้เป็น Okta issuer URI ทั้งคู่ บริการ API-Access ใช้Authorityเพื่อค้นหา JWKS (JSON Web Key Set) สำหรับการตรวจสอบลายเซ็นของโทเค็น และใช้ValidIssuerเพื่อตรวจสอบ claimissในโทเค็น
export HALO_DOMAIN=<your-halo-domain>
helm upgrade --install cdrplatform-api-access cdrplatform-api-access --reuse-values \
--set configuration.AuthenticationScheme="Bearer" \
--set configuration.Authentication__Schemes__Bearer__Authority="${OKTA_ISSUER_URI:?}" \
--set configuration.Authentication__Schemes__Bearer__ValidIssuer="${OKTA_ISSUER_URI:?}" \
--set configuration.Authentication__Schemes__Bearer__ValidAudiences__0="${VALID_AUDIENCE:?}" \
--set strategy.type="Recreate" \
--set ingress.enabled=true \
--set ingress.tls.enabled=true \
--set ingress.tls.domain="${HALO_DOMAIN:?}" \
--atomic
หลาย audience (ไม่บังคับ)
หาก API client หรือแอปพลิเคชันหลายรายการต้องเข้าถึง Halo API ด้วย audience ที่แตกต่างกัน ให้เพิ่มรายการ ValidAudiences เพิ่มเติม:
--set configuration.Authentication__Schemes__Bearer__ValidAudiences__0="api://halo-api" \
--set configuration.Authentication__Schemes__Bearer__ValidAudiences__1="<second-client-id>" \
--set configuration.Authentication__Schemes__Bearer__ValidAudiences__2="<third-client-id>"
การใช้งาน Halo API
รับ bearer token
Client Credentials flow (machine-to-machine)
ใช้ flow นี้สำหรับระบบอัตโนมัติ, ไปป์ไลน์ CI/CD และการเชื่อมต่อแบบ service-to-service ที่ไม่ต้องมีการโต้ตอบจากผู้ใช้
export TOKEN_ENDPOINT="${OKTA_ISSUER_URI}/v1/token"
ขอโทเค็น:
curl -s -X POST "${TOKEN_ENDPOINT}" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=${CLIENT_ID}" \
-d "client_secret=${CLIENT_SECRET}" \
-d "scope=halo.api"
ตัวอย่างการตอบกลับ:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6Ikp...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "halo.api"
}
แยกโทเค็น:
export ACCESS_TOKEN=$(curl -s -X POST "${TOKEN_ENDPOINT}" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=${CLIENT_ID}" \
-d "client_secret=${CLIENT_SECRET}" \
-d "scope=halo.api" | jq -r '.access_token')
ยืนยันตัวตนคำขอ API
ใส่ Bearer token ในส่วนหัว Authorization ของทุกคำขอ API:
export HALO_API_URL="https://<your-halo-domain>"
ตรวจสอบการยืนยันตัวตน
ทดสอบด้วย endpoint ที่มีการป้องกัน คำขอที่ไม่มีโทเค็นควรส่งกลับ 401 และคำขอที่มีโทเค็นที่ถูกต้องควรส่งกลับ 200:
# Without token - expect 401
curl -s -o /dev/null -w "%{http_code}" \
"${HALO_API_URL}/api/v1/policies"
# With token - expect 200
curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
"${HALO_API_URL}/api/v1/policies"
ตัวอย่าง: ส่งไฟล์เพื่อประมวลผล
curl -s -X POST \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-F "file=@/path/to/document.pdf" \
"${HALO_API_URL}/api/v1/rebuild/file" \
--output rebuilt_document.pdf
การแก้ไขปัญหา
| อาการ | สาเหตุ | วิธีแก้ไข |
|---|---|---|
401 Unauthorized | โทเค็นหมดอายุหรือไม่ถูกต้อง | ขอโทเค็นใหม่ ตรวจสอบว่า CLIENT_ID และ CLIENT_SECRET ถูกต้อง |
401 Unauthorized พร้อมโทเค็นที่ถูกต้อง | Audience ไม่ตรงกัน | ตรวจสอบให้แน่ใจว่า ValidAudiences ใน API-Access ตรงกับเคลม aud ในโทเค็น |
403 Forbidden พร้อม AdminRoleMissing | ไม่มีบทบาท Admin ในโทเค็น | กำหนดค่าเคลม role บน authorization server (ดู API Roles) จำเป็นสำหรับการดำเนินการเขียนของการจัดการไลเซนส์ |
| คำขอโทเค็นล้มเหลว | URL ของ token endpoint ไม่ถูกต้อง | ตรวจสอบ ID ของ authorization server และโดเมน Okta ตรวจสอบ /.well-known/openid-configuration |
ข้อผิดพลาด invalid_scope | ใช้ OIDC scopes กับ Client Credentials | ใช้ scope แบบกำหนดเอง halo.api แทน openid, profile หรือ email |
ข้อผิดพลาด invalid_dpop_proof | ไม่ได้ปิดใช้งาน DPoP | ปิดใช้งาน DPoP บนแอปพลิเคชัน API Services (ดู Disable DPoP) |
| หมดเวลาการเชื่อมต่อเครือข่าย | ไฟร์วอลล์หรือพร็อกซีบล็อกอยู่ | ตรวจสอบให้แน่ใจว่าไคลเอนต์ API สามารถเข้าถึงได้ทั้ง Okta token endpoint และ Halo API endpoint |