ข้ามไปเนื้อหา
Enterprise SSO

OIDC กับ AWS IAM Identity Center

ตั้งค่า Single Sign-On (SSO) ระดับองค์กรสำหรับ Amazon Quick บนเดสก์ท็อป โดยใช้ OpenID Connect (OIDC) ร่วมกับ AWS IAM Identity Center เพื่อให้ผู้ใช้ในองค์กรเข้าสู่ระบบด้วยบัญชีของบริษัท

ข้อมูลตรวจกับเอกสารทางการของ AWS เมื่อ 17 ต.ค. 2026 แอปเดสก์ท็อปเปิดให้ใช้งานทั่วไป (GA) บน macOS และ Windows ตั้งแต่ 9 ก.ย. 2026

เลือกวิธีที่เหมาะกับคุณ

การเข้าสู่ระบบระดับองค์กรของ Amazon Quick Desktop ต้องมี OIDC provider เส้นทางที่ AWS ระบุไว้ในเอกสารคือใช้ IdP เดิมขององค์กร (Microsoft Entra ID, Google Workspace, Okta หรือ Ping Identity) ส่วนเส้นทาง Amazon Cognito เป็นวิธีแก้ชั่วคราวจากการใช้งานจริง

องค์กรของคุณมี OIDC identity provider อยู่แล้ว AWS มีคู่มือการตั้งค่าสำหรับ Microsoft Entra ID, Google Workspace, Okta และ Ping Identity (PingFederate และ PingOne) นี่คือเส้นทางที่มีในเอกสาร — เลือก identity provider ของคุณเพื่อไปยังขั้นตอนการตั้งค่า:

  เลือก identity provider ของคุณ

Google Workspace: ดูหมายเหตุ Google Workspace ในขั้นที่ 1

หรือดูภาพรวมก่อน (คู่มือ AWS มี 4 ขั้น: สร้างแอปใน IdP, เพิ่ม extension access, สร้าง extension, แจกจ่าย):

1

ขั้นที่ 1 — สร้าง OIDC application ใน IdP

ลงทะเบียน public OIDC client (authorization code + PKCE)

2

ไม่บังคับ — Trusted Token Issuer

ไม่อยู่ใน 4 ขั้นของคู่มือเดสก์ท็อปของ AWS ใช้เฉพาะเมื่อการออกแบบต้องการ (วิธี Cognito จะสร้างให้)

3

ขั้นที่ 3 — เพิ่ม extension access และสร้าง extension

ลงทะเบียน OIDC endpoint ในคอนโซลผู้ดูแล Amazon Quick แล้วสร้าง extension

4

ขั้นที่ 4 — ดาวน์โหลด ตรวจสอบ และแจกจ่าย

ทดสอบ Continue with SSO แล้วแจกจ่ายให้ผู้ใช้

วิธีแก้ชั่วคราว (ไม่ใช่วิธีที่ AWS ระบุไว้ในเอกสาร) คู่มือเดสก์ท็อปของ AWS ครอบคลุมเฉพาะการใช้ OIDC IdP ที่มีอยู่แล้ว รูปแบบ Amazon Cognito + proxy นี้เป็นวิธีที่ทีม AWS Thailand ใช้หน้างาน เพราะ Amazon Quick Desktop ส่ง scope offline_access มาด้วย ซึ่งเส้นทาง Cognito + IAM Identity Center ไม่รับ จึงต้องมี proxy ตัด scope นี้ออกก่อนคำขอจะถึง identity provider ควรทดสอบในบัญชีของคุณเองก่อนใช้งานจริง

ใช้เส้นทางนี้เมื่อยังไม่มี IdP เดิม: Amazon Quick แบบ local users (ไม่มี IAM Identity Center) หรือมี IAM Identity Center ที่จัดการผู้ใช้เองโดยไม่มี OIDC provider ภายนอก โดยจะ deploy Amazon Cognito เป็น OIDC provider ผ่าน CDK stack ตัวอย่าง

ทำไมต้องมี proxy? proxy ตัด offline_access ออกจากคำขอ /authorize — ดังนั้น Authorization Endpoint ต้องชี้ไปที่ proxy ไม่ใช่ Cognito hosted UI ทั้งนี้ Cognito ไม่ได้ใช้ scope offline_access ในการควบคุม refresh token แต่จะคืน refresh token ให้เมื่อใช้ authorization code grant (Cognito token endpoint)

2 วิธีในการสร้าง authorize proxy

proxy มีหน้าที่เดียว: ดักคำขอ /authorize ตัด scope offline_access ที่ไม่รองรับ (และถ้าต้องการ บังคับ identity_provider=IdentityCenter) แล้วส่งผู้ใช้ต่อไป Cognito ทำได้ 2 วิธี — เลือกตามว่าต้องการ logic มากแค่ไหน และจะป้องกันด้วยอะไร

Authorization Endpoint ชี้ไปที่ path บน CloudFront โดย CloudFront Function บน viewer-request เขียน query string ใหม่แล้ว return 302 ที่ edge — /authorize ไม่แตะ origin (Cognito) เลย

  • เร็วระดับ sub-millisecond ที่ edge ไม่มี cold start
  • ชิ้นส่วนน้อย: distribution + ฟังก์ชัน JS ตัวเดียว
  • แนบ WAF ได้ที่ distribution โดยตรง
  • ต้นทุนต่ำ (~$0.10 / ล้านคำขอ)
ทีม AWS Thailand เลือกใช้ (ไม่ใช่คำแนะนำของ AWS): งานคือแค่ตัด scope + redirect ซึ่ง CloudFront Function ทำได้ เป็น reference deployment ที่ทีมทดสอบแล้ว ดู Reference deployment ผ่าน CloudFront ด้านล่าง

