บทนำ
APISIX เป็น API gateway ที่มีประสิทธิภาพสูงและสามารถขยายได้ตามความต้องการ พัฒนาบนพื้นฐานของ Nginx และ etcd เป็นโปรเจกต์โอเพนซอร์สโดยมูลนิธิซอฟต์แวร์ Apache นอกจากนี้สิ่งที่ทำให้ APISIX ดีเยี่ยมคือการสนับสนุนปลั๊กอินที่มีประสิทธิภาพมากมายที่สามารถใช้ในการดำเนินการฟีเจอร์ต่างๆ เช่น การตรวจสอบสิทธิ์, การตรวจสอบการทำงาน, การกำหนดเส้นทาง ฯลฯ และความจริงที่ว่าปลั๊กอินใน APISIX สามารถรีโหลดได้ทันที (ไม่ต้องรีสตาร์ท) ทำให้มันมีความยืดหยุ่นสูง
แต่ขณะใช้งาน APISIX อาจมีสถานการณ์ที่คุณต้องการเพิ่มตรรกะการอนุญาตที่ซับซ้อนในแอปพลิเคชันของคุณ นี่คือที่ที่ authz-casbin อาจช่วยคุณได้, authz-casbin เป็นปลั๊กอินของ APISIX ที่พัฒนาบน Lua Casbin ที่ช่วยให้สามารถอนุญาตได้อย่างมีประสิทธิภาพตามโมเดลการควบคุมการเข้าถึงต่างๆ Casbin เป็นไลบรารีการอนุญาตที่รองรับโมเดลการควบคุมการเข้าถึงเช่น ACL, RBAC, ABAC เขียนขึ้นเดิมในภาษา Go และได้ถูกพอร์ตไปยังภาษาอื่นๆ และ Lua Casbin เป็นการนำไปใช้ของ Casbin ในภาษา Lua การพัฒนา authz-casbin เริ่มต้นเมื่อเราเสนอปลั๊กอินใหม่สำหรับการอนุญาตในที่เก็บข้อมูล APISIX (#4674) ซึ่งสมาชิกหลักตกลง และหลังจากการทบทวนที่มีประโยชน์ซึ่งนำไปสู่การเปลี่ยนแปลงและการปรับปรุงที่สำคัญ คำขอ PR (#4710) ก็ถูกผสานเข้าไปในที่สุด
ในบล็อกนี้ เราจะใช้ปลั๊กอิน authz-casbin เพื่อแสดงวิธีการที่คุณสามารถนำไปใช้โมเดลการอนุญาตตาม Role Based Access Control (RBAC) ใน APISIX
หมายเหตุ: คุณจะต้องใช้ปลั๊กอินอื่นหรือกระบวนการทำงานที่กำหนดเองสำหรับการตรวจสอบสิทธิ์ผู้ใช้ เนื่องจาก Casbin จะทำเพียงการอนุญาตและไม่ใช่การตรวจสอบสิทธิ์
การสร้างโมเดล
ปลั๊กอินใช้สามพารามิเตอร์ในการอนุญาตคำขอใดๆ - หัวข้อ, วัตถุ และการกระทำ ที่นี่ หัวข้อคือค่าของหัวข้อ username ซึ่งอาจเป็นอะไรก็ได้เช่น [username: alice]
จากนั้น วัตถุคือเส้นทาง URL ที่กำลังถูกเข้าถึง และการกระทำคือวิธีการขอที่กำลังถูกใช้
สมมติว่าเราต้องการสร้างโมเดลที่มีทรัพยากรสามอย่างที่เส้นทาง - /
, /res1
และ /res2
และเราต้องการมีโมเดลเช่นนี้:
นี่จะหมายความว่าผู้ใช้ทุกคน (*
) เช่น jack
สามารถเข้าถึงหน้าแรก (/
) และผู้ใช้ที่มีสิทธิ์ admin
เช่น alice
และ bob
สามารถเข้าถึงทุกหน้าและทรัพยากร (เช่น res1
และ res2
) นอกจากนี้ มาจำกัดผู้ใช้ที่ไม่มีสิทธิ์ admin ให้ใช้เฉพาะวิธีการขอ GET
สำหรับสถานการณ์นี้ เราสามารถกำหนดโมเดลได้เป็น:
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[role_definition]
g = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = (g(r.sub, p.sub) || keyMatch(r.sub, p.sub)) && keyMatch(r.obj, p.obj) && keyMatch(r.act, p.act)
การสร้างนโยบาย
จากสถานการณ์ข้างต้น นโยบายจะเป็น:
p, *, /, GET
p, admin, *, *
g, alice, admin
g, bob, admin
ตัวจับคู่จากโมเดลหมายถึง:
(g(r.sub, p.sub) || keyMatch(r.sub, p.sub))
: หัวข้อของคำขอมีบทบาทเหมือนกับหัวข้อของนโยบาย หรือหัวข้อของคำขอตรงกับหัวข้อของนโยบายในkeyMatch
keyMatch
เป็นฟังก์ชันที่มีอยู่ใน Lua Casbin คุณสามารถดูคำอธิบายของฟังก์ชันและฟังก์ชันอื่นๆ ที่อาจมีประโยชน์ ที่นี่keyMatch(r.obj, p.obj)
: วัตถุของคำขอตรงกับวัตถุของนโยบาย (เส้นทาง URL ที่นี่)keyMatch(r.act, p.act)
: การกระทำของคำขอตรงกับการกระทำของนโยบาย (วิธีการขอ HTTP ที่นี่)
การเปิดใช้งานปลั๊กอินบนเส้นทาง
เมื่อคุณได้สร้างโมเดลและนโยบายแล้ว คุณสามารถเปิดใช้งานได้บนเส้นทางโดยใช้ APISIX Admin API เพื่อเปิดใช้งานโดยใช้เส้นทางไฟล์โมเดลและนโยบาย:
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"plugins": {
"authz-casbin": {
"model_path": "/path/to/model.conf",
"policy_path": "/path/to/policy.csv",
"username": "username"
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/*"
}'
ที่นี่ ฟิลด์ username เป็นชื่อหัวข้อที่คุณจะใช้ในการส่งหัวข้อ ตัวอย่างเช่น ถ้าคุณจะส่งหัวข้อ username เป็น user: alice
คุณจะใช้ "username": "user"
สำหรับการใช้ข้อความโมเดล/นโยบายแทนไฟล์ คุณสามารถใช้ฟิลด์ model
และ policy
แทน:
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"plugins": {
"authz-casbin": {
"model": "[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[role_definition]
g = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = (g(r.sub, p.sub) || keyMatch(r.sub, p.sub)) && keyMatch(r.obj, p.obj) && keyMatch(r.act, p.act)",
"policy": "p, *, /, GET
p, admin, *, *
g, alice, admin
g, bob, admin",
"username": "username"
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/*"
}'
การเปิดใช้งานปลั๊กอินโดยใช้โมเดล/นโยบายสากล
อาจมีสถานการณ์ที่คุณต้องการใช้โมเดลและนโยบายเดียวกันในหลายเส้นทาง คุณสามารถทำได้โดยการส่งคำขอ PUT
เพื่อเพิ่มการกำหนดค่าโมเดลและนโยบายไปยังข้อมูลเมตาของปลั๊กอินโดย:
curl http://127.0.0.1:9080/apisix/admin/plugin_metadata/authz-casbin -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -i -X PUT -d '
{
"model": "[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[role_definition]
g = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = (g(r.sub, p.sub) || keyMatch(r.sub, p.sub)) && keyMatch(r.obj, p.obj) && keyMatch(r.act, p.act)",
"policy": "p, *, /, GET
p, admin, *, *
g, alice, admin
g, bob, admin"
}'
และจากนั้นเพื่อเปิดใช้งานการกำหนดค่าเดียวกันบนเส้นทางใดๆ ส่งคำขอโดยใช้ Admin API:
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"plugins": {
"authz-casbin": {
"username": "username"
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/route1/*"
}'
นี่จะเพิ่มการกำหนดค่าข้อมูลเมตาของปลั๊กอินไปยังเส้นทาง คุณยังสามารถอัปเดตการกำหนดค่าข้อมูลเมตาของปลั๊กอินได้อย่างง่ายดายโดยการส่งคำขอใหม่ไปยังข้อมูลเมตาของปลั๊กอินด้วยการกำหนดค่าโมเดลและนโยบายที่อัปเดต ปลั๊กอินจะอัปเดตเส้นทางทั้งหมดที่ใช้การกำหนดค่าข้อมูลเมตาโดยอัตโนมัติ
กรณีการใช้งาน
- กรณีการใช้งานหลักของปลั๊กอินนี้คือการดำเนินการอนุญาตใน API ของคุณ คุณสามารถเพิ่มปลั๊กอินนี้ได้อย่างง่ายดายในเส้นทาง API ใดๆ ที่คุณใช้กับโมเดลการอนุญาตและการกำหนดค่านโยบายของคุณ
- ถ้าคุณต้องการมีโมเดลการอนุญาตเดียวสำหรับ API ทั้งหมดของคุณ คุณสามารถใช้วิธีโมเดล/นโยบายสากล นี่ทำให้การอัปเดตนโยบายง่ายสำหรับทุกเส้นทาง เนื่องจากคุณเพียงแค่ต้องอัปเดตข้อมูลเมตาใน etcd
- ในขณะที่ถ้าคุณต้องการใช้โมเดลที่แตกต่างกันสำหรับทุกเส้นทางที่แตกต่างกัน คุณสามารถใช้วิธีเส้นทาง สิ่งนี้มีประโยชน์เมื่อเส้นทาง API ที่แตกต่างกันมีชุดสิทธิ์ผู้ใช้ที่แตกต่างกัน คุณยังสามารถใช้สิ่งนี้เมื่อคุณกำลังจัดการกับนโยบายขนาดใหญ่ เนื่องจากจะทำให้การอนุญาตเร็วขึ้นเมื่อกรองเข้าสู่เส้นทางหลายเส้นทาง