Xác thực Bearer API Okta
Xác thực quyền truy cập theo chương trình vào Halo API bằng token Bearer OAuth 2.0 do Okta cấp.
Tổng quan
Halo cung cấp một REST API thông qua dịch vụ API-Access. Mọi yêu cầu API phải bao gồm một token Bearer hợp lệ trong header Authorization. Token được lấy từ Okta bằng luồng OAuth 2.0 Client Credentials (máy với máy).
Hướng dẫn này trình bày cách cấu hình Okta làm Nhà cung cấp danh tính cho dịch vụ Halo API-Access, sau đó kiểm tra tích hợp bằng xác thực token Bearer.
Điều kiện tiên quyết
- Một triển khai Halo đang chạy với dịch vụ API-Access đã được cấu hình
- Một tổ chức Okta có quyền truy cập quản trị viên
- Máy chủ ủy quyền Okta được cấu hình cho Halo (xem Okta Authorization Server)
- Quyền truy cập mạng từ API client đến cả Okta và endpoint Halo API
Thiết lập
Đăng ký một API client trong Okta
Tạo một ứng dụng machine-to-machine
- Đăng nhập vào Okta Admin Console.
- Đi tới
Applications->Applications->Create App Integration->API Services.

- Cung cấp tên App integration phù hợp: ví dụ
Glasswall Halo API

Tắt DPoP (proof of possession)
- Đi tới tab
Generalcủa ứng dụng -> phầnGeneral Settings-> nhấp vàoEdit. - Trong mục Proof of possession, bỏ chọn
Require Demonstrating Proof of Possession (DPoP) header in token requests. - Lưu.
Lưu ý: Okta bật DPoP theo mặc định cho các ứng dụng API Services. DPoP liên kết token với khóa mật mã của client, giúp ngăn chặn các cuộc tấn công phát lại token. Tuy nhiên, dịch vụ Halo API-Access hiện chưa hỗ trợ xác thực token DPoP, vì vậy cần phải tắt tính năng này để xác thực Bearer token hoạt động.

Cấu hình thông tin xác thực của client
-
Ghi lại
Client IDvà tạo mộtClient Secret.export CLIENT_ID="<your-client-id>"
export CLIENT_SECRET="<your-client-secret>"
Lưu ý bảo mật: Lưu trữ client secret một cách an toàn bằng trình quản lý bí mật (ví dụ: Azure KeyVault). Không bao giờ commit secret vào source control.

Cấu hình vai trò (tùy chọn)
- Nếu API client của bạn cần quyền ghi vào các endpoint quản lý giấy phép, hãy đảm bảo claim
roleđược cấu hình trên authorization server với giá trịAdminđược ánh xạ tới client của bạn (xem API Roles).
Lưu ý: Nếu không có claim
role, API mặc định sử dụng vai tròUser. Xem API Roles to Action Mapping để biết chi tiết về những gì mỗi vai trò có thể truy cập.
Ghi lại issuer URI và audience
-
Từ authorization server đã được cấu hình trong bước điều kiện tiên quyết:
export OKTA_ISSUER_URI="https://<your-okta-domain>/oauth2/<authorization-server-id>"
export VALID_AUDIENCE="api://halo"
Thêm access policy cho API client
- Đi tới tab
Access Policiescủa authorization server (Security->API-> chọn authorization server của bạn ->Access Policies). - Add a new access policy:
- Tên: ví dụ
API Client Access - Mô tả: ví dụ
Access policy for Halo API clients - Gán cho: API Services client đã tạo ở trên (tìm theo tên ứng dụng
glasswall-halo-apitừ bước 2)
- Tên: ví dụ
- Add a rule:
- Tên: ví dụ
Allow API Clients - Loại cấp quyền:
Client Credentials - Giữ các cài đặt khác ở mặc định hoặc điều chỉnh thời gian tồn tại của token nếu cần.
- Tên: ví dụ
Lưu ý: Access policy cho grant Client Credentials kiểm soát những client nào (theo
client_id) có thể yêu cầu token. Việc thuộc nhóm không áp dụng vì không có ngữ cảnh người dùng trong luồng này. Bảo mật quyền truy cập vào API bằng cách giới hạn những ai cóclient_idvàclient_secretthông qua trình quản lý bí mật của bạn.

Cấu hình dịch vụ API-Access cho Okta
Helm chart cdrplatform-api-access phải được cấu hình để xác thực Bearer token do authorization server Okta của bạn phát hành. Chart này cung cấp các cài đặt xác thực dưới khóa giá trị configuration.
Triển khai cấu hình
Lưu ý:
AuthorityvàValidIssuerđều phải được đặt thành URI issuer của Okta. Dịch vụ API-Access sử dụngAuthorityđể khám phá JWKS (JSON Web Key Set) nhằm xác thực chữ ký token, vàValidIssuerđể xác minh claimisstrong token.
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
Nhiều audience (tùy chọn)
Nếu nhiều API client hoặc ứng dụng cần truy cập Halo API với các audience khác nhau, hãy thêm các mục ValidAudiences bổ sung:
--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>"
Cách sử dụng Halo API
Lấy bearer token
Luồng Client Credentials (machine-to-machine)
Sử dụng luồng này cho các hệ thống tự động, pipeline CI/CD và các tích hợp service-to-service khi không cần tương tác của người dùng.
export TOKEN_ENDPOINT="${OKTA_ISSUER_URI}/v1/token"
Yêu cầu một 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"
Phản hồi ví dụ:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6Ikp...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "halo.api"
}
Trích xuất token:
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')
Xác thực các yêu cầu API
Bao gồm Bearer token trong header Authorization của mọi yêu cầu API:
export HALO_API_URL="https://<your-halo-domain>"
Xác minh xác thực
Kiểm tra bằng một endpoint được bảo vệ. Một yêu cầu không có token sẽ trả về 401, và một yêu cầu có token hợp lệ sẽ trả về 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"
Ví dụ: Gửi tệp để xử lý
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
Khắc phục sự cố
| Triệu chứng | Nguyên nhân | Cách khắc phục |
|---|---|---|
401 Unauthorized | Token đã hết hạn hoặc không hợp lệ | Yêu cầu token mới. Xác minh CLIENT_ID và CLIENT_SECRET là chính xác. |
401 Unauthorized với token hợp lệ | Không khớp audience | Đảm bảo ValidAudiences trong API-Access khớp với claim aud trong token. |
403 Forbidden với AdminRoleMissing | Thiếu vai trò Admin trong token | Cấu hình claim role trên authorization server (xem API Roles). Bắt buộc đối với các thao tác ghi quản lý giấy phép. |
| Yêu cầu token thất bại | URL endpoint token không chính xác | Xác minh ID authorization server và miền Okta. Kiểm tra /.well-known/openid-configuration. |
Lỗi invalid_scope | Các scope OIDC được dùng với Client Credentials | Sử dụng scope tùy chỉnh halo.api thay cho openid, profile hoặc email. |
Lỗi invalid_dpop_proof | DPoP chưa bị vô hiệu hóa | Vô hiệu hóa DPoP trên ứng dụng API Services (xem Disable DPoP). |
| Hết thời gian chờ mạng | Tường lửa hoặc proxy đang chặn | Đảm bảo ứng dụng khách API có thể truy cập cả endpoint token Okta và endpoint API Halo. |