AuthEndpoint = CloudFront URL · edge · ไม่มี cold start

Authorization Endpoint ชี้ไปที่ API Gateway HTTP API ทุกคำขอจะเรียก Lambda ที่เขียน query string ใหม่แล้ว return 302 ไปยัง Cognito hosted UI เป็นสิ่งที่ CDK stack สำเร็จรูป deploy ให้

  • runtime เต็ม — เรียก AWS API อื่น, lookup, crypto, async ได้
  • CloudWatch Logs เต็มรูปแบบ
  • เป็น CDK stack สำเร็จรูป deploy ได้เร็ว
ข้อควรระวัง: WAF แนบกับ API Gateway HTTP API ตรง ๆ ไม่ได้ ต้องเอา CloudFront มาคั่นหรือเปลี่ยนเป็น REST API — เลือกวิธีนี้เมื่อ logic ซับซ้อนเกินขีดจำกัดของ CloudFront Function

AuthEndpoint = API Gateway URL · runtime เต็ม · regional

ตารางเปรียบเทียบ

มิติOption 1 — API Gateway + LambdaOption 2 — CloudFront Function
ที่รันโค้ดRegional (1 Region)Edge (PoP ทั่วโลก)
LatencyLambda cold start + round trip เข้า regionSub-millisecond ไม่มี cold start
แตะ origin ที่ /authorize ไหมแตะ — คำขอเข้า endpoint จริงไม่แตะ — return 302 ที่ edge
Host-header / origin-request-policyต้องจัดการไม่มีปัญหา (ไม่ใช้ origin)
ชิ้นส่วนที่ต้องดูแลAPI Gateway + Lambda + IAM roleCloudFront distribution 1 ตัว + ฟังก์ชัน JS 1 ตัว
ขีดจำกัด computeruntime เต็ม — เรียก AWS API, crypto, async ได้จำกัดมาก: โค้ด ≤10 KB, ~1 ms CPU, เรียก network ไม่ได้, JS subset (cloudfront-js-2.0)
LoggingCloudWatch Logs เต็มรูปแบบจำกัด
ต้นทุนต่อคำขอLambda + API Gateway requestsถูกกว่า — CloudFront Function ~$0.10 / ล้าน
เหมาะกับlogic ที่เกินกว่าการ rewrite ธรรมดา (lookup, เรียก API อื่น)การ rewrite query string + 302 ล้วน ๆ (เคสนี้พอดี)

สิ่งที่เหมือนกันทั้ง 2 วิธี

  • proxy แค่ /authorize เท่านั้น — Token, JWKS และ Issuer endpoint ชี้ไป Cognito ตรง ๆ (token exchange เป็น POST ต้องถึง Cognito)
  • Refresh token ยังทำงานได้แม้ตัด offline_access — Cognito ออกให้ตาม refresh-token expiration ของ app client ไม่ผูกกับ scope
  • บังคับ federation ผ่าน IAM Identity Center โดยเพิ่ม identity_provider=IdentityCenter ในคำขอ authorization ของ Cognito หากดีไซน์นี้ใช้ Trusted Token Issuer บทบาทของ TTI คือ trusted identity propagation และ token exchange ไม่ใช่การกำหนดเส้นทาง sign-in

การเพิ่ม AWS WAF

ข้อจำกัดสำคัญ: AWS WAF แนบได้กับ CloudFront, API Gateway REST API, ALB, AppSync, Cognito user pool, App Runner และ Amplify — แต่ แนบกับ API Gateway HTTP API ไม่ได้ stack สำเร็จรูปใช้ HTTP API จึงแนบ WAF ตรง ๆ ไม่ได้
 Option 1 (API Gateway HTTP API)Option 2 (CloudFront)
แนบ WAF ตรง ๆ ได้ไหมไม่ได้ — HTTP API ไม่รองรับได้ — แนบที่ distribution
Web ACL scope / Regionต้องใช้ REST API (REGIONAL) หรือเอา CloudFront มาคั่นหน้าCLOUDFRONT scope — สร้างใน us-east-1
ลำดับการทำงานWAF → API Gateway → LambdaWAF ทำงาน ก่อน CloudFront Function

ทางเลือกของฝั่ง HTTP API: เอา CloudFront มาคั่นหน้าแล้วแนบ WAF ที่ CloudFront, เปลี่ยนไปใช้ REST API เพื่อใช้ WAF และ resource policy, หรือคง HTTP API แล้วใช้ IAM authorization, JWT/Lambda authorizer และ throttling (HTTP API ไม่รองรับ resource policy)

ป้องกัน Cognito ด้วย: เพราะ Token/JWKS วิ่งเข้า Cognito ตรง ๆ ควรแนบ WAF Web ACL ที่ Cognito user pool ด้วย (จำกัดอัตราความพยายาม login และกรองคำขอที่ไม่ต้องการ) หากต้องการป้องกัน credential stuffing และ account takeover โดยเฉพาะ ให้ประเมิน AWS WAF Fraud Control ATP หรือ Amazon Cognito threat protection แยกต่างหาก managed rule ที่ทีมใช้กับทั้ง 2 วิธี: AWSManagedRulesCommonRuleSet, AWSManagedRulesAmazonIpReputationList และ rate-based rule
ทีมเลือกใช้: สำหรับงานแคบ ๆ "ตัด scope" แบบนี้ ทีม AWS Thailand ใช้ Option 2 (CloudFront Function) เพราะง่ายกว่า เร็วกว่า ถูกกว่า และแนบ WAF ที่ distribution ได้ ส่วน Option 1 (API Gateway + Lambda) เป็นทางเลือกเมื่อต้องการ logic ที่เกินขีดจำกัดของ CloudFront Function ทั้งสองแบบไม่ใช่คำแนะนำของ AWS ขั้นตอนด้านล่างทำตาม CDK stack ตัวอย่าง (Option 1); ส่วน Reference deployment ผ่าน CloudFront คือ Option 2

