ขั้นตอนการลงชื่อเพียงครั้งเดียวโดยใช้ JWT สำหรับการตรวจสอบสิทธิ์ข้ามโดเมน


113

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

ฉันทำงานให้กับ บริษัท แห่งหนึ่งซึ่งมีไซต์จำนวนมากในโฮสต์ที่แตกต่างกัน ใช้ Let 's example1.comและexample2.com เราจำเป็นต้องมี single sign-on วิธีการแก้ปัญหาซึ่งหมายความว่าถ้าพิสูจน์ผู้ใช้บนexample1.comเราต้องการให้เขายังได้รับการรับรองความถูกต้องในexample2.comโดยอัตโนมัติ

เมื่อใช้ขั้นตอนการเชื่อมต่อ OpenIdฉันเข้าใจว่าผู้ใช้ที่ต้องการตรวจสอบสิทธิ์บนexample1.comจะถูกเปลี่ยนเส้นทางไปยังเซิร์ฟเวอร์การตรวจสอบความถูกต้อง (หรือOP: "OpenId Provider") ผู้ใช้พิสูจน์ตัวตนบนเซิร์ฟเวอร์นั้นซึ่งจะเปลี่ยนเส้นทางเขากลับไปยังไซต์example1.comดั้งเดิมด้วยโทเค็น JWT ที่ลงชื่อ (ฉันเข้าใจว่ามีอีกขั้นตอนหนึ่งที่ส่งคืนโทเค็นระดับกลางที่สามารถแลกเปลี่ยนกับโทเค็น JWT จริงได้ในภายหลัง แต่ฉันไม่คิดว่าสิ่งนี้จำเป็นสำหรับเรา) ...

ตอนนี้ผู้ใช้กลับมาที่example1.comและได้รับการรับรองความถูกต้องแล้ว! เขาสามารถส่งคำขอส่งโทเค็น JWT ในAuthenticationส่วนหัวและเซิร์ฟเวอร์สามารถตรวจสอบ JWT ที่ลงนามแล้วดังนั้นจึงสามารถระบุผู้ใช้ได้ ดี!

คำถามแรก:

ควรเก็บโทเค็น JWT บนไคลเอนต์อย่างไร นอกจากนี้อีกครั้งข้อมูลจำนวนมากเกี่ยวกับเรื่องนี้และคนที่ดูเหมือนจะยอมรับว่าการใช้เป็นวิธีที่จะไปมากกว่าดีเก่าWeb Storage cookiesเราต้องการให้ JWT คงอยู่ระหว่างการรีสตาร์ทเบราว์เซอร์ดังนั้นขอใช้Local Storageไม่ใช่Session Storage...

ตอนนี้ผู้ใช้สามารถรีสตาร์ทเบราว์เซอร์ได้และจะยังคงได้รับการรับรองความถูกต้องบนexample1.comตราบใดที่โทเค็น JWT ยังไม่หมดอายุ!

นอกจากนี้หากexample1.comต้องการส่งคำขอ Ajax ไปยังโดเมนอื่นของเราฉันเข้าใจว่าการกำหนดค่าCORSจะอนุญาตให้ทำได้ แต่กรณีการใช้งานหลักของเราไม่ใช่คำขอข้ามโดเมน แต่มีโซลูชันการลงชื่อเพียงครั้งเดียว !

ดังนั้นคำถามหลัก:

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

ควร:

  • ผู้ใช้ถูกเปลี่ยนเส้นทางไปยังเซิร์ฟเวอร์การตรวจสอบอีกครั้งหรือไม่? เมื่อผู้ใช้รับรองความถูกต้องสำหรับexample1.comที่ เซิร์ฟเวอร์การตรวจสอบอาจมีการตั้งค่าคุกกี้กับผู้ใช้เพื่อให้การตรวจสอบคำขอใหม่สำหรับexample2.comสามารถใช้คุกกี้ที่จะเห็นว่าผู้ใช้จะได้รับรองความถูกต้องแล้วและทันทีที่เปลี่ยนเส้นทางไปเขากลับไป example2.comด้วยโทเค็น JWT เดียวกันหรือไม่
  • หรือเบราว์เซอร์บนexample2.comสามารถเข้าถึงโทเค็น JWT โดยไม่ต้องไปที่เซิร์ฟเวอร์การตรวจสอบอีกครั้งได้หรือไม่? ฉันเห็นว่ามีโซลูชันการจัดเก็บข้ามพื้นที่แต่ใช้กันอย่างแพร่หลายหรือไม่ เป็นโซลูชันที่แนะนำสำหรับสภาพแวดล้อม SSO ข้ามโดเมนหรือไม่

เราไม่ต้องการอะไรที่หรูหราเรายินดีกับโซลูชันที่ใช้เป็นส่วนใหญ่!

คำตอบ:


28

ผู้ใช้ควรถูกเปลี่ยนเส้นทางไปยังเซิร์ฟเวอร์การพิสูจน์ตัวตนอีกครั้งและรับโทเค็นใหม่ (JWT) ซึ่งเป็นโทเค็นที่กำหนดเป้าหมายโดยเฉพาะสำหรับ example2.com นี่คือวิธีการทำงานของ OpenID Connect และโปรโตคอล SSO แบบรวมข้ามโดเมนอื่น ๆ


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

