ประเภทการให้สิทธิ์โดยนัยในวัตถุประสงค์ของ OAuth 2 คืออะไร


254

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

การไหลทั้งสองเริ่มเหมือนกัน (ที่มา: http://tools.ietf.org/html/draft-ietf-oauth-v2-22 ):

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

นี่คือที่ที่กระแสแยก ในทั้งสองกรณี URI การเปลี่ยนเส้นทาง ณ จุดนี้คือจุดปลายทางที่โฮสต์โดยลูกค้า:

  • ในโฟลว์การอนุญาตเมื่อเอเจนต์ผู้ใช้พบจุดสิ้นสุดนั้นด้วยโค้ดการอนุญาตใน URI โค้ดที่จุดปลายนั้นจะแลกเปลี่ยนโค้ดการอนุญาตพร้อมกับหนังสือรับรองไคลเอ็นต์สำหรับโทเค็นการเข้าถึงซึ่งสามารถใช้งานได้ตามต้องการ ตัวอย่างเช่นสามารถเขียนลงในหน้าเว็บที่สคริปต์บนหน้าสามารถเข้าถึงได้
  • โฟลว์โดยปริยายจะข้ามขั้นตอนการพิสูจน์ตัวตนลูกค้าทั้งหมดและเพียงโหลดหน้าเว็บด้วยสคริปต์ลูกค้า มีเคล็ดลับน่ารักอยู่ที่นี่ด้วยส่วน URL ที่ทำให้ไม่สามารถส่งโทเค็นการเข้าถึงได้มากเกินไป แต่ผลลัพธ์สุดท้ายก็เหมือนกัน: ไซต์ที่โฮสต์โดยไคลเอ็นต์ให้บริการหน้าเว็บที่มีสคริปต์บางตัวที่สามารถเข้าถึงโทเค็นการเข้าถึงได้ .

ดังนั้นคำถามของฉัน: สิ่งที่ได้รับที่นี่โดยข้ามขั้นตอนการตรวจสอบลูกค้า?


ดูสิ่งนี้ได้ที่: ibm.com/developerworks/wikis/display/…
Håvard Geithus

5
ลิงก์ในความคิดเห็นก่อนหน้านี้ตาย นี่คืออัพเดทล่าสุด
AndrewR

3
ฉันได้อ่านคำตอบทั้งหมดที่นี่แล้ว แต่ฉันยังไม่เข้าใจว่าการไม่ใช้ความลับของไคลเอ็นต์ส่วนตัวเพื่อให้ได้รับโทเค็นการเข้าถึงได้อย่างปลอดภัย สมมติว่า TrustedAppDeveloper เผยแพร่ TrustedPopularApp ที่ให้ผู้ใช้ให้สิทธิ์ (พูดโดยใช้ Twitter oauth) โดยใช้การให้สิทธิ์โดยปริยาย ถ้าฉันเป็น EvilAppDeveloper สิ่งที่ทำให้ฉันไม่สามารถสร้างแอปที่ส่งผ่าน TrustedPopularAppId ในฐานะ client_id ในคำขอการให้สิทธิ์โดยปริยายแล้วทำการกระทำ (เช่นการส่งสแปมฟีด) ในนามของผู้ใช้ซึ่งตอนนี้ดูเหมือนว่าพวกเขามาจาก ?
adevine

ฉันสงสัยในสิ่งเดียวกันกับ adevine แต่แอพพลิเคชั่นส่วนใหญ่ที่ต้องการคำขอการอนุญาตโดยนัยไม่มีความจำเป็นในการรับรองความถูกต้องเพิ่มเติม
Mave

13
@adevine สิ่งที่จะป้องกัน EvilApp ในสถานการณ์ของคุณจากการรับรองความถูกต้องของ Twitter เป็น TrustedPopularApp คือมันไม่สามารถรับการเรียกกลับจาก Twitter พวกเขาจะถูกส่งไปยัง URI ที่กำหนดไว้เสมอเมื่อลงทะเบียนรหัสลูกค้า
Ivan

คำตอบ:


196

นี่คือความคิดของฉัน:

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

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

ดังนั้นคำตอบของ "สิ่งที่ได้รับ" คือ "ความเรียบง่าย"


4
ขอบคุณ นั่นเป็นจุดที่ดีที่ในรหัสการให้สิทธิ์เจ้าของทรัพยากรไม่จำเป็นต้องเห็นโทเค็นการเข้าถึงในขณะที่ในไคลเอนต์จาวาสคริปต์ที่หลีกเลี่ยงไม่ได้ ความลับของลูกค้ายังสามารถถูกเก็บไว้จากไคลเอนต์ javascript โดยใช้โฟลว์รหัสการอนุญาตอย่างไรก็ตาม: หลังจากตรวจสอบและรับโทเค็นการเข้าถึงแล้วโค้ดฝั่งเซิร์ฟเวอร์จะส่งโทเค็นไปยังไคลเอนต์ javascript สิ่งที่ฉันเห็นตอนนี้คือการให้สิทธิ์โดยปริยายทำให้การกระจาย javascript oauth SDKs เช่น Facebook ช่วยให้ผู้พัฒนาไม่ต้องเขียนโค้ด oauth ของตัวเองอย่างสมบูรณ์
Dan Taflin

3
ฉันอาจจะเพิ่มที่ไหลรหัสอนุญาตให้ลูกค้าเก็บโทเค็นและนำมาใช้ใหม่ ในโฟลว์ทางอ้อมคุณไม่จำเป็นต้องมีตัวเลือกนั้นเสมอไปดังนั้นโฟลว์แบบ implicit เป็นตัวเลือกที่ใช้งานได้จริงระหว่างระดับความปลอดภัยและความสะดวกสบาย
PålOliver

2
คำตอบนี้เพียงครึ่งเดียวและ "สิ่งที่หายไป"?
EralpB

3
ฉันไม่คิดว่านี่เป็นคำตอบที่ครอบคลุมการไหลโดยนัยไม่ได้มีจุดประสงค์เพื่อให้ได้เปรียบในเรื่องความเรียบง่าย แต่เพื่อลดความกังวลด้านความปลอดภัยด้วยแอปฝั่งไคลเอ็นต์ Auth codeร่วมกับclient_idและclient_secretถูกนำมาใช้เพื่อระบุลูกค้าที่เชื่อถือได้ที่สามารถฟื้นฟูสัญญาณสำหรับการเข้าสู่ระบบเวลานานและสำหรับ"การเข้าสู่ระบบออฟไลน์" อย่างไรก็ตามในแอปฝั่งไคลเอ็นต์ไม่มีวิธีในการลงทะเบียนลูกค้าแต่ละรายดังนั้นประเภทการให้สิทธิ์แบบ "ง่าย" โดยนัยสำหรับการเข้าถึงข้อมูลผู้ใช้ชั่วคราว
Chen Xie

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

94

มันมีเหตุผลด้านความปลอดภัยไม่ใช่เพื่อความเรียบง่าย

คุณควรพิจารณาความแตกต่างระหว่างตัวแทนผู้ใช้และลูกค้า :

user-agent คือซอฟต์แวร์ที่ผู้ใช้ ("เจ้าของทรัพยากร") สื่อสารกับส่วนอื่น ๆ ของระบบ (เซิร์ฟเวอร์การตรวจสอบความถูกต้องและเซิร์ฟเวอร์ทรัพยากร)

ไคลเอ็นต์คือซอฟต์แวร์ที่ต้องการเข้าถึงทรัพยากรของผู้ใช้บนเซิร์ฟเวอร์ทรัพยากร

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

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


2
ฉันเห็นว่าเบราว์เซอร์ของฉันลงชื่อเข้าใช้บัญชี Google เป็นเวลาหลายเดือน Google ใช้โทเค็นการเข้าถึงบนเบราว์เซอร์หรือโทเค็นการเข้าถึงที่มีเวลาหมดอายุนานหรือไม่ ความแตกต่างในการใช้งานระหว่างโทเค็นการเข้าถึงที่มีเวลาหมดอายุนานและโทเค็นการเข้าถึงคืออะไร ไคลเอ็นต์อื่น ๆ สามารถตรวจจับโทเค็นการเข้าถึงและใช้งานได้เมื่อไม่มีเจ้าของทรัพยากร
โมฮัมหมัด Nikravan

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

ขอบคุณสำหรับคำอธิบายของคุณ แต่ฉันก็มีความสับสนเช่นกัน ฉันไม่เข้าใจว่าทำไมเราถึงต้องการโฟลว์ "รหัสการอนุญาต" เราสามารถเข้าถึงผลลัพธ์เดียวกันบนเซิร์ฟเวอร์โดยการไหลโดยนัย (access_token) และโทเค็นการรีเฟรช ดูเหมือนว่าการพิจารณาด้านความปลอดภัยโดยนัยของโฟลว์ทางอ้อมคือ access_code ควรมีอายุสั้นดังนั้นจึงไม่สามารถใช้บนเซิร์ฟเวอร์ไปยังเซิร์ฟเวอร์ได้ ตกลง แต่โทเค็นการรีเฟรชแก้ปัญหานี้ได้ เหตุใดเราจึงควรใช้โฟลว์ auth_code และร้องขอ access_token โดยโทเค็นนั้นบนเซิร์ฟเวอร์เพื่อรับ access_code เมื่อเราสามารถบรรลุผลลัพธ์เดียวกันกับ refresh_token
Mohammad Nikravan

"โทเค็นสามารถแยกได้ง่ายโดยแอปพลิเคชันอื่น" ได้อย่างไร
mvmn

@MohammadNikravan ค้นหาคำตอบในstackoverflow.com/q/13387698/355438
Lu55

60

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

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

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

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

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

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


21

มันลดลงมาที่: หากผู้ใช้เรียกใช้แอพพลิเคชั่นบนเว็บที่ใช้เบราว์เซอร์หรือ "สาธารณะ", (JavaScript) โดยไม่มีองค์ประกอบด้านเซิร์ฟเวอร์จากนั้นผู้ใช้จะไว้วางใจแอป (และเบราว์เซอร์ที่ทำงาน) แอพที่ใช้ ... )

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

