Chuyển đến nội dung chính

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

  1. Đăng nhập vào Okta Admin Console.
  2. Đi tới Applications -> Applications -> Create App Integration -> API Services.

Screenshot: Create API Services application in Okta

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

Screenshot: API service app name in Okta

Tắt DPoP (proof of possession)

  1. Đi tới tab General của ứng dụng -> phần General Settings -> nhấp vào Edit.
  2. Trong mục Proof of possession, bỏ chọn Require Demonstrating Proof of Possession (DPoP) header in token requests.
  3. 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.

Screenshot: Disable DPoP in Okta application settings

Cấu hình thông tin xác thực của client

  1. Ghi lại Client ID và tạo một Client 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.

Screenshot: Client ID and secret from Okta application

Cấu hình vai trò (tùy chọn)

  1. 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

  1. 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

  1. Đi tới tab Access Policies của authorization server (Security -> API -> chọn authorization server của bạn -> Access Policies).
  2. 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-api từ bước 2)
  3. 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.

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_idclient_secret thông qua trình quản lý bí mật của bạn.

Screenshot: API access policy on authorization server

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 ý: AuthorityValidIssuer đều phải được đặt thành URI issuer của Okta. Dịch vụ API-Access sử dụng Authority để khám phá JWKS (JSON Web Key Set) nhằm xác thực chữ ký token, và ValidIssuer để xác minh claim iss trong 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ứngNguyên nhânCách khắc phục
401 UnauthorizedToken đã hết hạn hoặc không hợp lệYêu cầu token mới. Xác minh CLIENT_IDCLIENT_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 AdminRoleMissingThiếu vai trò Admin trong tokenCấ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ạiURL endpoint token không chính xácXác minh ID authorization server và miền Okta. Kiểm tra /.well-known/openid-configuration.
Lỗi invalid_scopeCác scope OIDC được dùng với Client CredentialsSử dụng scope tùy chỉnh halo.api thay cho openid, profile hoặc email.
Lỗi invalid_dpop_proofDPoP chưa bị vô hiệu hóaVô hiệu hóa DPoP trên ứng dụng API Services (xem Disable DPoP).
Hết thời gian chờ mạngTườ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.