คำตอบสำหรับคำถามของคุณอาจอยู่ในระดับรหัสระดับโปรโตคอลหรือระดับสถาปัตยกรรม ฉันจะพยายามสรุปประเด็นปัญหาระดับโปรโตคอลส่วนใหญ่ที่นี่เนื่องจากเป็นเรื่องสำคัญในการวิเคราะห์ข้อดีข้อเสีย โปรดทราบว่าOAuth2เป็นมากกว่าข้อมูลประจำตัวของรหัสผ่านเจ้าของทรัพยากรซึ่งตามข้อมูลจำเพาะมีอยู่สำหรับ "เหตุผลดั้งเดิมหรือเหตุผลในการย้ายข้อมูล" ถือว่าเป็น "ความเสี่ยงสูงกว่าประเภทการให้สิทธิ์อื่น" และข้อกำหนดระบุอย่างชัดเจนว่าลูกค้าและเซิร์ฟเวอร์การอนุญาต "ควรใช้การให้ทุนประเภทนี้ให้น้อยที่สุดและใช้การให้ทุนประเภทอื่นทุกครั้งที่ทำได้"
ยังคงมีข้อดีหลายประการของการใช้ ROPC ผ่านการรับรองความถูกต้องพื้นฐาน แต่ก่อนที่เราจะเข้าใจสิ่งนั้นให้เข้าใจถึงความแตกต่างของโปรโตคอลพื้นฐานระหว่าง OAuth2 และการรับรองความถูกต้องเบื้องต้น โปรดอดทนกับฉันเมื่อฉันอธิบายสิ่งเหล่านี้และจะมาที่ ROPC ในภายหลัง
กระแสการตรวจสอบผู้ใช้
มีสี่บทบาทที่กำหนดไว้ในข้อกำหนด OAuth2 ด้วยตัวอย่างคือ:
- เจ้าของทรัพยากร: ผู้ใช้ที่สามารถเข้าถึงทรัพยากรบางอย่างเช่นในกรณีของคุณผู้ใช้อื่นอาจมีระดับการเข้าถึง REST API ที่แตกต่างกัน
- ไคลเอนต์: โดยปกติคือแอปพลิเคชันที่ผู้ใช้ใช้และต้องการเข้าถึงทรัพยากรเพื่อให้บริการแก่ผู้ใช้
- เซิร์ฟเวอร์ทรัพยากร: REST API ในกรณีของคุณ และ
- เซิร์ฟเวอร์การอนุญาต: เซิร์ฟเวอร์ที่จะแสดงข้อมูลประจำตัวของผู้ใช้และจะรับรองความถูกต้องของผู้ใช้
เมื่อแอปพลิเคชันไคลเอนต์ทำงานจะได้รับสิทธิ์เข้าถึงทรัพยากรตามผู้ใช้ หากผู้ใช้มีสิทธิ์ของผู้ดูแลระบบทรัพยากรและการดำเนินงานที่มีให้กับผู้ใช้ใน REST API อาจมากกว่าผู้ใช้ที่ไม่มีสิทธิ์ของผู้ดูแลระบบ
OAuth2 ยังอนุญาตให้ใช้เซิร์ฟเวอร์การอนุญาตเดียวที่มีหลายไคลเอนต์และสำหรับทรัพยากรหลาย ๆ ตัวอย่างเช่นเซิร์ฟเวอร์ทรัพยากรสามารถยอมรับการตรวจสอบสิทธิ์ของผู้ใช้กับ Facebook (ซึ่งสามารถทำหน้าที่เป็นเซิร์ฟเวอร์การอนุญาตในกรณีดังกล่าว) ดังนั้นเมื่อผู้ใช้รันแอปพลิเคชั่น (เช่นไคลเอนต์) ก็จะส่งผู้ใช้ไปที่ Facebook ผู้ใช้พิมพ์ข้อมูลประจำตัวของพวกเขาใน Facebook และลูกค้าจะได้รับ "โทเค็น" ซึ่งสามารถนำเสนอไปยังเซิร์ฟเวอร์ทรัพยากร เซิร์ฟเวอร์ทรัพยากรดูที่โทเค็นและยอมรับหลังจากตรวจสอบว่า Facebook เป็นผู้ออกและอนุญาตให้ผู้ใช้เข้าถึงทรัพยากร ในกรณีนี้ลูกค้าไม่เคยเห็นข้อมูลรับรองของผู้ใช้ (เช่นข้อมูลรับรอง Facebook ของพวกเขา)
แต่สมมติว่าคุณกำลังจัดการข้อมูลประจำตัวของผู้ใช้ (และมีเซิร์ฟเวอร์การอนุญาต) แทน Facebook ซึ่งมอบโทเค็นให้กับลูกค้าของคุณแล้ว ตอนนี้สมมติว่าคุณมีพันธมิตรและคุณต้องการอนุญาตให้แอปพลิเคชันของพวกเขา (เช่นลูกค้า) เข้าถึง REST API ของคุณ ด้วยการรับรองความถูกต้องเบื้องต้น (หรือ ROPC) ผู้ใช้จะมอบข้อมูลประจำตัวให้กับลูกค้าซึ่งจะส่งไปยังเซิร์ฟเวอร์การให้สิทธิ์ เซิร์ฟเวอร์การอนุญาตจะให้โทเค็นที่ลูกค้าสามารถใช้เพื่อเข้าถึงทรัพยากร น่าเสียดายซึ่งหมายความว่าตอนนี้ข้อมูลประจำตัวของผู้ใช้ก็ปรากฏให้ลูกค้าเห็นเช่นกัน อย่างไรก็ตามคุณไม่ต้องการให้แอปพลิเคชันของพันธมิตร (ซึ่งอาจอยู่นอกองค์กรของคุณ) แม้แต่จะรู้รหัสผ่านของผู้ใช้ นั่นเป็นปัญหาด้านความปลอดภัยในขณะนี้ เพื่อให้บรรลุเป้าหมายนั้น
ดังนั้นด้วย OAuth2 เราจะไม่ใช้ ROPC ในกรณีเช่นนั้นแทนที่จะใช้ ROAuth2 ที่แตกต่างกันเช่นรหัสการอนุญาต สิ่งนี้ปกป้องแอปพลิเคชันใด ๆ จากการรู้ข้อมูลประจำตัวของผู้ใช้ซึ่งจะแสดงเฉพาะกับเซิร์ฟเวอร์การให้สิทธิ์ ดังนั้นข้อมูลประจำตัวของผู้ใช้จะไม่รั่วไหลออกมา ปัญหาเดียวกันนี้ใช้กับการรับรองความถูกต้องเบื้องต้น แต่ในส่วนถัดไปฉันจะอธิบายว่า ROPC ยังคงดีกว่าได้อย่างไรเนื่องจากข้อมูลประจำตัวของผู้ใช้ยังไม่จำเป็นต้องเก็บไว้ในไคลเอนต์ ROPC สำหรับการเข้าถึงลูกค้าโดยถาวร
โปรดทราบว่าเมื่อผู้ใช้ไปที่เซิร์ฟเวอร์การอนุญาตเซิร์ฟเวอร์การอนุญาตยังสามารถขอให้ผู้ใช้ยืนยันว่าพวกเขาต้องการอนุญาตให้ไคลเอ็นต์เข้าถึงทรัพยากรในนามของพวกเขาหรือไม่ นั่นคือสาเหตุที่เรียกว่า เซิร์ฟเวอร์การให้สิทธิ์เนื่องจากกระบวนการให้สิทธิ์แก่ลูกค้าในการเข้าถึงทรัพยากรนั้นได้รับการยอมรับในกระบวนการ หากผู้ใช้ไม่อนุญาตไคลเอ็นต์จะไม่สามารถเข้าถึงทรัพยากรได้ ในทำนองเดียวกันหากผู้ใช้เองไม่สามารถเข้าถึงทรัพยากรเซิร์ฟเวอร์การอนุญาตยังคงสามารถปฏิเสธการเข้าถึงและไม่ออกโทเค็น
ในการพิสูจน์ตัวตนพื้นฐานแม้แต่เซิร์ฟเวอร์การอนุญาตและเซิร์ฟเวอร์ทรัพยากรจะรวมกันเป็นเอนทิตีเดียว ดังนั้นเซิร์ฟเวอร์ทรัพยากรต้องการอนุญาตผู้ใช้จึงถามข้อมูลรับรองจากลูกค้า ไคลเอนต์ให้ข้อมูลประจำตัวเหล่านั้นซึ่งใช้โดยเซิร์ฟเวอร์ทรัพยากรเพื่อรับรองความถูกต้องของผู้ใช้ ซึ่งหมายความว่าเซิร์ฟเวอร์ทรัพยากรหลายแห่งจำเป็นต้องมีหนังสือรับรองจากผู้ใช้เป็นหลัก
การออกโทเค็น
ไคลเอนต์ได้รับโทเค็นจากเซิร์ฟเวอร์การอนุญาตเก็บไว้และใช้เพื่อเข้าถึงทรัพยากร (รายละเอียดเพิ่มเติมเกี่ยวกับโทเค็นด้านล่าง) ลูกค้าไม่เคยรู้รหัสผ่านของผู้ใช้ (ในโฟลว์นอกเหนือจาก ROPC) และไม่จำเป็นต้องเก็บไว้ ใน ROPC แม้ว่าลูกค้าจะรู้รหัสผ่านของผู้ใช้พวกเขายังไม่จำเป็นต้องเก็บไว้เพราะใช้โทเค็นเหล่านี้เพื่อเข้าถึงทรัพยากร ในทางตรงกันข้ามในการตรวจสอบเบื้องต้นหากลูกค้าไม่ต้องการให้ผู้ใช้ให้ข้อมูลประจำตัวในทุกเซสชั่นแล้วลูกค้าจะต้องเก็บรหัสผ่านของผู้ใช้เพื่อให้พวกเขาสามารถให้ในครั้งต่อไป นี่เป็นข้อเสียเปรียบหลักในการใช้การรับรองความถูกต้องเบื้องต้นเว้นแต่ว่าลูกค้าเป็นเพียงเว็บแอปพลิเคชั่นเท่านั้นในกรณีนี้คุกกี้สามารถตอบข้อกังวลเหล่านี้ได้ ด้วยแอปพลิเคชั่นดั้งเดิมนั่นไม่ใช่ตัวเลือก
มีอีกแง่มุมหนึ่งของ OAuth2 ซึ่งมีการมอบให้ในวิธีการออกโทเค็นและการทำงาน เมื่อผู้ใช้มอบข้อมูลรับรองให้กับเซิร์ฟเวอร์การอนุญาต (แม้ใน ROPC) เซิร์ฟเวอร์การให้สิทธิ์สามารถมอบโทเค็นการเข้าถึงหนึ่งหรือสองประเภท: 1) โทเค็นการเข้าถึงและ 2) รีเฟรชโทเค็น
โทเค็นการเข้าถึงจะถูกส่งไปยังเซิร์ฟเวอร์ทรัพยากรซึ่งจะให้สิทธิ์การเข้าถึงทรัพยากรหลังจากตรวจสอบความถูกต้องแล้วโดยปกติจะมีอายุการใช้งานสั้นเช่น 1 ชั่วโมง โทเค็นการรีเฟรชจะถูกส่งไปยังเซิร์ฟเวอร์การอนุญาตโดยลูกค้าเพื่อรับโทเค็นการเข้าถึงอีกครั้งเมื่อหมดอายุและมักจะมีอายุการใช้งานที่ยาวนาน (เช่นสองสามวันเป็นเดือนหรือเป็นปี)
เมื่อไคลเอ็นต์จัดให้มีโทเค็นการเข้าถึงไปยังเซิร์ฟเวอร์ทรัพยากรมันจะดูที่โทเค็นและหลังจากการตรวจสอบความถูกต้องแล้วมองเข้าไปในโทเค็นเพื่อพิจารณาว่าจะอนุญาตการเข้าถึงหรือไม่ ตราบใดที่โทเค็นการเข้าถึงนั้นถูกต้องไคลเอ็นต์สามารถใช้งานต่อไปได้ สมมติว่าผู้ใช้ปิดแอปพลิเคชันและเริ่มในวันถัดไปและโทเค็นการเข้าถึงหมดอายุแล้ว ตอนนี้ไคลเอนต์จะโทรไปยังเซิร์ฟเวอร์การให้สิทธิ์และแสดงโทเค็นการรีเฟรชโดยสมมติว่ามันยังไม่หมดอายุ เซิร์ฟเวอร์การให้สิทธิ์เนื่องจากมีการออกโทเค็นแล้วให้ทำการตรวจสอบและสามารถพิจารณาได้ว่าผู้ใช้ไม่จำเป็นต้องให้ข้อมูลประจำตัวอีกครั้งและมอบโทเค็นการเข้าถึงอื่นให้กับลูกค้า ตอนนี้ไคลเอ็นต์สามารถเข้าถึงเซิร์ฟเวอร์ทรัพยากรได้อีกครั้ง นี่คือวิธีที่แอปพลิเคชันไคลเอนต์สำหรับ Facebook และ Twitter ขอข้อมูลประจำตัวหนึ่งครั้งจากนั้นไม่ต้องการให้ผู้ใช้ระบุข้อมูลประจำตัวอีกครั้ง แอปพลิเคชันเหล่านี้ไม่จำเป็นต้องรู้ข้อมูลรับรองผู้ใช้และยังสามารถเข้าถึงทรัพยากรทุกครั้งที่ผู้ใช้เริ่มต้นแอปพลิเคชัน
ตอนนี้ผู้ใช้สามารถเข้าไปในเซิร์ฟเวอร์การอนุญาต (เช่นในโปรไฟล์ผู้ใช้ Facebook) เปลี่ยนรหัสผ่านโดยไม่ส่งผลกระทบต่อแอปพลิเคชันไคลเอนต์ใด ๆ พวกเขาทั้งหมดจะยังคงทำงานได้อย่างถูกต้อง หากผู้ใช้สูญเสียอุปกรณ์ที่มีแอปพลิเคชันที่มีโทเค็นการรีเฟรชอยู่แล้วพวกเขาสามารถบอกเซิร์ฟเวอร์การอนุญาต (เช่น Facebook) เพื่อ "ออกจากระบบ" ของแอปพลิเคชันที่เซิร์ฟเวอร์การอนุญาต (เช่น Facebook) จะทำได้สำเร็จ รีเฟรชโทเค็นและบังคับให้ผู้ใช้ระบุข้อมูลประจำตัวอีกครั้งเมื่อพวกเขาพยายามเข้าถึงทรัพยากรผ่านแอปพลิเคชันเหล่านั้น
JWTเป็นเพียงรูปแบบโทเค็นที่มักใช้กับ OAuth2 และ OpenID Connect วิธีการลงชื่อโทเค็นและตรวจสอบความถูกต้องเป็นมาตรฐานกับไลบรารีที่มีให้สำหรับผู้ที่ใช้แทนเซิร์ฟเวอร์ทรัพยากรทุกเครื่องที่ใช้งานโซลูชันอื่น ดังนั้นข้อได้เปรียบอยู่ในการใช้งานซ้ำของรหัสที่ได้รับการตรวจสอบและได้รับการสนับสนุนอย่างต่อเนื่อง
ผลกระทบด้านความปลอดภัย
การรับรองความถูกต้องเบื้องต้นจะอ่อนแอลงเมื่อสถานการณ์ใด ๆ ข้างต้นอยู่ในภาพ นอกจากนี้ยังมีรูปแบบการคุกคามที่ครอบคลุมสำหรับ OAuth2สำหรับนักพัฒนาที่สามารถใช้คำแนะนำในการหลีกเลี่ยงช่องโหว่ที่พบบ่อยในการใช้งาน หากคุณผ่านรูปแบบการคุกคามคุณจะเห็นว่ามีช่องโหว่ที่เกี่ยวข้องกับการติดตั้งใช้งานจำนวนมาก (เช่น open redirector และ CSRF) ฉันไม่ได้ทำการเปรียบเทียบกับการพิสูจน์ตัวตนพื้นฐานในการตอบกลับนี้
ข้อได้เปรียบที่สำคัญสุดท้ายของ OAuth2 คือโปรโตคอลเป็นมาตรฐานและเซิร์ฟเวอร์การอนุญาตหลายไคลเอนต์และเซิร์ฟเวอร์ทรัพยากรเคารพมัน มีไลบรารีจำนวนมากสำหรับนักพัฒนาซึ่งได้รับการดูแลรักษาเพื่อให้พบปัญหาด้านความปลอดภัยในการนำไปใช้งานห้องสมุดจะได้รับการอัปเดตในขณะที่อนุญาตการทำงานร่วมกัน
ข้อสรุป
หากคุณกำลังเขียนแอปพลิเคชันใหม่ IMO กรณีที่เหมาะสมที่สุดคือการหลีกเลี่ยงทั้งการตรวจสอบสิทธิ์พื้นฐานและ ROPC เนื่องจากปัญหาที่มีอยู่ในตัว อย่างไรก็ตามแต่ละแอปพลิเคชันมีความต้องการ, ระยะเวลา, ความสามารถของนักพัฒนาซอฟต์แวร์ที่แตกต่างกันดังนั้นการตัดสินใจเป็นกรณี ๆ ไป แต่แม้ว่าคุณจะไม่ต้องการมากกว่าการพิสูจน์ตัวตนพื้นฐานคุณสามารถล็อคตัวคุณเองเข้ากับสถาปัตยกรรมที่อาจไม่ขยายได้ง่าย (เช่นหากคุณมีเซิร์ฟเวอร์หลายเครื่องในอนาคตคุณไม่จำเป็นต้องมี ผู้ใช้ให้ข้อมูลประจำตัวแก่พวกเขาแต่ละคนเพียงแค่มอบให้กับเซิร์ฟเวอร์การอนุญาตครั้งเดียวซึ่งสามารถส่งสัญญาณโทเค็น ฯลฯ )
โปรดทราบว่าฉันไม่ได้พูดถึงความคิดเห็นของคุณเกี่ยวกับวิธีการส่งข้อมูลรับรองผ่านสายเพราะสามารถรักษาความปลอดภัยโดยใช้ TLS หรือโปรโตคอลที่คล้ายกันหรือหลักฐานการครอบครอง ฯลฯ ตามที่มีคนแนะนำแล้วการเข้ารหัส 64 ฐานคือ 0 ความปลอดภัยโปรดอย่า หลงลืมโดยที่ ความแตกต่างดังกล่าวข้างต้นมักจะอยู่ในระดับสถาปัตยกรรมและนั่นคือสิ่งที่ฉันมุ่งเน้นเพราะสถาปัตยกรรมยากที่สุดที่จะเปลี่ยนแปลงเมื่อดำเนินการ
Azure Active Directory B2C Basicเป็นบริการที่ฉันใช้งานและเปิดตัวเมื่อเร็ว ๆ นี้เพื่อให้ประชาชนทั่วไปอนุญาตให้แอปพลิเคชันบุคคลที่สามใช้ AAD เป็นเซิร์ฟเวอร์การอนุญาตที่มีการทำงานร่วมกันกับ IDP ทางสังคม (เช่น Facebook, Google เป็นต้น) นอกจากนี้ยังอนุญาตให้ผู้ใช้สร้างบัญชีของตนเองแทนที่จะใช้ IDP โซเชียลและสามารถใช้เพื่อวัตถุประสงค์ในการตรวจสอบสิทธิ์ในภายหลัง มีบริการอื่น ๆ อีกสองสามอย่างเช่นนั้น (เช่นอีกอันที่ฉันรู้จักคือauth0) ซึ่งนักพัฒนาซอฟต์แวร์สามารถใช้เพื่อรับรองความถูกต้องของแหล่งภายนอกและการจัดการผู้ใช้สำหรับแอปพลิเคชันและทรัพยากรของพวกเขา นักพัฒนาซอฟต์แวร์ใช้คุณสมบัติโปรโตคอลเดียวกับที่กล่าวถึงข้างต้นเพื่อแยกเซิร์ฟเวอร์การอนุญาต (AAD) ทรัพยากร (เช่น REST APIs) ลูกค้า (เช่นแอปพลิเคชันมือถือ) และผู้ใช้ ฉันหวังว่าคำอธิบายนี้จะช่วยได้บ้าง