JWT (Json Web Token) "ผู้ชม" กับ Client_Id - ความแตกต่างคืออะไร?


103

ฉันกำลังดำเนินการติดตั้ง OAuth 2.0 JWT access_token ในเซิร์ฟเวอร์การตรวจสอบสิทธิ์ของฉัน แต่ฉันไม่ชัดเจนว่าความแตกต่างระหว่างการaudอ้างสิทธิ์JWT และclient_idค่าส่วนหัว HTTP คืออะไร พวกเดียวกันหรือเปล่า? ถ้าไม่คุณสามารถอธิบายความแตกต่างระหว่างทั้งสองได้หรือไม่?

ความสงสัยของฉันคือaudควรอ้างถึงเซิร์ฟเวอร์ทรัพยากรและclient_idควรอ้างถึงแอปพลิเคชันไคลเอนต์ตัวใดตัวหนึ่งที่เซิร์ฟเวอร์รับรองความถูกต้อง (เช่นเว็บแอปหรือแอป iOS)

ในกรณีปัจจุบันเซิร์ฟเวอร์ทรัพยากรของฉันยังเป็นไคลเอนต์เว็บแอปของฉัน

คำตอบ:


133

ปรากฎว่าความสงสัยของฉันถูกต้อง การaudอ้างสิทธิ์ของผู้ชมใน JWT หมายถึงการอ้างถึงเซิร์ฟเวอร์ทรัพยากรที่ควรยอมรับโทเค็น

ตามที่โพสต์นี้ใส่ไว้:

ผู้ชมของโทเค็นคือผู้รับที่ต้องการของโทเค็น

ค่าผู้ชมเป็นสตริง - https://contoso.comโดยทั่วไปที่อยู่ฐานของทรัพยากรที่มีการเข้าถึงเช่น

client_idใน OAuth หมายถึงโปรแกรมไคลเอนต์ที่จะร้องขอทรัพยากรจากทรัพยากรของเซิร์ฟเวอร์

แอปไคลเอ็นต์ (เช่นแอป iOS ของคุณ) จะขอ JWT จากเซิร์ฟเวอร์การตรวจสอบสิทธิ์ของคุณ ในการดำเนินการนี้จะส่งผ่านclient_idและclient_secretไปพร้อมกับข้อมูลรับรองผู้ใช้ที่อาจจำเป็น การอนุญาตเซิร์ฟเวอร์ตรวจสอบลูกค้าใช้client_idและclient_secretและผลตอบแทน JWT

JWT จะมีการaudอ้างสิทธิ์ที่ระบุว่าเซิร์ฟเวอร์ทรัพยากรใดที่ JWT ใช้ได้ หากaudมีwww.myfunwebapp.comแต่แอปไคลเอ็นต์พยายามใช้ JWT เปิดwww.supersecretwebapp.comการเข้าถึงจะถูกปฏิเสธเนื่องจากเซิร์ฟเวอร์ทรัพยากรนั้นจะเห็นว่า JWT ไม่ได้มีไว้สำหรับใช้งาน


6
ดูเหมือนว่า aud อาจเป็น client_id ด้วย ดูtools.ietf.org/id/draft-hunt-oauth-v2-user-a4c-01.txt aud REQUIRED for session_token. Contains the client_id of the client receiving the assertion.
themihai

1
เซิร์ฟเวอร์รีซอร์สไม่ทราบว่าไคลเอนต์ส่ง JWT ไปที่ใด เซิร์ฟเวอร์ทรัพยากรจะปฏิเสธการรับส่งข้อมูลดังกล่าวจากแอป iOS ของคุณไปยัง URL อื่นได้อย่างไร ฉันไม่คิดว่าคุณถูกต้อง
John Korsnes

ฉันจะบอกว่า "ถ้า" aud "มี" www.webapp.com "แต่แอปไคลเอ็นต์พยายามใช้ JWT บน" secret.webapp.com ""
catamphetamine

