คุณกำลังดูเอกสารประกอบของ Apigee Edge
ไปที่
เอกสารประกอบของ Apigee X info
หัวข้อนี้ให้ข้อมูลทั่วไปเกี่ยวกับ JWT (JSON Web Token) และ JWS (JSON Web Signature) รวมถึงนโยบาย JWS/JWT ของ Apigee ที่อาจเป็นประโยชน์ต่อนักพัฒนาพร็อกซี Apigee
บทนำ
ทั้ง JWS และ JWT ใช้กันโดยทั่วไปเพื่อแชร์การอ้างสิทธิ์หรือการยืนยันระหว่างแอปพลิเคชันที่เชื่อมต่อ นโยบาย JWS/JWT ช่วยให้พร็อกซี API ของ Edge ทำสิ่งต่อไปนี้ได้
- สร้าง JWT หรือ JWS ที่ลงชื่อแล้ว
- ยืนยัน JWT หรือ JWS ที่ลงชื่อแล้วและการอ้างสิทธิ์ภายใน JWS/JWT
- ถอดรหัส JWT หรือ JWS ที่ลงชื่อแล้วโดยไม่ต้องตรวจสอบลายเซ็น
ใน 2 กรณีหลัง นโยบายยังตั้งค่าตัวแปรที่อนุญาตให้นโยบายเพิ่มเติมหรือบริการแบ็กเอนด์เองตรวจสอบการอ้างสิทธิ์ที่ตรวจสอบแล้วและตัดสินใจตามการอ้างสิทธิ์เหล่านั้น
เมื่อใช้นโยบาย Verify JWS/JWT ระบบจะปฏิเสธ JWS/JWT ที่ไม่ถูกต้องและทำให้เกิดเงื่อนไขข้อผิดพลาด ในทำนองเดียวกัน เมื่อใช้นโยบาย Decode JWS/JWT ระบบจะทำให้เกิดเงื่อนไขข้อผิดพลาด หาก JWS/JWT มีรูปแบบไม่ถูกต้อง
วิดีโอ
ดูวิดีโอสั้นๆ เพื่อดูข้อมูลเบื้องต้นเกี่ยวกับ JWT แม้ว่าวิดีโอนี้จะ เจาะจงไปที่การสร้าง JWT แต่แนวคิดหลายอย่างก็เหมือนกับ JWS
ดูวิดีโอสั้นๆ เพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับโครงสร้าง JWT
กรณีการใช้งาน
คุณสามารถใช้นโยบาย JWS/JWT เพื่อทำสิ่งต่อไปนี้
- สร้าง JWS/JWT ใหม่ที่ด้านพร็อกซีหรือปลายทางเป้าหมายของพร็อกซี Edge เช่น คุณอาจสร้างโฟลว์คำขอพร็อกซีที่สร้าง JWS/JWT และส่งกลับไปยังไคลเอ็นต์ หรือคุณอาจออกแบบพร็อกซีเพื่อให้สร้าง JWS/JWT ในโฟลว์คำขอเป้าหมายและ แนบ JWS/JWT กับคำขอที่ส่งไปยังเป้าหมาย จากนั้นการอ้างสิทธิ์เหล่านั้นจะพร้อมใช้งานเพื่อให้บริการ แบ็กเอนด์ใช้การประมวลผลด้านความปลอดภัยเพิ่มเติมได้
- ยืนยันและแยกการอ้างสิทธิ์จาก JWS/JWT ที่ได้รับจากคำขอของไคลเอ็นต์ขาเข้า, การตอบกลับของบริการเป้าหมาย การตอบกลับของนโยบาย Service Callout หรือจากแหล่งที่มาอื่นๆ Edge จะ ยืนยันลายเซ็นใน JWS/JWT ไม่ว่า JWS/JWT จะสร้างขึ้นโดยบุคคลที่สามหรือโดย Edge เอง โดยใช้อัลกอริทึม RSA หรือ HMAC
- ถอดรหัส JWS/JWT การถอดรหัสจะมีประโยชน์มากที่สุดเมื่อใช้ร่วมกับนโยบาย Verify JWS/JWT ในกรณีที่ต้องทราบค่าของการอ้างสิทธิ์ (JWT) หรือส่วนหัว (JWS/JWT) จากภายใน JWS/JWT ก่อนที่จะยืนยัน JWS/JWT
ส่วนต่างๆ ของ JWS/JWT
JWS/JWT ที่ลงชื่อแล้วจะเข้ารหัสข้อมูลเป็น 3 ส่วนที่คั่นด้วยจุด ได้แก่ ส่วนหัว เพย์โหลด และ ลายเซ็น
header.payload.signature
- นโยบาย Generate JWS/JWT จะสร้างทั้ง 3 ส่วน
- นโยบาย Verify JWS/JWT จะตรวจสอบทั้ง 3 ส่วน
- นโยบาย Decode JWS/JWT จะตรวจสอบเฉพาะส่วนหัวและเพย์โหลด
นอกจากนี้ JWS ยังรองรับรูปแบบ แยก ซึ่งละเว้นเพย์โหลดจาก JWS
header..signature
ใน JWS ที่แยก เพย์โหลดจะถูกส่งแยกจาก JWS คุณใช้
<DetachedContent> องค์ประกอบของนโยบาย Verify JWS เพื่อระบุเพย์โหลด JWS ดิบที่ไม่ได้เข้ารหัส
จากนั้นนโยบาย Verify JWS จะยืนยัน JWS โดยใช้ส่วนหัวและลายเซ็นใน JWS รวมถึงเพย์โหลด
ที่ระบุโดยองค์ประกอบ <DetachedContent>
ดูข้อมูลเพิ่มเติมเกี่ยวกับโทเค็น รวมถึงวิธีเข้ารหัสและลงชื่อโทเค็นได้ที่
- JWT: IETF RFC7519
- JWS: IETF RFC7515
ความแตกต่างระหว่าง JWS กับ JWT
คุณสามารถใช้ JWT หรือ JWS เพื่อแชร์การอ้างสิทธิ์หรือการยืนยันระหว่างแอปพลิเคชันที่เชื่อมต่อ ความแตกต่างที่สำคัญระหว่าง JWT กับ JWS คือการแสดงเพย์โหลด ดังนี้
- JWT
- เพย์โหลดจะเป็นออบเจ็กต์ JSON เสมอ
- เพย์โหลดจะแนบกับ JWT เสมอ
- ระบบจะตั้งค่าส่วนหัว
typของโทเค็นเป็นJWTเสมอ
- JWS
- เพย์โหลดสามารถแสดงได้ในรูปแบบใดก็ได้ เช่น ออบเจ็กต์ JSON, สตรีมไบต์, สตรีมออกเต็ต และอื่นๆ
- เพย์โหลดไม่จำเป็นต้องแนบกับ JWS
เนื่องจากรูปแบบ JWT ใช้เฉพาะออบเจ็กต์ JSON เพื่อแสดงเพย์โหลด นโยบาย Generate JWT และ Verify JWT ของ Edge จึงมีการรองรับในตัวเพื่อจัดการชื่อการอ้างสิทธิ์ที่ลงทะเบียนไว้ทั่วไป เช่น aud, iss, sub และอื่นๆ ซึ่งหมายความว่าคุณสามารถใช้องค์ประกอบของ นโยบาย Generate JWT เพื่อตั้งค่าการอ้างสิทธิ์เหล่านี้ในเพย์โหลด และใช้องค์ประกอบของนโยบาย Verify JWT เพื่อยืนยันค่าของการอ้างสิทธิ์ ดูข้อมูลเพิ่มเติมได้ที่ส่วนชื่อการอ้างสิทธิ์ที่ลงทะเบียนไว้ ของข้อกำหนด JWT
นอกจากจะรองรับชื่อการอ้างสิทธิ์ที่ลงทะเบียนไว้บางชื่อแล้ว นโยบาย Generate JWT ยังรองรับการเพิ่มการอ้างสิทธิ์ที่มีชื่อที่กำหนดเองลงใน JWT โดยตรง การอ้างสิทธิ์แต่ละรายการเป็นคู่ชื่อ/ค่าอย่างง่าย โดยค่าอาจเป็นตัวเลข บูลีน สตริง แผนที่ หรืออาร์เรย์
เนื่องจาก JWS สามารถใช้การแสดงข้อมูลใดก็ได้สำหรับเพย์โหลด คุณจึงเพิ่มการอ้างสิทธิ์ลงในเพย์โหลดไม่ได้ อย่างไรก็ตาม นโยบาย Generate JWS รองรับการเพิ่มการอ้างสิทธิ์ที่มีชื่อที่กำหนดเองลงในส่วนหัวของ JWS นอกจากนี้ นโยบาย JWS ยังรองรับเพย์โหลดที่แยก ซึ่ง JWS จะละเว้นเพย์โหลด เพย์โหลดที่แยกช่วยให้คุณส่ง JWS และเพย์โหลดแยกกันได้ และมาตรฐานความปลอดภัยหลายรายการกำหนดให้ต้องทำเช่นนี้
ป้องกันการแทรกเทมเพลตเมื่อใช้ JWS และ JWT
หากต้องการป้องกันการเปิดเผยข้อมูลโดยไม่ได้รับอนุญาต ให้ทำตามหลักเกณฑ์ต่อไปนี้เมื่อใช้นโยบาย GenerateJWT หรือ GenerateJWS
- หลีกเลี่ยงการอ้างอิงข้อมูลจากผู้ใช้โดยตรง: อย่าใช้ข้อมูลที่ไม่น่าเชื่อถือ (เช่น
request.queryparam.*หรือrequest.header.*) โดยตรงในแอตทริบิวต์refที่รองรับการใช้เทมเพลต - ล้างข้อมูลอินพุต: หากต้องใช้ข้อมูลภายนอกในการอ้างสิทธิ์ JWT/JWS ให้ใช้
นโยบาย AssignMessage
เพื่อนำวงเล็บปีกกา (
{ }) หรืออักขระเทมเพลตอื่นๆ ออกจากอินพุต ก่อนที่จะอ้างอิง - ใช้การอ้างสิทธิ์ที่ชัดเจนสำหรับสตริง: สำหรับการอ้างสิทธิ์สตริงอย่างง่าย ให้หลีกเลี่ยง
type="map". การใช้ค่าเริ่มต้นtype="string"จะป้องกันการใช้เทมเพลตโดยนัย ของค่าที่อ้างอิง - โปรดทราบถึงความไม่สอดคล้องกันของลักษณะการทำงานระหว่างนโยบายการยืนยันและนโยบายการสร้าง: นโยบายการสร้าง JWS และ JWT มีลักษณะการทำงานที่แตกต่างจากนโยบายการยืนยันเกี่ยวกับการใช้เทมเพลต
เกี่ยวกับอัลกอริทึมลายเซ็น
นโยบายการยืนยัน JWS/JWT และนโยบายการสร้าง JWS/JWT รองรับอัลกอริทึม RSA, RSASSA-PSS, ECDSA และ HMAC โดยใช้ผลรวมตรวจสอบ SHA2 ที่มีความแรงของบิต 256, 384 หรือ 512 นโยบายการถอดรหัส JWS/JWT จะทำงานโดยไม่คำนึงถึง อัลกอริทึมที่ใช้ลงชื่อ JWS/JWT
อัลกอริทึม HMAC
อัลกอริทึม HMAC อาศัยข้อมูลลับที่ใช้ร่วมกัน ซึ่งเรียกว่าคีย์ลับ ในการสร้าง ลายเซ็น (หรือที่เรียกว่าการลงชื่อ JWS/JWT) และในการยืนยันลายเซ็น
ความยาวขั้นต่ำของคีย์ลับจะขึ้นอยู่กับความแรงของบิตของอัลกอริทึม ดังนี้
- HS256: ความยาวคีย์ขั้นต่ำ 32 ไบต์
- HS386: ความยาวคีย์ขั้นต่ำ 48 ไบต์
- HS512: ความยาวคีย์ขั้นต่ำ 64 ไบต์
อัลกอริทึม RSA
อัลกอริทึม RSA ใช้คู่คีย์สาธารณะ/ส่วนตัวสำหรับลายเซ็นการเข้ารหัส เมื่อใช้ลายเซ็น RSA ฝ่ายลงชื่อจะใช้คีย์ส่วนตัว RSA เพื่อลงชื่อ JWS/JWT และฝ่ายยืนยันจะใช้ คีย์สาธารณะ RSA ที่ตรงกันเพื่อยืนยันลายเซ็นใน JWS/JWT ไม่มีข้อกำหนดด้านขนาดสำหรับ คีย์
อัลกอริทึม RSASSA-PSS
อัลกอริทึม RSASSA-PSS เป็นอัลกอริทึม RSA ที่อัปเดต เช่นเดียวกับ RSS อัลกอริทึม RSASSA-PSS ใช้คู่คีย์สาธารณะ/ส่วนตัว RSA สำหรับลายเซ็นการเข้ารหัส รูปแบบของคีย์จะเหมือนกับ RSS ฝ่ายลงชื่อจะใช้คีย์ส่วนตัวเพื่อลงชื่อ JWS/JWT และฝ่ายยืนยันจะใช้คีย์สาธารณะที่ตรงกัน เพื่อยืนยันลายเซ็นใน JWS/JWT ไม่มีข้อกำหนดด้านขนาดสำหรับคีย์
อัลกอริทึม ECDSA
อัลกอริทึม Elliptic Curve Digital Signature Algorithm (ECDSA) เป็นอัลกอริทึมการเข้ารหัสเส้นโค้งวงรี ที่มีเส้นโค้ง P-256, P-384 และ P-521 เมื่อใช้อัลกอริทึม ECDSA อัลกอริทึมจะกำหนด ประเภทคีย์สาธารณะและคีย์ส่วนตัวที่คุณต้องระบุ
| อัลกอริทึม | เส้นโค้ง | ข้อกำหนดที่สำคัญ |
|---|---|---|
| ES256 | P-256 | คีย์ที่สร้างจากเส้นโค้ง P-256 (หรือที่เรียกว่า secp256r1 หรือ prime256v1) |
| ES384 | P-384 | คีย์ที่สร้างจากเส้นโค้ง P-384 (หรือที่เรียกว่า secp384r1) |
| ES512 | P-521 | คีย์ที่สร้างจากเส้นโค้ง P-521 (หรือที่เรียกว่า secp521r1) |
อัลกอริทึมการเข้ารหัสคีย์
นโยบาย JWS/JWT รองรับอัลกอริทึมการเข้ารหัสคีย์ทั้งหมดที่ OpenSSL รองรับ
การใช้ JSON Web Key Set (JWKS) เพื่อยืนยัน JWS/JWT
เมื่อยืนยัน JWS/JWT ที่ลงชื่อแล้ว คุณต้องระบุคีย์สาธารณะที่ เชื่อมโยงกับคีย์ส่วนตัวที่ใช้ลงชื่อโทเค็น คุณมีตัวเลือก 2 รายการ ในการ ระบุคีย์สาธารณะสำหรับนโยบายการยืนยัน JWS/JWT ดังนี้
- ใช้ค่าคีย์สาธารณะจริง (โดยปกติจะระบุไว้ในตัวแปรโฟลว์) หรือ
- ใช้คีย์สาธารณะที่ห่อหุ้มไว้ใน JWKS
เกี่ยวกับ JWKS
JWKS เป็นโครงสร้าง JSON ที่แสดงชุด JSON Web Key (JWK) JWK เป็นโครงสร้างข้อมูล JSON ที่แสดงคีย์การเข้ารหัส JWK และ JWKS อธิบายไว้ใน RFC7517 ดูตัวอย่าง JKWS ได้ที่ ภาคผนวก ก ตัวอย่าง JSON Web Key Set
โครงสร้าง JWKS
RFC7517 อธิบายองค์ประกอบคีย์ JWKS สำหรับคีย์แต่ละประเภท เช่น "RSA" หรือ "EC" ตัวอย่างเช่น ทั้งนี้ขึ้นอยู่กับประเภทคีย์ พารามิเตอร์เหล่านี้อาจรวมถึงสิ่งต่อไปนี้
- kty - ประเภทคีย์ เช่น "RSA" หรือ "EC"
- kid (รหัสคีย์) - อาจเป็นค่าที่กำหนดเอง (ไม่ซ้ำกันภายในชุดคีย์ ) หาก JWT ขาเข้ามีรหัสคีย์ที่อยู่ในชุด JWKS นโยบาย จะใช้คีย์สาธารณะที่ถูกต้องเพื่อยืนยันลายเซ็น JWS/JWT
ตัวอย่างองค์ประกอบที่ไม่บังคับและค่าขององค์ประกอบดังกล่าว
- alg - อัลกอริทึมคีย์ ต้องตรงกับอัลกอริทึมการลงชื่อใน JWS/JWT
- use - หากมี ต้องเป็น sig
JWKS ต่อไปนี้มีองค์ประกอบและค่าที่จำเป็น และจะถูกต้องใน Edge (จาก https://www.googleapis.com/oauth2/v3/certs)
{
"keys":[
{
"kty":"RSA",
"alg":"RS256",
"use":"sig",
"kid":"ca04df587b5a7cead80abee9ea8dcf7586a78e01",
"n":"iXn-WmrwLLBa-QDiToBozpu4Y4ThKdwORWFXQa9I75pKOvPUjUjE2Bk05TUSt7-V7KDjCq0_Nkd-X9rMRV5LKgCa0_F8YgI30QS3bUm9orFryrdOc65PUIVFVxIwMZuGDY1hj6HEJVWIr0CZdcgNIll06BasclckkUK4O-Eh7MaQrqb646ghFlG3zlgk9b2duHbDOq3s39ICPinRQWC6NqTYfqg7E8GN_NLY9srUCc_MswuUfMJ2cKT6edrhLuIwIj_74YGkpOwilr2VswKsvJ7dcoiJxheKYvKDKtZFkbKrWETTJSGX2Xeh0DFB0lqbKLVvqkM2lFU2Qx1OgtTnrw",
"e":"AQAB"
},
{
"kty":"EC",
"alg":"ES256",
"use":"enc",
"kid":"k05TUSt7-V7KDjCq0_N"
"crv":"P-256",
"x":"Xej56MungXuFZwmk_xccvsMpCtXmqhvEEMCmHyAmKF0",
"y":"Bozpu4Y4ThKdwORWFXQa9I75pKOvPUjUjE2Bk05TUSt",
}
]
}การออกแบบพร็อกซีให้ ใช้ JWKS
เมื่อได้รับ JWS/JWT จากผู้ออก ผู้ออกมักจะแทรกรหัสคีย์ (หรือ kid) ลงในส่วนหัว JWS/JWT คีย์จะบอกผู้รับ JWS/JWT ถึงวิธีค้นหาคีย์สาธารณะหรือคีย์ลับที่จำเป็นในการ ยืนยันลายเซ็นใน JWS/JWT ที่ลงชื่อแล้ว
ตัวอย่างเช่น สมมติว่าผู้ออกลงชื่อ JWT ด้วยคีย์ส่วนตัว "รหัสคีย์" จะระบุคีย์สาธารณะที่ตรงกัน เพื่อใช้ยืนยัน JWT โดยปกติแล้วรายการคีย์สาธารณะจะพร้อมใช้งานที่ ปลายทางที่รู้จักกันดี เช่น https://www.googleapis.com/oauth2/v3/certs
นี่คือลำดับพื้นฐานที่ Edge (หรือแพลตฟอร์มใดก็ตามที่ทำงานร่วมกับ JWKS) ต้องดำเนินการ เพื่อทำงานร่วมกับ JWS/JWT ที่มี JWKS
- ตรวจสอบส่วนหัว JWS/JWT เพื่อหารหัสคีย์ (kid)
- ตรวจสอบส่วนหัว JWS/JWT เพื่อค้นหาอัลกอริทึมการลงชื่อ (alg) เช่น RS256
- ดึงรายการคีย์และรหัสจาก JWKS ของปลายทางที่รู้จักกันดีสำหรับผู้ออกที่ระบุ
- แยกคีย์สาธารณะจากรายการคีย์ที่มีรหัสคีย์ที่ระบุไว้ในส่วนหัว JWS/JWT และมีอัลกอริทึมที่ตรงกัน หากคีย์ JWKS ระบุอัลกอริทึม
- ใช้คีย์สาธารณะนั้นเพื่อยืนยันลายเซ็นใน JWS/JWT
ในฐานะนักพัฒนาพร็อกซี API ของ Edge คุณต้องทำสิ่งต่อไปนี้เพื่อยืนยัน JWS/JWT
- ดึงรายการคีย์และรหัสจากปลายทางที่รู้จักกันดีสำหรับผู้ออกที่ระบุ คุณสามารถ ใช้นโยบาย Service Callout สำหรับขั้นตอนนี้ได้
- ในนโยบาย Verify JWS/JWT ให้ระบุตำแหน่งของ JWS/JWT ในองค์ประกอบ
<Source>และเพย์โหลด JWKS ในองค์ประกอบ<PublicKey/JWKS>ตัวอย่างเช่น สำหรับนโยบาย VerifyJWT<VerifyJWT name="JWT-Verify-RS256"> <Algorithm>RS256</Algorithm> <Source>json.jwt</Source> <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables> <PublicKey> <JWKS ref="public.jwks"/> </PublicKey> <Subject>apigee-seattle-hatrack-montage</Subject> <Issuer>urn://apigee-edge-JWT-policy-test</Issuer> <Audience>urn://c60511c0-12a2-473c-80fd-42528eb65a6a</Audience> <AdditionalClaims> <Claim name="show">And now for something completely different.</Claim> </AdditionalClaims> </VerifyJWT>
นโยบาย Verify JWT จะดำเนินการอื่นๆ ทั้งหมด ดังนี้
- หากไม่พบคีย์ที่มีรหัสคีย์ที่ตรงกับรหัสคีย์ (kid) ที่ยืนยันใน JWT ใน JWKS นโยบาย Verify JWT จะแสดงข้อผิดพลาดและไม่ตรวจสอบ JWT
- หาก JWT ขาเข้าไม่มีรหัสคีย์ (kid) ในส่วนหัว การแมปรหัสคีย์กับคีย์การยืนยันนี้จะเป็นไปไม่ได้
ในฐานะผู้ออกแบบพร็อกซี คุณมีหน้าที่รับผิดชอบในการกำหนดคีย์ที่จะใช้ ซึ่งในบางกรณีนี้ อาจเป็นคีย์ที่คงที่และฮาร์ดโค้ด