OAuth 2.0: ประโยชน์และการใช้เคส - ทำไม?


256

ใครสามารถอธิบายสิ่งที่ดีเกี่ยวกับ OAuth2 และทำไมเราควรนำไปใช้? ฉันถามเพราะฉันสับสนเล็กน้อยเกี่ยวกับมัน - นี่คือความคิดปัจจุบันของฉัน:

คำขอ OAuth1 (HMAC ที่แม่นยำยิ่งขึ้น) นั้นดูสมเหตุสมผลเข้าใจง่ายง่ายต่อการพัฒนาและปลอดภัยจริงๆ

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

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

นอกจากนี้ตามที่ / r / netsec แสดงให้เห็นเมื่อเร็ว ๆ นี้ SSL นั้นไม่ได้ปลอดภัยทั้งหมดดังนั้นการผลักดันเพื่อให้ทุกอย่างเข้าสู่ TLS / SSL แทนที่จะเป็น HMAC ที่ปลอดภัยนั้นทำให้ฉันสับสน

OAuth กำลังเถียงว่าไม่ใช่เรื่องความปลอดภัย 100% แต่ให้ตีพิมพ์และเสร็จสิ้น แต่นั่นไม่ได้เสียงที่แน่นอนว่าจากมุมมองของผู้ให้บริการ ฉันสามารถเห็นสิ่งที่ร่างพยายามที่จะบรรลุเมื่อมันกล่าวถึงกระแสที่แตกต่างกัน 6 แต่มันก็ไม่เหมาะกันในหัวของฉัน

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


คำตอบ:


324

แบ็คกราวน์: ฉันได้เขียนไคลเอนต์และเซิร์ฟเวอร์สแต็คสำหรับ OAuth 1.0a และ 2.0

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

ซับซ้อนหนึ่ง: การรับรองความถูกต้องสามขา

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

หากไม่มี (?) ลึกเข้าไปในรายละเอียดของ OAuth มากเกินไป:

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

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

การแลกเปลี่ยนแต่ละครั้ง (ไคลเอนต์ - เซิร์ฟเวอร์, เซิร์ฟเวอร์ -> ผู้ให้บริการเนื้อหา) รวมถึงการตรวจสอบความลับที่ใช้ร่วมกัน แต่เนื่องจาก OAuth 1 สามารถเรียกใช้ผ่านการเชื่อมต่อที่ไม่ได้เข้ารหัสการตรวจสอบแต่ละครั้งจึงไม่สามารถส่งความลับผ่านสาย

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

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

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

ข้อกำหนดเดียวกันนั้นมีอยู่ในการเชื่อมต่อของเซิร์ฟเวอร์ -> ผู้ให้บริการเนื้อหาและเนื่องจากนั่นคือ SSL ที่ลบสิ่งกีดขวางหนึ่งเพื่อเขียนเซิร์ฟเวอร์ที่เข้าถึงบริการ OAuth

นั่นทำให้สิ่งต่าง ๆ ง่ายขึ้นมากในขั้นตอนที่ 1, 2 และ 5 ข้างต้น

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

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

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

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

การรับรองความถูกต้องสองขา

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

OAuth 2 สร้างส่วนขยายมาตรฐานให้กับ OAuth 1 ที่มีการใช้งานอย่างกว้างขวาง หนึ่งฉันรู้ดีที่สุดได้รับการแนะนำให้รู้จักกับ Twitter เป็นxauth คุณสามารถเห็นมันใน OAuth 2 เป็นเจ้าของทรัพยากรข้อมูลประจำตัวรหัสผ่าน

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

ด้วย OAuth 1 สิ่งนี้ไม่ได้เป็นส่วนหนึ่งของมาตรฐานอย่างเป็นทางการและจำเป็นต้องใช้ขั้นตอนการลงชื่อเช่นเดียวกับคำขออื่น ๆ ทั้งหมด

ฉันเพิ่งใช้ฝั่งเซิร์ฟเวอร์ของ OAuth 2 พร้อมด้วยรหัสผ่านเจ้าของทรัพยากรและจากมุมมองของลูกค้าการเข้าถึงโทเค็นการเข้าถึงนั้นง่าย: ขอโทเค็นการเข้าถึงจากเซิร์ฟเวอร์ผ่าน ID ลูกค้า / ความลับเป็นส่วนหัว HTTP Authorization และ เข้าสู่ระบบ / รหัสผ่านของผู้ใช้เป็นข้อมูลแบบฟอร์ม