2
RFC กล่าวว่าผู้ชม (aud) ระบุผู้รับ ผู้รับจะได้รับโทเค็น JWT ของคุณ หากคุณมีแอปพลิเคชันเว็บสิ่งนี้อาจเป็นcontoso.comแต่ถ้าคุณมีแอปบนเดสก์ท็อปหรือมือถือ (ที่ตรวจสอบสิทธิ์) ผู้ชมจะไม่มี URI ใด ๆ ผู้ออกคือผู้สร้างโทเค็น JWT ซึ่งอาจเป็นที่อยู่ของเซิร์ฟเวอร์มากที่สุด RFC กล่าวว่าการใช้การอ้างสิทธิ์นี้เป็นทางเลือกดังนั้นควรใช้เมื่อคุณต้องการเท่านั้น
Konrad

1
อันที่จริงฉันสับสนว่าความแตกต่างระหว่างผู้ชมและผู้ออกตราสารคืออะไร
Andy

64

การaudอ้างสิทธิ์JWT (ผู้ชม)

ตามRFC 7519 :

การอ้างสิทธิ์ "aud" (ผู้ชม) ระบุผู้รับที่ JWT มีไว้สำหรับ หลักแต่ละคนมีวัตถุประสงค์เพื่อประมวลผล JWT ต้องระบุตัวเองด้วยคุณค่าในการอ้างสิทธิ์ของผู้ชม หากการประมวลผลหลักของการอ้างสิทธิ์ไม่ได้ระบุตัวตนด้วยค่าในการอ้างสิทธิ์ "aud" เมื่อมีการอ้างสิทธิ์นี้ JWT จะต้องถูกปฏิเสธ ในกรณีทั่วไปค่า "aud" คืออาร์เรย์ของสตริงที่คำนึงถึงขนาดตัวพิมพ์แต่ละตัวมีค่า StringOrURI ในกรณีพิเศษเมื่อ JWT มีหนึ่งผู้ชมค่า "aud" อาจเป็นสตริงที่คำนึงถึงตัวพิมพ์เล็กและใหญ่ที่มีค่า StringOrURI โดยทั่วไปแล้วการตีความค่าของผู้ชมจะเป็นไปตามความเฉพาะเจาะจง การใช้การอ้างสิทธิ์นี้เป็นทางเลือก

การaudอ้างสิทธิ์Audience ( ) ตามที่กำหนดโดยข้อมูลจำเพาะเป็นแบบทั่วไปและเป็นแอปพลิเคชันเฉพาะ วัตถุประสงค์การใช้งานคือการระบุผู้รับที่ต้องการของโทเค็น ความหมายของผู้รับหมายถึงแอปพลิเคชันเฉพาะ ค่าผู้ชมอาจเป็นรายการสตริงหรืออาจเป็นสตริงเดียวก็ได้หากมีการaudอ้างสิทธิ์เพียงรายการเดียว ผู้สร้างโทเค็นไม่บังคับให้audมีการตรวจสอบความถูกต้องอย่างถูกต้องความรับผิดชอบคือผู้รับในการพิจารณาว่าควรใช้โทเค็นหรือไม่

ไม่ว่าค่าจะเป็นเท่าใดเมื่อผู้รับตรวจสอบความถูกต้องของ JWT และต้องการตรวจสอบความถูกต้องว่าโทเค็นถูกนำไปใช้เพื่อวัตถุประสงค์ของมันต้องกำหนดว่าค่าใดในการaudระบุตัวเองและโทเค็นควรตรวจสอบความถูกต้องก็ต่อเมื่อ ID ที่ประกาศของผู้รับคือ มีอยู่ในaudข้อเรียกร้อง ไม่สำคัญว่านี่คือ URL หรือสตริงเฉพาะแอปพลิเคชันอื่น ๆ ตัวอย่างเช่นหากระบบของฉันตัดสินใจระบุตัวเองaudด้วยสตริงapi3.app.comควรยอมรับ JWT ก็ต่อเมื่อการaudอ้างสิทธิ์มีapi3.app.comอยู่ในรายการค่าผู้ชมเท่านั้น

แน่นอนว่าผู้รับอาจเลือกที่จะไม่สนใจaudดังนั้นสิ่งนี้จะมีประโยชน์ก็ต่อเมื่อผู้รับต้องการการตรวจสอบเชิงบวกว่าโทเค็นถูกสร้างขึ้นโดยเฉพาะ