stack นี้ deploy อะไรบ้าง

  • Amazon Cognito User Pool พร้อม hosted UI domain และ public app client
  • Secrets Manager secret ที่มี temporary password สำหรับผู้ใช้ใหม่
  • Trusted Token Issuer ใน IAM Identity Center (auto-discover; ข้ามถ้าไม่มี IDC instance)
  • API Gateway HTTP API + Lambda proxy ที่ตัด scope offline_access ที่ไม่รองรับ

สิ่งที่ต้องเตรียม

บัญชี AWS ที่มี Amazon Quick subscription (บัญชี Enterprise; home Region ต้องเป็น Region ที่มีแอปเดสก์ท็อป); Node.js 18+, AWS CDK CLI, Python 3.12+ พร้อม boto3 และ AWS credentials ที่ตั้งค่าแล้ว; ติดตั้งแอปเดสก์ท็อปไว้แล้ว

ขั้นที่ 1 — Deploy

cd proxy npm install cdk deploy

API Gateway HTTP API ไม่รองรับ resource policy หากต้องการจำกัด authorize endpoint ตาม source IP ให้เอา CloudFront และ AWS WAF มาคั่นหน้า HTTP API หรือเปลี่ยนเป็น REST API แล้วใช้ AWS WAF หรือ resource policy

ดึงค่า stack outputs:

aws cloudformation describe-stacks \ --stack-name QuickDesktopCognitoProxyStack \ --query "Stacks[0].Outputs" --output table

ขั้นที่ 2 — Sync ผู้ใช้

คัดลอกผู้ใช้เข้า Cognito User Pool (สคริปต์อ่าน pool ID และ temporary password จาก stack และถามยืนยันก่อนสร้างผู้ใช้แต่ละราย)

python3 scripts/sync_users.py --source quicksight # local users python3 scripts/sync_users.py # IAM Identity Center

ขั้นที่ 3 — ตั้งค่า extension access

ในคอนโซลผู้ดูแล Amazon Quick เลือก Manage account → Permissions → Extension access แล้วกรอกค่าจาก stack outputs จากนั้นในเมนูซ้ายของคอนโซล Amazon Quick เลือก Extensions (อยู่ใต้ More ถ้าไม่เห็น) แล้วสร้าง extension

FieldStack output
Trusted Token Issuer ARN (เฉพาะ IDC)TtiArn
Aud claimClientId
Issuer URLIssuerUrl
Authorization EndpointAuthEndpoint (API Gateway)
Token EndpointTokenEndpoint
JWKS URIJwksUri
Client IDClientId

ขั้นที่ 4 — เข้าสู่ระบบ

เปิดแอปเดสก์ท็อปแล้วเลือก Continue with SSO เข้าสู่ระบบด้วย username หรือ email และ temporary password — ระบบจะให้ตั้งรหัสผ่านใหม่ในครั้งแรก

ข้อควรพิจารณาด้านความปลอดภัย

ปกป้อง API Gateway: HTTP API เปิด public endpoint โดยค่าเริ่มต้น หากต้องการ AWS WAF ให้เอา CloudFront มาคั่นหน้าหรือเปลี่ยนเป็น REST API สำหรับ HTTP API โดยตรง ให้ใช้ IAM authorization, JWT/Lambda authorizer และ throttling ตามความเหมาะสม สคริปต์ sync_users.py เป็น stop-gap แบบทำมือ สำหรับ production ให้ใช้กระบวนการ provisioning ที่องค์กรอนุมัติและทดสอบ lifecycle ของผู้ใช้แบบ end-to-end

การแก้ปัญหา

ปัญหาสาเหตุ / วิธีแก้
redirect_mismatchCallback URL ต้องเป็น http://localhost:18080 (stack ตั้งให้อัตโนมัติ)
invalid_scopeAuthorization Endpoint ต้องชี้ไป API Gateway (AuthEndpoint) ไม่ใช่ Cognito hosted UI
หาผู้ใช้ไม่พบอีเมลใน Cognito ต้องตรงกับอีเมลผู้ใช้ใน Amazon Quick ทุกตัวอักษร
ค่าตั้งค่าเก่าค้างหลังแก้ไขเคลียร์ cached profiles ใน ~/.quickwork/ (ดูด้านล่าง)
เคลียร์ cache ~/.quickwork (สิ่งที่ทีมพบ): AWS ระบุว่า ~/.quickwork/ (macOS) และ %USERPROFILE%\.quickwork\ (Windows) คือโฟลเดอร์เก็บการตั้งค่าในเครื่อง ทีมพบว่าแอปแคช OIDC config ไว้ที่ ~/.quickwork/profiles.json และค้างอยู่แม้ติดตั้งใหม่ หลังตั้งค่า extension access ใหม่ ให้ลบ entry ของ profile enterprise ออก เพื่อให้แอปใช้ค่าใหม่