ข้อดี: เรียบง่าย

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

และจะแปลงเป็นส่วนขยายมาตรฐานบางส่วนไปยัง OAuth 1.0a (เช่น xAuth) ซึ่งตอนนี้มีการใช้งานอย่างกว้างขวาง


20
เกี่ยวกับคำศัพท์: มันจะดีกว่าถ้าคุณใช้ชื่อทางการของฝ่ายที่ได้รับผลกระทบ (เซิร์ฟเวอร์การอนุญาตเซิร์ฟเวอร์ทรัพยากรเจ้าของทรัพยากร) แทนที่จะใช้ชื่อที่ไม่ชัดเจน (ลูกค้าเซิร์ฟเวอร์ผู้ใช้ .. )
Aydin K.

สวัสดีปีเตอร์คุณสามารถเปลี่ยนโพสต์ของคุณด้วยเซิร์ฟเวอร์การอนุญาต, เซิร์ฟเวอร์ทรัพยากร, เจ้าของทรัพยากร .. ในนามของลูกค้า, เซิร์ฟเวอร์, ผู้ใช้ .. เช่น Aydin K กล่าว มันส่วนใหญ่ช่วยให้ผู้เริ่มต้น aouth ขอบคุณ.
JustCode

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

ถ้าใครไม่เข้าใจ oauth การอธิบาย oauth โดยใช้คำศัพท์ oauth ไม่ใช่ภาษาอังกฤษแบบธรรมดาดูเหมือนจะไม่ได้ผล
Jacob

7

ขั้นแรกตามที่ระบุไว้อย่างชัดเจนในการตรวจสอบสิทธิ์ OAuth

OAuth 2.0 ไม่ใช่โปรโตคอลการตรวจสอบสิทธิ์

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

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

มีมาตรฐานสำหรับการตรวจสอบผู้ใช้โดยใช้ OAuth: OpenID Connect เข้ากันได้กับ OAuth2

Token ID การเชื่อมต่อ OpenID เป็นโทเค็น JSON Web Token (JWT) ที่ลงนามซึ่งมอบให้แก่แอปพลิเคชันไคลเอนต์ด้านโทเค็นการเข้าถึง OAuth ปกติ ID Token มีชุดของการอ้างสิทธิ์เกี่ยวกับเซสชันการตรวจสอบสิทธิ์รวมถึงตัวระบุสำหรับผู้ใช้ (sub) ตัวระบุสำหรับผู้ให้บริการข้อมูลประจำตัวที่ออกโทเค็น (iss) และตัวระบุของลูกค้าที่สร้างโทเค็นนี้ ( AUD)

ใน Go คุณสามารถดู coreos / dex, OpenID Connect Identity (OIDC) และผู้ให้บริการ OAuth 2.0 ที่มีตัวเชื่อมต่อแบบเสียบได้

คำตอบจากโพสต์นี้vonc


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

3

ฉันจะตอบคำถามนี้แตกต่างกันเล็กน้อยและฉันจะแม่นยำมากและสั้น ๆ ส่วนใหญ่เพราะ @Peter T ตอบทุกอย่าง

กำไรหลักที่ฉันเห็นจากมาตรฐานนี้คือการเคารพหลักการสองข้อ:

  1. แยกความกังวล
  2. การแยกการพิสูจน์ตัวตนจากเว็บแอปพลิเคชันซึ่งโดยทั่วไปจะให้บริการทางธุรกิจ

โดยการทำเช่นนั้น

  1. คุณสามารถใช้ทางเลือกเดียวกับการลงชื่อเข้าใช้ครั้งเดียว: หากคุณมีหลายแอปพลิเคชันที่ไว้วางใจ STS เดียว ฉันหมายถึงชื่อผู้ใช้เดียวสำหรับทุกแอปพลิเคชัน
  2. คุณสามารถเปิดใช้งานเว็บแอปพลิเคชันของคุณ (ไคลเอ็นต์) เพื่อเข้าถึงทรัพยากรที่เป็นของผู้ใช้และไม่ได้เป็นของเว็บแอปพลิเคชัน (ไคลเอ็นต์)
  3. คุณสามารถมอบอำนาจให้กระบวนการรับรองความถูกต้องแก่บุคคลที่สามที่คุณเชื่อถือและไม่ต้องกังวลเกี่ยวกับการตรวจสอบความถูกต้องของผู้ใช้
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.