การตีความของฉันตามข้อกำหนดคือการaudอ้างสิทธิ์มีประโยชน์ในการสร้าง JWT ที่สร้างขึ้นตามวัตถุประสงค์ซึ่งใช้ได้เฉพาะกับวัตถุประสงค์บางประการเท่านั้น สำหรับระบบหนึ่งอาจหมายความว่าคุณต้องการให้โทเค็นใช้ได้กับคุณสมบัติบางอย่าง แต่ใช้ไม่ได้กับระบบอื่น คุณสามารถออกโทเค็นที่ จำกัด เฉพาะ "ผู้ชม" บางกลุ่มในขณะที่ยังคงใช้คีย์และอัลกอริทึมการตรวจสอบความถูกต้องเดียวกัน

เนื่องจากในกรณีทั่วไป JWT ถูกสร้างขึ้นโดยบริการที่เชื่อถือได้และถูกใช้โดยระบบอื่น ๆ ที่เชื่อถือได้ (ระบบที่ไม่ต้องการใช้โทเค็นที่ไม่ถูกต้อง) ระบบเหล่านี้จำเป็นต้องประสานค่าที่จะใช้

แน่นอน, audเป็นทางเลือกที่สมบูรณ์และสามารถละเว้นได้หากกรณีการใช้งานของคุณไม่รับประกัน หากคุณไม่ต้องการ จำกัด โทเค็นให้ใช้กับผู้ชมบางกลุ่มหรือไม่มีระบบของคุณที่จะตรวจสอบaudโทเค็นจริงก็ไม่มีประโยชน์

ตัวอย่าง: Access เทียบกับ Refresh Token

ตัวอย่างหนึ่งที่สร้างขึ้น (แต่เรียบง่าย) ที่ฉันคิดได้คือบางทีเราต้องการใช้ JWT เพื่อเข้าถึงและรีเฟรชโทเค็นโดยไม่ต้องใช้คีย์การเข้ารหัสและอัลกอริทึมแยกต่างหาก แต่ต้องการให้แน่ใจว่าโทเค็นการเข้าถึงจะไม่ตรวจสอบความถูกต้องเป็นโทเค็นรีเฟรชหรือรอง - ตรงกันข้าม

ด้วยการใช้audเราสามารถระบุการอ้างสิทธิ์refreshสำหรับโทเค็นการรีเฟรชและการอ้างสิทธิ์accessสำหรับโทเค็นการเข้าถึงเมื่อสร้างโทเค็นเหล่านี้ เมื่อมีการร้องขอเพื่อรับโทเค็นการเข้าถึงใหม่จากโทเค็นการรีเฟรชเราจำเป็นต้องตรวจสอบว่าโทเค็นการรีเฟรชเป็นโทเค็นการรีเฟรชของแท้ การaudตรวจสอบความถูกต้องตามที่อธิบายไว้ข้างต้นจะบอกเราว่าโทเค็นนั้นเป็นโทเค็นการรีเฟรชที่ถูกต้องหรือไม่โดยมองหาการอ้างสิทธิ์refreshในaudใน

รหัสไคลเอ็นต์ OAuth เทียบกับการaudอ้างสิทธิ์JWT

รหัสไคลเอ็นต์ OAuth ไม่เกี่ยวข้องกันโดยสิ้นเชิงและไม่มีความสัมพันธ์โดยตรงกับ JWT audอ้างสิทธิ์จากมุมมองของ OAuth โทเค็นเป็นวัตถุทึบแสง

แอปพลิเคชันที่รับโทเค็นเหล่านี้มีหน้าที่ในการแยกวิเคราะห์และตรวจสอบความหมายของโทเค็นเหล่านี้ ฉันไม่เห็นคุณค่ามากนักในการระบุรหัสไคลเอ็นต์ OAuth ภายในการaudอ้างสิทธิ์JWT