วิธี Cognito นี้เป็นวิธีแก้ชั่วคราวสำหรับสภาพแวดล้อมที่ไม่มี IdP และไม่ใช่วิธีที่ AWS ระบุไว้ในเอกสาร หากมี IdP เดิมอยู่แล้ว ให้ใช้แท็บ มี IdP อยู่แล้ว ดูตัวอย่าง deployment จริงด้วย CloudFront ได้ที่หัวข้อ เคสตัวอย่างจริง — Cognito + Identity Center ผ่าน CloudFront ด้านล่าง ดูเพิ่มเติมที่ public enterprise setup guide

ภาพรวม — การเข้าสู่ระบบระดับองค์กรทำงานอย่างไร

ใช้กับ: Enterprise Edition (ถ้าใช้บัญชี Free หรือ Plus ขั้นตอนนี้ไม่เกี่ยวกับคุณ) · กลุ่มเป้าหมาย: ผู้ดูแลระบบ. ที่มา: เอกสาร AWS

แอป Amazon Quick บนเดสก์ท็อปใช้โปรโตคอล OIDC ในการยืนยันตัวตนผู้ใช้ เมื่อผู้ใช้เลือก Continue with SSO เบราว์เซอร์จะเปิดไปที่ Amazon Quick ซึ่งจะหา identity provider ที่ตั้งค่าไว้แล้ว redirect ไปยัง authorization endpoint ของ IdP โดยเบราว์เซอร์ต้องมี web session ของ Amazon Quick อยู่ ถ้ายังไม่มีจะให้เข้าสู่ระบบ Amazon Quick ก่อน จากนั้นแอปแลก authorization code เป็น token ด้วย Proof Key for Code Exchange (PKCE) แล้ว Amazon Quick จะตรวจสอบ token และจับคู่ผู้ใช้กับตัวตนในบัญชีของคุณ โดยอีเมลใน IdP ต้องตรงกันทุกตัวอักษรกับอีเมลของผู้ใช้ใน Amazon Quick

1. Continue with SSO

ผู้ใช้เลือก Continue with SSO ในแอปเดสก์ท็อป

2. Redirect ไป IdP

เบราว์เซอร์เปิด authorization endpoint ของ IdP

3. Auth code + PKCE

แลก code เป็น token (ไม่ใช้ client secret)

4. ตรวจสอบ & จับคู่

Quick ตรวจ token และจับคู่ด้วยอีเมล

ข้อกำหนด Region: home region (identity region) ของบัญชี Amazon Quick ต้องเป็น Region ที่รองรับ แอปเดสก์ท็อปใช้ได้กับบัญชี Enterprise ใน Region ที่มีฟีเจอร์ Amazon Quick ครบ ส่วน Region ที่มีแค่ Amazon Quick Sight จะไม่มีเดสก์ท็อป ปัจจุบันแอปเดสก์ท็อปมีใน 7 Region: US East (N. Virginia), US West (Oregon), Asia Pacific (Sydney), Asia Pacific (Tokyo), Europe (Ireland), Europe (London) และ Europe (Frankfurt) — ยังไม่มีใน Singapore และ Thailand รองรับทุกประเภทตัวตน: IAM Identity Center, IAM federation และ native Amazon Quick (username/password)
การ sign token: IdP ต้อง sign ID token ด้วยอัลกอริทึมแบบ asymmetric (RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384, ES512) ระบบไม่รับ token ที่ sign ด้วย HMAC (HS256/HS384/HS512) หรือไม่ได้ sign

สิ่งที่ต้องเตรียม

ตรวจสอบรายการต่อไปนี้ก่อนเริ่ม

รายการรายละเอียด
บัญชี AWS & subscriptionบัญชี AWS ที่มี Amazon Quick subscription ที่ใช้งานได้ (บัญชี Enterprise) โดย home region (identity region) ต้องเป็น Region ที่มีแอปเดสก์ท็อป (ดูหมายเหตุ Region ด้านบน)
สิทธิ์ผู้ดูแลระบบสิทธิ์ระดับ administrator ในบัญชี Amazon Quick ของคุณ
สิทธิ์บน IdPเข้าถึง IdP ขององค์กรได้ พร้อมสิทธิ์สร้าง OIDC application registration
การเข้าถึงเครือข่ายในเครือข่ายที่จำกัด ต้องเปิด allow list โดเมนของ Amazon Quick และ IdP ดู Network access and required domains
IAM Identity Center (ถ้ามี)คู่มือเดสก์ท็อปของ AWS ไม่มีขั้นสร้าง Trusted Token Issuer (TTI) ส่วนวิธี Cognito ในหน้านี้จะสร้าง TTI ให้ ดูหัวข้อ Identity Center ด้านล่าง

ขั้นที่ 1 — สร้าง OIDC application ใน IdP ของคุณ

ลงทะเบียน public OIDC client (authorization code flow พร้อม PKCE ไม่ใช้ client secret — ยกเว้น Google Workspace ดูด้านล่าง) ให้สิทธิ์ offline_access (Entra ID, Okta, Ping) เพื่อให้ IdP ออก refresh token ถ้าไม่มี ผู้ใช้ต้องยืนยันตัวตนใหม่บ่อย

ค่าตั้งค่าร่วม

Redirect URI: http://localhost:18080
Client type: Public / Native (ไม่มี secret)
Grant types: Authorization Code + Refresh Token
PKCE: จำเป็น (S256)
Scopes: openid email profile offline_access

Refresh token

Entra ID: ให้สิทธิ์ offline_access
Okta: เปิด Refresh Token grant + offline_access
Ping: เปิด Refresh Token grant + offline_access สำหรับ PingFederate ต้องเปิด Return ID Token On Refresh Grant ด้วย
Google Workspace: ไม่ต้องเพิ่ม scope Quick ใส่ access_type=offline ให้อัตโนมัติ