อย่างไรก็ตามผลกระทบด้านความปลอดภัยมีความสำคัญ จากhttp://tools.ietf.org/html/rfc6749#section-10.3 :

เมื่อใช้ชนิดการให้โดยนัยโทเค็นการเข้าถึงจะถูกส่งในส่วนของ URI ซึ่งสามารถเปิดเผยให้กับบุคคลที่ไม่ได้รับอนุญาต

จากhttp://tools.ietf.org/html/rfc6749#section-10.16 :

เจ้าของทรัพยากรอาจมอบหมายการเข้าถึงทรัพยากรด้วยความเต็มใจโดยอนุญาตให้โทเค็นการเข้าถึงลูกค้าที่เป็นอันตรายของผู้โจมตี อาจเกิดจากฟิชชิงหรือข้ออ้างอื่น ๆ ...


แอพพลิเคชั่น "สาธารณะ", (JavaScript) บนเว็บที่ไม่มีองค์ประกอบด้านเซิร์ฟเวอร์หมายความว่าอย่างไร จะมีเว็บแอปพลิเคชันที่ไม่มีเซิร์ฟเวอร์ได้อย่างไร
Zammy หน้า

2
@ZammyPage นี่จะเป็นสิ่งที่มักจะเรียกว่าแอปหน้าเดียว (SPA) แอพพลิเคชั่นทั้งหมดทำหน้าที่จากทรัพยากรคงที่ จากนั้น Javascript ในแอปจะเข้าถึงทรัพยากรที่ต้องการในเซิร์ฟเวอร์ทรัพยากรใดก็ได้ที่สามารถเข้าถึงได้ ไม่มีเซิร์ฟเวอร์ที่สร้างเนื้อหาของไคลเอนต์: จาวาสคริปต์ในไคลเอนต์แก้ไข DOM ตามที่จำเป็นเพื่อแสดงทรัพยากรที่มีการเข้าถึง
Elroy Flynn