3
ฉันค่อนข้างคลุมเครือกับบิต "ต้องระบุตัวเอง" RFC7519 เต็มไปด้วยบิตที่ไม่สามารถอธิบายได้เช่นนั้นพร้อมกับการพาดพิงที่คลุมเครือกับระบบการตรวจสอบสิทธิ์อื่น ๆ ซึ่งเป็นไปได้ว่าจะพบการตีความที่เหมาะสมของฟิลด์การอ้างสิทธิ์มาตรฐาน ตรงไปตรงมา RFC มีประโยชน์อย่างที่ควรจะเป็นไม่ควรออกจากขั้นตอนการร่างในสถานะเช่นนี้
Chuck Adams

1
@ChuckAdams ฉันแก้ไขเพื่อชี้แจงความคิดของฉัน ฉันยอมรับว่า RFC นั้นคลุมเครือมากโดยเฉพาะอย่างยิ่งเกี่ยวกับ "การอ้างสิทธิ์มาตรฐาน" และวิธีการ / เวลาที่จะใช้
Kekoa

2
ขณะนี้เรามีการพูดคุยกันเกี่ยวกับวิธีการใช้ฟิลด์การตรวจสอบและฉันยอมรับว่ามีวัตถุประสงค์เพื่อให้มีผู้รับ (ผู้ที่ตรวจสอบและยอมรับโทเค็น) ไม่ใช่ client_id (ผู้ที่ขอให้โทเค็นดำเนินการ นามของผู้ใช้)
ฮาร์ดิซิม

4

หากคุณมาที่นี่เพื่อค้นหา OpenID Connect (OIDC): OAuth 2.0! = OIDC

ฉันรับรู้ว่าสิ่งนี้ถูกแท็กสำหรับ oauth 2.0 และไม่ใช่ OIDC อย่างไรก็ตามมักมีความขัดแย้งระหว่าง 2 มาตรฐานเนื่องจากทั้งสองมาตรฐานสามารถใช้ JWT และการaudอ้างสิทธิ์ได้ และหนึ่ง (OIDC) นั้นเป็นส่วนขยายของอีกอันหนึ่ง (OAUTH 2.0) (ฉันเจอคำถามนี้โดยมองหา OIDC ด้วยตัวเอง)

โทเค็นการเข้าถึง OAuth 2.0 ##

สำหรับ OAuth 2.0 โทเค็นการเข้าถึงคำตอบที่มีอยู่ครอบคลุมได้ดี นอกจากนี้นี่คือส่วนที่เกี่ยวข้องอีกหนึ่งส่วนจากOAuth 2.0 Framework (RFC 6749)

สำหรับไคลเอ็นต์สาธารณะที่ใช้โฟลว์โดยนัยข้อกำหนดนี้ไม่ได้จัดเตรียมวิธีการใด ๆ สำหรับไคลเอ็นต์ในการพิจารณาว่าไคลเอ็นต์ใดที่มีการออกโทเค็นการเข้าถึง
... การ
พิสูจน์ตัวตนเจ้าของทรัพยากรกับไคลเอ็นต์อยู่นอกขอบเขตสำหรับข้อกำหนดนี้ ข้อกำหนดใด ๆ ที่ใช้กระบวนการอนุญาตเป็นรูปแบบของการรับรองความถูกต้องของผู้ใช้ปลายทางที่มอบหมายให้กับไคลเอ็นต์ (เช่นบริการลงชื่อเข้าใช้ของบุคคลที่สาม) ต้องไม่ใช้ขั้นตอนโดยนัยโดยไม่มีกลไกการรักษาความปลอดภัยเพิ่มเติมที่จะทำให้ไคลเอ็นต์ตรวจสอบว่าการเข้าถึง โทเค็นถูกออกเพื่อใช้งาน (เช่นผู้ชม - จำกัด โทเค็นการเข้าถึง)

OIDC ID โทเค็น ##

OIDC มีID Tokenนอกเหนือจากโทเค็นการเข้าถึง ข้อกำหนด OIDC มีความชัดเจนเกี่ยวกับการใช้การaudอ้างสิทธิ์ใน ID Tokens ( openid-connect-core-1.0 )