Google Workspace (ตามคู่มือ AWS): ใน Google Cloud Console สร้าง OAuth client ID ชนิด Desktop app ตั้ง User type ของ consent screen เป็น Internal และเพิ่ม scope openid, email, profile Endpoint: Issuer https://accounts.google.com; Authorization https://accounts.google.com/o/oauth2/v2/auth; Token https://oauth2.googleapis.com/token?client_secret=<CLIENT_SECRET> (ต่อ client secret เป็น query parameter); JWKS https://www.googleapis.com/oauth2/v3/certs ขั้นตอนเต็ม: คู่มือ Google Workspace
1

New registration

Azure portal → Microsoft Entra ID → App registrations → New registration ตั้งชื่อ Amazon Quick Desktop; Supported account types: Single tenant; Redirect URI platform: Public client/native (mobile & desktop); Redirect URI: http://localhost:18080 แล้วเลือก Register

2

จด ID ไว้

ที่หน้า Overview จด Application (client) ID และ Directory (tenant) ID

3

API permissions

เพิ่ม Microsoft Graph → Delegated permissions: openid, email, profile, offline_access และ Grant admin consent หากองค์กรกำหนด

4

Authentication settings

ใน Advanced settings ให้คง Allow public client flows เป็น No ตรวจว่ามี http://localhost:18080 อยู่ใต้ Mobile and desktop applications แล้ว Save (Entra ID บังคับ PKCE ให้ public client อัตโนมัติ)

5

Token configuration (จำเป็น)

Token configuration → Add optional claim → token type ID → email และผู้ใช้ทุกคนต้องมีค่า Mail ในโปรไฟล์ Entra ID ใช้แค่ UPN ไม่พอ

Issuer URL ต้องมี /v2.0 ต่อท้าย (อย่าใช้ Authority URL จากหน้า Endpoints) ถ้าแอปมี custom signing key จาก claims mapping ให้ต่อ ?appid=<CLIENT_ID> ท้าย JWKS URI

Fieldค่า (แทน <TENANT_ID>)
Issuer URLhttps://login.microsoftonline.com/<TENANT_ID>/v2.0
Authorization endpointhttps://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/authorize
Token endpointhttps://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/token
JWKS URIhttps://login.microsoftonline.com/<TENANT_ID>/discovery/v2.0/keys
1

Create App Integration

Okta Admin Console → Applications → Applications → Create App Integration; Sign-in method: OIDC - OpenID Connect; Application type: Native Application

2

ตั้งค่า

ชื่อ Amazon Quick Desktop; Grant type: Authorization Code + Refresh Token; Sign-in redirect URI: http://localhost:18080; assign ให้ผู้ใช้/กลุ่มที่เหมาะสม แล้ว Save และจด Client ID

3

ตรวจค่าตั้ง

ที่แท็บ General ตรวจว่า application type เป็น Native, client authentication เป็น None (public client), PKCE เป็น Required และมี http://localhost:18080 ใต้ LOGIN โดย Quick จะขอ scope openid, profile, email, offline_access ตอน sign-in

Fieldค่า (แทน <OKTA_DOMAIN> เช่น your-org.okta.com — ไม่ใช่ subdomain -admin)
Issuer URLhttps://<OKTA_DOMAIN>
Authorization endpointhttps://<OKTA_DOMAIN>/oauth2/v1/authorize
Token endpointhttps://<OKTA_DOMAIN>/oauth2/v1/token
JWKS URIhttps://<OKTA_DOMAIN>/oauth2/v1/keys
1

Add client

Applications → OAuth → Clients → Add Client ใส่ Client ID ที่ไม่ซ้ำ; Name: Amazon Quick Desktop; Client Authentication: None; Redirection URI: http://localhost:18080

2

Grants, PKCE, scopes

Allowed Grant Types: Authorization Code + Refresh Token; เลือก Require PKCE; ให้ scope openid, email, profile, offline_access แล้ว Save และจด Client ID

3

OIDC policy

Applications → OAuth → OpenID Connect Policy Management เลือก Return ID Token On Refresh Grant และตรวจว่า claim email อยู่ใน Attribute Contract และถูก map ทั้งตอน initial auth และ refresh grant

Fieldค่า (แทน <PINGFEDERATE_HOST>)
Issuer URLhttps://<PINGFEDERATE_HOST>
Authorization endpointhttps://<PINGFEDERATE_HOST>/as/authorization.oauth2
Token endpointhttps://<PINGFEDERATE_HOST>/as/token.oauth2
JWKS URIhttps://<PINGFEDERATE_HOST>/pf/JWKS
1

สร้าง application

PingOne admin console → Applications → +; ชื่อ Amazon Quick Desktop; Application Type: Native แล้ว Save

2

Configuration

Response Type: Code; Grant Type: Authorization Code + Refresh Token; PKCE Enforcement: S256; Redirect URIs: http://localhost:18080; Token Endpoint Authentication Method: None แล้ว Save

3

Scopes, attributes, enable

แท็บ Resources (แยกจากแท็บ Configuration): เพิ่ม openid, email, profile, offline_access — PingOne ให้แค่ openid เป็นค่าเริ่มต้น ถ้าข้ามขั้นนี้จะเจอ "User info request failed (HTTP 401)"; แท็บ Attribute Mappings: map email ให้ตรงกับอีเมลผู้ใช้; เปิดแอปเป็น Enabled และจด Client ID กับ Environment ID สำหรับ JWKS ใช้ /as/jwks ไม่ใช่ /.well-known/jwks.json