13

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

Dan Taflin กล่าวว่า:

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

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


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

แน่นอนคำตอบที่ยอมรับได้ทำให้ฉันสับสน ทำให้ฉันคิดว่าฉันเข้าใจผิดว่า client_secret คืออะไร! คำตอบนี้และความคิดเห็นข้างต้นเป็นจุดที่
Sarsaparilla

9

แม้ว่าImplicit Grantได้รับการออกแบบมาเพื่อรองรับแอพที่ไม่สามารถป้องกันความลับของลูกค้ารวมถึงแอพ JavaScript ฝั่งไคลเอ็นต์ผู้ให้บริการบางรายกำลังใช้ทางเลือกอื่นโดยใช้รหัสการอนุญาตโดยไม่มีความลับของลูกค้าแทน OAuth 2.0 IETF RFC-6749ได้รับการเผยแพร่ในปี 2012 และข้อเสนอแนะปัจจุบันมีการอภิปรายล่าสุดจากปี 2560

2017 การสนทนาในรายชื่อผู้รับจดหมาย IETF OAuth มีให้จากผู้ใช้งานเหล่านี้:

อ่านเพิ่มเติมได้ที่นี่:

ก่อนหน้านี้มีการแนะนำโดยปริยายสำหรับลูกค้าที่ไม่มีความลับ แต่ถูกแทนที่โดยใช้รหัสการอนุญาตที่ไม่มีความลับ