7
แต่ถ้าผู้ใช้กำหนดค่าเบราว์เซอร์ให้บล็อกคุกกี้ทั้งหมดล่ะ?
Christiaan Westerbeek

1
ฉันเดาว่าควรมีคำเตือนเกี่ยวกับคุกกี้ว่า "ไซต์อาจทำงานไม่ถูกต้องหากเบราว์เซอร์ของคุณบล็อกคุกกี้"
AnBisw

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

36

การเปลี่ยนเส้นทางผู้ใช้ไปยังบริการรับรองความถูกต้องส่วนกลางเมื่อผู้ใช้ไม่ได้เข้าสู่ระบบเพื่อขอหนังสือรับรองและออกโทเค็นการตรวจสอบสิทธิ์ใหม่เป็นสถานการณ์ทั่วไปในระบบ Single Sign On โดยใช้โปรโตคอลที่รู้จักกันดีเช่น oauth2 หรือ OpenId Connect

อย่างไรก็ตามเมื่อใช้สคีมานี้ข้ามโดเมนข้อเสียเปรียบหลักคือผู้ใช้จะถูกเปลี่ยนเส้นทางและรับรองความถูกต้องทุกครั้งที่ไปยังโดเมนอื่นเนื่องจากนโยบายที่มาเดียวกัน : โทเค็นการเข้าถึงไม่สามารถแชร์ระหว่างโดเมนได้ ( example2.comไม่สามารถเข้าถึงข้อมูลได้ ของexample1.com) ดังนั้นโดเมนเป้าหมายจะถือว่าผู้ใช้ไม่ได้รับการตรวจสอบสิทธิ์โดยเปลี่ยนเส้นทางเขาไปยังบริการ SSO ส่วนกลาง

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

  1. ในการพิสูจน์ตัวตนผู้ใช้example1.comให้เปลี่ยนเส้นทางไปยังเซิร์ฟเวอร์การตรวจสอบความถูกต้องในsso.example.comออก JWT หลังจากพิสูจน์ตัวตนและเก็บไว้ใน localStorage ของโดเมนนี้ หลังจากนี้ให้เปลี่ยนเส้นทางผู้ใช้ไปยังโดเมนต้นทาง example1.com

  2. สร้าง iframe ในชี้ไปที่example2.com sso.example.comiframe ใน sso.example.com อ่านโทเค็น JWT และส่งข้อความไปยังเพจพาเรนต์

  3. เพจพาเรนต์ได้รับข้อความและรับโทเค็นที่แนบมาโดยดำเนินการต่อด้วยโฟลว์ SSO

ไม่มีปัญหากับนโยบายต้นทางเดียวกันเนื่องจากsso.example.comสามารถเข้าถึง localStorage ได้และอนุญาตให้มีการสื่อสารระหว่าง iframe และเพจพาเรนต์ได้หากโดเมนต้นทางและโดเมนเป้าหมายรู้จักกัน (ดูhttp://blog.teamtreehouse.com/cross-domain- การส่งข้อความกับโพสต์ข้อความ )

เพื่อให้การพัฒนาง่ายขึ้นเราเพิ่งเปิดตัวSSO ข้ามโดเมนพร้อม JWT ที่https://github.com/Aralink/ssojwt

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


3
นอกเหนือจากโซลูชันนี้ที่ไม่เป็นไปตามมาตรฐานโดยปกติแล้วใน SSO ข้ามโดเมนหนึ่งจะข้ามขอบเขตการดูแลระบบและในกรณีนั้นการใช้ JWT เดียวกันสำหรับทั้งสองโดเมนจะเปิดโอกาสให้เจ้าของแอปพลิเคชันในโดเมนหนึ่งแอบอ้างเป็นผู้ใช้ในอีกโดเมนหนึ่ง โดเมน
Hans Z.

6
ขอบคุณ @HansZ เราได้นำโซลูชันนี้ไปใช้จริงเพื่อให้มีการดูแลระบบเดียวในหลายโดเมนโดยมีแอปพลิเคชันมากมายและผู้ใช้รายเดียวกัน การทำงานคล้ายกับระบบของ Google (ค่อนข้างพูด)
pedrofb

2

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

ดังนั้น example1.com example2.com

จะกลายเป็นสิ่งที่ชอบ

example.com/example1

example.com/example2

(และจากฝั่งผู้ใช้มักจะสะอาดกว่า)

หากไม่ใช่ตัวเลือกคุณอาจต้องตั้งค่าเพื่อให้เมื่อผู้ใช้ตรวจสอบสิทธิ์ในโดเมน 1 โดเมนจะใช้ AJAX / hidden iframes เพื่อสร้างการตรวจสอบสิทธิ์กับโดเมนอื่นด้วย (ส่งโทเค็น 1 ครั้งผ่าน url หากคุณต้อง ).

และหากนั่นไม่ใช่ตัวเลือกคุณอาจต้องใช้ username + pin เนื่องจากเบราว์เซอร์มีความเข้มงวดมากขึ้นเกี่ยวกับการโต้ตอบข้ามโดเมน

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