Fieldค่า (แทน <ENV_ID>; โดเมนต่างกันตาม region)
Issuer URLhttps://auth.pingone.com/<ENV_ID>/as
Authorization endpointhttps://auth.pingone.com/<ENV_ID>/as/authorize
Token endpointhttps://auth.pingone.com/<ENV_ID>/as/token
JWKS URIhttps://auth.pingone.com/<ENV_ID>/as/jwks

ไม่บังคับ — Trusted Token Issuer ใน IAM Identity Center

ไม่ได้อยู่ในคู่มือการตั้งค่าเดสก์ท็อปของ AWS ซึ่งมี 4 ขั้น (แอปใน IdP, extension access, extension, แจกจ่าย) สำหรับทุกประเภทตัวตนรวมถึง IAM Identity Center วิธี Cognito ในหน้านี้จะสร้าง TTI ให้ ให้เพิ่มเองเฉพาะเมื่อการออกแบบต้องการ Trusted Token Issuer (TTI) ทำให้ IAM Identity Center เชื่อถือ OIDC token จาก issuer ภายนอก (trusted identity propagation) ที่มา: เอกสาร AWS

1

เปิด Settings → Authentication

ในคอนโซล IAM Identity Center เลือก Settings แล้วไปที่แท็บ Authentication ใต้หัวข้อ Trusted token issuers เลือก Create trusted token issuer

2

Issuer URL (OIDC discovery)

ที่ช่อง Issuer URL ใส่ OIDC discovery URL ของ IdP จนถึงส่วนก่อนหน้า .well-known/openid-configuration (ไม่รวมส่วนนี้) และต้องตรงกับ claim iss ใน token โดย discovery endpoint ต้องเข้าถึงได้ผ่านพอร์ต 80 และ 443 เท่านั้น

3

Map attributes

ใต้ Map attributes เลือก Identity provider attribute (claim ใน token เช่น email) และ IAM Identity Center attribute ที่ใช้ค้นหาผู้ใช้รายเดียวใน Identity Center directory

4

สร้าง & แจ้งทีม

ตั้ง Trusted token issuer name แล้วเลือก Create trusted token issuer จากนั้นแจ้งผู้ดูแลแอปพลิเคชันให้เลือก TTI นี้และตั้งค่า token exchange (รวมถึงค่า claim Aud ของ AWS service ปลายทาง)

Aud (audience) claim: TTI จะใส่ claim Aud ใน token เพื่อระบุ AWS service ปลายทาง ผู้ดูแล IdP ภายนอกจะให้ค่านี้แก่ผู้ดูแล AWS service เพื่อตั้งค่า token exchange ให้ยอมรับค่าดังกล่าว
การแก้ไข TTI อาจทำให้ผู้ใช้สูญเสียการเข้าถึงแอปที่ใช้ TTI นั้น ควรประสานกับผู้ดูแลแอปก่อนแก้ไข issuer URL, attribute mapping หรือ tag

ขั้นที่ 3 — เพิ่ม extension access และสร้าง extension

ลงทะเบียน OIDC endpoint จากขั้นที่ 1 เพื่อให้แอปเดสก์ท็อปยืนยันตัวตนได้ ต้องทำทั้งสองส่วน

1

Add extension access

เข้าสู่คอนโซลผู้ดูแล Amazon Quick แล้วเลือก Manage account → ใต้ Permissions เลือก Extension access → Add extension access ที่ Select Service เลือก Amazon Quick (Desktop application for Quick) แล้วเลือก Next

2

กรอกข้อมูล OIDC

กรอกค่าตามตารางด้านล่างด้วยค่าจากขั้นที่ 1 แล้วเลือก Add

3

สร้าง extension

ในเมนูซ้ายของคอนโซล Amazon Quick เลือก Extensions (เลือก More ถ้าไม่เห็น) → Add extension เลือก extension access แบบ Desktop application for Quick ที่สร้างไว้ → Next → Create ถ้าไม่ทำขั้นนี้ ผู้ใช้จะเห็นข้อความ "Enterprise sign-in for Quick Desktop has not been configured for this account." ทำครั้งเดียวต่อบัญชี

Fieldค่า
Nameชื่อสำหรับ extension access นี้ (เช่น QuickDesktop-access) ใช้ตัวอักษร ตัวเลข และขีดกลางเท่านั้น ห้ามเว้นวรรค
Description(ไม่บังคับ) คำอธิบาย
Issuer URLOIDC issuer URL จากขั้นที่ 1 แบบตรงทุกตัว รวม path ที่ต้องต่อท้าย
Authorization EndpointOIDC authorization endpoint จากขั้นที่ 1
Token EndpointOIDC token endpoint จากขั้นที่ 1
JWKS URIJSON Web Key Set URI จากขั้นที่ 1
Client IDOIDC client identifier จากขั้นที่ 1
แก้ไขไม่ได้: ตรวจสอบทุกค่าก่อนเลือก Add เพราะ extension access ไม่สามารถแก้ไขหลังสร้างได้ หากค่าใดผิดต้องลบแล้วสร้างใหม่

ขั้นที่ 4 — ดาวน์โหลด ตรวจสอบ และแจกจ่าย

ยืนยันว่าตั้งค่าถูกต้อง แล้วจึงแจกจ่ายให้ผู้ใช้

1

ดาวน์โหลดและทดสอบ Continue with SSO

ในคอนโซล Amazon Quick เลือก Extensions เลือก extension Quick Desktop เปิดเมนู (...) แล้วเลือก Download for Windows หรือ Download for Mac ติดตั้งแอป เลือก Continue with SSO ที่หน้าจอเข้าสู่ระบบ (เลือก AWS Region หรือ Dynamic ได้) แล้วยืนยันตัวตนด้วยบัญชีบริษัท