...

ก่อนหน้านี้ขอแนะนำให้แอปที่ใช้เบราว์เซอร์ใช้โฟลว์ "โดยนัย" ซึ่งจะส่งคืนโทเค็นการเข้าถึงทันทีและไม่มีขั้นตอนการแลกเปลี่ยนโทเค็น ในช่วงเวลาตั้งแต่สเปคถูกเขียนขึ้นเดิมแนวทางปฏิบัติที่ดีที่สุดในอุตสาหกรรมได้เปลี่ยนไปเพื่อแนะนำให้ใช้การไหลของรหัสการให้สิทธิ์โดยไม่มีความลับของลูกค้า สิ่งนี้ให้โอกาสมากขึ้นในการสร้างโฟลว์ที่ปลอดภัยเช่นการใช้พารามิเตอร์สถานะ อ้างอิง: Redhat , Deutsche Telekom , สมาร์ทไอทีสุขภาพ

การย้ายไปยังรหัสรับรองความถูกต้องโดยไม่มีความลับของลูกค้าจากการให้สิทธิ์โดยปริยายจะกล่าวถึงสำหรับแอปมือถือที่นี่:


ฉันคิดว่าคุณต้องการระมัดระวังคำแนะนำนี้ สิ่งนี้แนะนำในคำแนะนำสำหรับแอพพื้นฐานไม่ใช่สปา น่าเสียดายที่ไม่มีคำแนะนำที่ดีเกี่ยวกับ SPAs ดังที่ได้บันทึกไว้ในการสนทนาออนไลน์ฟอรัมและแม้แต่รายชื่อผู้รับจดหมาย oauth-wg
Tom

คำแนะนำในการย้ายไปยังรหัสรับรองความถูกต้องโดยไม่ได้รับการอนุญาตโดยนัยคือคำแนะนำสำหรับทั้งสปาและแอพมือถือ แต่ข้อความที่ตัดตอนมาของฉันเป็นเฉพาะกับสปา บทความที่อ้างถึงใช้ข้อความที่คล้ายกันสำหรับทั้งสปาและแอพมือถือ แต่ใช้ภาษา "แอพที่ใช้เบราว์เซอร์" "แอพมือถือและแอพเนทีฟ" ในข้อความที่เกี่ยวข้อง นอกจากนี้การอ้างอิงสำหรับ Redhat, DT, Smart Health IT นั้นใช้เฉพาะกับ SPAs และไม่รวมอยู่ในหมายเหตุสำหรับแอพมือถือ ฉันได้เพิ่มลิงก์ลึกลงไปใน SPA ในคำตอบเพื่อให้ค้นหาได้ง่ายขึ้น กรุณาโพสต์ลิงก์ไปยังการสนทนาที่คุณพูดถึง
Grokify