AUD
จำเป็น ผู้ชมที่ ID Token นี้มีไว้สำหรับ ต้องมี OAuth 2.0 client_id ของ Relying Party เป็นค่าผู้ชมนอกจากนี้ยังอาจมีตัวระบุสำหรับผู้ชมอื่น ๆ ในกรณีทั่วไปค่า aud คืออาร์เรย์ของสตริงที่คำนึงถึงตัวพิมพ์เล็กและใหญ่ ในกรณีพิเศษทั่วไปเมื่อมีผู้ชมหนึ่งคนค่า aud อาจเป็นสตริงที่คำนึงถึงตัวพิมพ์เล็กและใหญ่เพียงตัวเดียว

นอกจากนี้ OIDC ยังระบุการazpอ้างสิทธิ์ที่ใช้ร่วมกับaudเมื่อaudมีค่ามากกว่าหนึ่งค่า

ตัว
เลือกazp ฝ่ายที่ได้รับอนุญาต - ฝ่ายที่ออก ID Token หากมีอยู่จะต้องมีรหัสไคลเอ็นต์ OAuth 2.0 ของฝ่ายนี้ การอ้างสิทธิ์นี้จำเป็นเฉพาะเมื่อ ID Token มีค่าผู้ชมเดียวและผู้ชมนั้นแตกต่างจากฝ่ายที่ได้รับอนุญาต อาจรวมได้แม้ว่าฝ่ายที่ได้รับอนุญาตจะเป็นคนเดียวกับผู้ชมเพียงคนเดียว ค่า azp เป็นสตริงที่คำนึงถึงตัวพิมพ์เล็กและใหญ่ที่มีค่า StringOrURI


1
สิ่งหนึ่งที่ควรทราบ: Oauth2 ไม่ได้บังคับให้ใช้ JWT
zoran

1

แม้ว่าเรื่องนี้จะเก่า แต่ฉันคิดว่าคำถามนี้ใช้ได้แม้กระทั่งในปัจจุบัน

ความสงสัยของฉันคือ aud ควรอ้างถึงเซิร์ฟเวอร์ทรัพยากรและ client_id ควรอ้างถึงหนึ่งในแอปพลิเคชันไคลเอนต์ที่เซิร์ฟเวอร์รับรองความถูกต้อง

ใช่Audควรหมายถึงบุคคลที่ใช้โทเค็น และclient_idหมายถึงบุคคลที่ได้รับโทเค็น

ในกรณีปัจจุบันเซิร์ฟเวอร์ทรัพยากรของฉันยังเป็นไคลเอนต์เว็บแอปของฉัน

ในสถานการณ์ของ OP เว็บแอปและเซิร์ฟเวอร์ทรัพยากรเป็นของฝ่ายเดียวกัน ดังนั้นจึงหมายความว่าลูกค้าและผู้ชมจะเหมือนกัน แต่อาจมีสถานการณ์ที่ไม่เป็นเช่นนั้น

ลองนึกถึงสปาที่ใช้ทรัพยากรที่มีการป้องกัน OAuth ในสถานการณ์นี้ SPA คือไคลเอนต์ ทรัพยากรที่มีการป้องกันคือผู้ชมของโทเค็นการเข้าถึง

สถานการณ์ที่สองนี้น่าสนใจ มีแบบร่างที่ใช้งานได้ชื่อ " ตัวบ่งชี้ทรัพยากรสำหรับ OAuth 2.0 " ซึ่งอธิบายว่าคุณสามารถกำหนดผู้ชมเป้าหมายในคำขออนุญาตของคุณได้ที่ใด ดังนั้นโทเค็นที่ได้จะ จำกัด เฉพาะผู้ชมที่ระบุ นอกจากนี้ Azure OIDC ยังใช้วิธีการที่คล้ายกันซึ่งอนุญาตให้ลงทะเบียนทรัพยากรและอนุญาตให้คำขอรับรองความถูกต้องมีพารามิเตอร์ทรัพยากรเพื่อกำหนดผู้ชมเป้าหมายโทเค็นการเข้าถึง กลไกดังกล่าวช่วยให้การโฆษณา OAuth มีการแยกระหว่างลูกค้าและฝ่ายที่ใช้โทเค็น (ผู้ชม)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.