2

แก้ค่าที่ผิด

หากเข้าสู่ระบบไม่สำเร็จ ให้ตรวจค่าจากขั้นที่ 3 เทียบกับ endpoint ในขั้นที่ 1 หากค่าใดผิด ให้ลบ extension access ที่ Permissions → Extension access แล้วทำขั้นที่ 3 ใหม่

3

แจกจ่ายให้ผู้ใช้

แนะนำผู้ใช้ไปที่คู่มือการติดตั้ง ผู้ใช้เลือก Continue with SSO ได้เลยโดยไม่ต้องตั้งค่ารายคน ถ้าจะติดตั้งแบบเงียบทั้งองค์กร ดู Managed deployment configuration (ติดตั้งแบบเงียบบน Windows สำหรับผู้ใช้คนเดียว: .\Amazon-Quick-Setup.exe /S)

เคสตัวอย่างจริง — Cognito + Identity Center ผ่าน CloudFront

วิธีแก้ชั่วคราว (ไม่ใช่วิธีที่ AWS ระบุไว้ในเอกสาร) นี่คือรูปแบบที่ทีม AWS Thailand ใช้หน้างาน ไม่ใช่การตั้งค่าที่ AWS ระบุหรือแนะนำ Amazon Quick Desktop ส่ง scope offline_access มาด้วย ซึ่งเส้นทาง Cognito + IAM Identity Center นี้ไม่รับ CloudFront Function จึงตัด scope ออกก่อนคำขอจะถึง identity provider หากต้องการเส้นทางที่มีในเอกสาร ให้ใช้คู่มือ AWS ของ IdP คุณ (Entra ID, Google Workspace, Okta, Ping Identity)

รูปแบบที่ทีมทดสอบแล้วของเส้นทาง Cognito แทนที่จะใช้ API Gateway + Lambda proxy ใช้ CloudFront Function ตัวเดียว return 302 ที่ edge — ตัด offline_access และบังคับ federate ผ่าน IAM Identity Center โดย /authorize ไม่แตะ origin เลย จึงไม่ต้องห่วงเรื่อง Host header หรือ origin request policy ค่าที่ระบุตัวตนทั้งหมดด้านล่างถูก mask ไว้

Trust chain แบบ end-to-end

Amazon Quick Desktop บัญชี consumer · public client + PKCE · callback http://localhost:18080 AuthEndpoint = CloudFront /oauth2/authorize CloudFront Function — viewer-request strip offline_access · add identity_provider=IdentityCenter return HTTP 302 ที่ edge (ไม่แตะ origin) HTTP 302 redirect (browser ตาม Location) Amazon Cognito user pool OIDC provider ให้ Amazon Quick · ออก token SAML federation (identity_provider=IdentityCenter) IAM Identity Center authentication จริง · custom-SAML app · identity store Cognito-issued JWT Trusted identity propagation (Trusted Token Issuer) IAM Identity Center เชื่อ JWT ที่ Cognito ออก ผ่าน Trusted Token Issuer (OIDC_JWT) จากนั้น application ของ Amazon Quick (QuickSight) ได้รับ token-exchange / trusted identity propagation

authorize ถูก rewrite ที่ CloudFront edge; Token / JWKS / Issuer ยิงตรงไป Cognito

องค์ประกอบ

CloudFront Function (ตัด offline_access + บังคับ IdC)

// cloudfront-js-2.0 | event: viewer-request | path: /oauth2/authorize function handler(event) { var COGNITO_AUTHORIZE = 'https://us-east-1XXXXXXXXX.auth.us-east-1.amazoncognito.com/oauth2/authorize'; var qs = event.request.querystring; // ค่า scope มาแบบ URL-encoded; token คั่นด้วย %20 หรือ + // ตัด "offline_access" โดยคงตัวคั่นเดิมไว้ if (qs.scope && qs.scope.value) { var raw = qs.scope.value; var sep = raw.indexOf('%20') >= 0 ? '%20' : (raw.indexOf('+') >= 0 ? '+' : ' '); var toks = raw.split(sep); var kept = []; for (var i = 0; i < toks.length; i++) { if (toks[i] && toks[i] !== 'offline_access') kept.push(toks[i]); } qs.scope = { value: kept.join(sep) }; } // บังคับ sign-in ตรงผ่าน IAM Identity Center qs['identity_provider'] = { value: 'IdentityCenter' }; var pairs = []; for (var key in qs) { var item = qs[key]; if (item.multiValue) { for (var j = 0; j < item.multiValue.length; j++) pairs.push(key + '=' + item.multiValue[j].value); } else { pairs.push(key + '=' + item.value); } } return { statusCode: 302, statusDescription: 'Found', headers: { 'location': { value: COGNITO_AUTHORIZE + '?' + pairs.join('&') }, 'cache-control': { value: 'no-store' } } }; }

ค่าที่ต้องตั้งใน Amazon Quick (Extension access)

Fieldค่า
Authorization Endpointhttps://dXXXXXXXXXXXXX.cloudfront.net/oauth2/authorize — CloudFront
Token Endpointhttps://us-east-1XXXXXXXXX.auth.us-east-1.amazoncognito.com/oauth2/token — Cognito (ตรง)
Issuer URLhttps://cognito-idp.us-east-1.amazonaws.com/us-east-1_XXXXXXXXX — Cognito (ตรง)
JWKS URI.../us-east-1_XXXXXXXXX/.well-known/jwks.json — Cognito (ตรง)
Aud claim / Client ID<PUBLIC_CLIENT_ID>