ธรรมที่ผ่านมา (2018) การอภิปราย OAuth-WG สามารถพบได้ที่นี่ietf.org/mail-archive/web/oauth/current/msg18020.html RFC 8252 สำหรับแอพเนทีฟเนื่องจากชื่อแนะนำ "OAuth 2.0 สำหรับแอพเนทีฟ" การอ้างอิงถึง Redhat, DT, Smart Health IT คือการตอบสนองต่อการสนทนารายชื่อผู้รับจดหมายไม่ใช่ rfc, ร่างการทำงาน ฯลฯ ...
Tom

3

นอกเหนือจากคำตอบอื่น ๆ สิ่งสำคัญคือต้องตระหนักว่าโปรไฟล์โดยนัยอนุญาตให้โฟลว์หน้าแชนเนลเท่านั้นเมื่อเทียบกับโฟลว์รหัสการอนุญาตที่ต้องมีการโทรกลับไปยังเซิร์ฟเวอร์การอนุญาต สิ่งนี้เห็นได้อย่างชัดเจนใน OpenID Connect ซึ่งเป็นโปรโตคอล SSO ที่สร้างจากด้านบนของ Auth 2.0 ซึ่งการไหลโดยนัยมีลักษณะคล้ายกับ SAML POST ที่ได้รับความนิยม


3

ในการไหลโดยปริยายหากเบราว์เซอร์ของผู้ใช้เสียหาย (ส่วนขยายที่ชั่วร้าย / ไวรัส) จากนั้นความเสียหายจะได้รับการเข้าถึงทรัพยากรของผู้ใช้และสามารถทำสิ่งที่ไม่ดี

ในกระบวนการตรวจสอบความเสียหายไม่สามารถทำได้เพราะไม่ทราบความลับของลูกค้า


2

https://tools.ietf.org/html/rfc6749#page-8

โดยปริยาย

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

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

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


1

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


1

นัยแกรนท์ช่วยให้สำหรับการได้รับราชสกุลจากการอนุมัติปลายทางGETด้วย ซึ่งหมายความว่าเซิร์ฟเวอร์การให้สิทธิ์ไม่จำเป็นต้องรองรับ CORS

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

ในอดีตมีเหตุผลอื่น ๆ ที่จะใช้การไหลโดยปริยาย แต่ดูเหมือนว่าพวกเขามีความได้เปรียบด้านความปลอดภัยเกินกว่าที่การมอบอำนาจให้รหัสอนุญาตรวมถึง:

  • ตัวเลือกในการจัดส่งและใช้โทเค็นทาง back-channel สำหรับลูกค้าที่เป็นความลับ
  • ไม่เปิดเผยโทเค็นในประวัติเบราว์เซอร์สำหรับลูกค้าสาธารณะ
  • การขัดจังหวะการไหลที่ไม่ได้รับอนุญาตก่อนมีการออกโทเค็น - ด้วยPKCEสำหรับ"ลูกค้า OAuth ทุกชนิด"

0

ฉันเพิ่งพบกับบทความเกี่ยวกับ OAuth 2.0 ผู้เขียนกล่าวว่าเหตุผลที่อยู่เบื้องหลังโฟลว์โดยนัยคือแอพ JS นั้นถูก จำกัด มากในคำขอ:

หากคุณสงสัยว่าทำไมประเภทโดยนัยรวมอยู่ใน OAuth 2.0 คำอธิบายนั้นง่าย: นโยบายแหล่งกำเนิดเดียวกัน ย้อนกลับไปตอนนั้นแอปพลิเคชันส่วนหน้าไม่ได้รับอนุญาตให้ส่งคำขอไปยังโฮสต์อื่นเพื่อรับโทเค็นการเข้าถึงโดยใช้รหัส วันนี้เรามี CORS (การแบ่งปันทรัพยากรข้ามแหล่ง)

https://medium.com/securing/what-is-going-on-with-oauth-2-0-and-why-you-should-not-use-it-for-authentication-5f47597b2611

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