ทดสอบ (curl ยิงเข้า distribution จริง)

$ curl -i "https://dXXXXXXXXXXXXX.cloudfront.net/oauth2/authorize?\ client_id=<PUBLIC_CLIENT_ID>&response_type=code&\ scope=openid+email+profile+offline_access&\ redirect_uri=http://localhost:18080&\ code_challenge=...&code_challenge_method=S256" HTTP/2 302 x-cache: FunctionGeneratedResponse from cloudfront cache-control: no-store location: https://us-east-1XXXXXXXXX.auth.us-east-1.amazoncognito.com/oauth2/authorize?... &scope=openid+email+profile&identity_provider=IdentityCenter

→ offline_access ถูกตัด, บังคับ federate ผ่าน IAM Identity Center, และ code_challenge (PKCE) ส่งผ่านครบ

ทำไมใช้ function 302 แทน API Gateway proxy? CloudFront Function return redirect ที่ edge เลย (FunctionGeneratedResponse) origin ของ Cognito ไม่ถูกเรียกใน /authorize — ไม่ต้อง rewrite Host header, ไม่ต้องมี origin request policy, sub-millisecond และไม่มี Lambda cold start
Refresh token ยังทำงานแม้ไม่มี offline_access: Cognito ไม่ได้ใช้ scope offline_access ควบคุม refresh token แต่จะคืน refresh token ให้เมื่อใช้ authorization code grant และกำหนดอายุด้วยค่า refresh-token validity ของ app client (Cognito token endpoint) การตัด scope ออกจึงเลี่ยง invalid_scope ได้โดยไม่ทำให้ session สั้นลง
Token / JWKS / Issuer ต้องชี้ Cognito ตรงๆ — ไม่ใช่ CloudFront: distribution อนุญาตแค่ GET/HEAD และ function จะ 302 ทุก request ส่วน token exchange เป็น POST ต้องยิงเข้า Cognito โดยตรง
การบังคับ identity_provider=IdentityCenter ทำให้ทุก sign-in วิ่งผ่าน IAM Identity Center (ไม่มี local Cognito users ตรงๆ) ถ้าต้องการ break-glass local admin ต้องทำ path แยก
สำหรับ production: เพิ่ม custom domain (ACM certificate ใน us-east-1) และ AWS WAF Web ACL ให้ distribution ส่วน domain *.cloudfront.net default ใช้ทดสอบได้

การแก้ปัญหา

ปัญหาที่พบบ่อยและวิธีแก้ (จากคู่มือแก้ปัญหาของ AWS) เคล็ดลับ: export log ของแอปได้จากหน้าจอเข้าสู่ระบบ

อาการวิธีแก้
ข้อผิดพลาด redirect_mismatchตรวจว่า redirect URI ใน IdP เป็น http://localhost:18080 ตรงเป๊ะ และตั้งเป็น public client / native platform
หาผู้ใช้ไม่พบหลังเข้าสู่ระบบtoken ต้องมี email claim (Entra ID: เพิ่ม optional claim email และกรอกค่า Mail ให้ผู้ใช้) และต้องตรงกับผู้ใช้ใน Amazon Quick ทุกตัวอักษร การจับคู่อีเมลแยกตัวพิมพ์เล็ก-ใหญ่
Token validation ล้มเหลวตรวจว่า issuer URL ใน extension access ตรงกับ OIDC issuer ของ IdP ทุกตัวอักษร และ IdP sign ID token ด้วยอัลกอริทึม asymmetric ที่รองรับ (ไม่ใช่ HMAC)
Invalid issuer (Entra ID)Issuer URL ต้องมี /v2.0 ให้ลบ extension access แล้วสร้างใหม่ด้วยค่าที่ถูก
Enterprise sign-in not configured for this accountมี extension access แล้วแต่ยังไม่ได้สร้าง extension ให้สร้างที่หน้า Extensions (ขั้นที่ 3)
User info request failed (HTTP 504)เป็น timeout ชั่วคราวฝั่ง backend ให้เข้าสู่ระบบ Amazon Quick ในเว็บเบราว์เซอร์ก่อน แล้วลองเข้าแอปเดสก์ท็อปอีกครั้ง และตรวจการเข้าถึงโดเมนที่จำเป็น
Access blocked: app not verified (Google Workspace)ตั้ง User type ของ OAuth consent screen เป็น Internal
Consent / permission error (Entra ID)Grant admin consent ให้ API permission ที่ต้องการในพอร์ทัล Azure (app registration → API permissions)
Session หมดอายุบ่อยตรวจว่า IdP ออก refresh token: Entra ID ต้องมี offline_access; Okta และ Ping ต้องเปิด Refresh Token grant และ offline_access; Google จัดการให้อัตโนมัติ สำหรับ PingFederate ต้องเปิด Return ID Token On Refresh Grant ด้วย
User info request failed (HTTP 401) (PingOne)เพิ่ม email, profile, offline_access ที่แท็บ Resources ของแอป
Token validation ล้มเหลวกับ JWKS ของ PingOneใช้ path /as/jwks ไม่ใช่ /.well-known/jwks.json
Application ไม่ได้เปิดใช้ (PingOne)หากยืนยันตัวตนล้มเหลวก่อนถึงหน้า login ให้ตรวจว่า toggle ของแอปตั้งเป็น Enabled
ไม่มี email claim หลัง refresh (PingFederate)ตรวจว่า claim email อยู่ใน OIDC policy Attribute Contract และ map ทั้งตอน initial auth และ refresh grant

แหล่งอ้างอิง

เอกสารทางการของ AWS ที่ใช้ในหน้านี้