Pengenalan
APISIX ialah gerbang API berasaskan awan yang berkelajuan tinggi dan boleh diubah suai yang berdasarkan Nginx dan etcd. Ia adalah projek sumber terbuka oleh Yayasan Perisian Apache. Selain itu, apa yang menjadikan APISIX begitu baik ialah sokongan untuk banyak plugin terbina dalam yang hebat yang boleh digunakan untuk melaksanakan ciri-ciri seperti pengesahan, pemantauan, perutean, dsb. Dan hakikat bahawa plugin dalam APISIX dimuat semula secara panas (tanpa mula semula) menjadikannya sangat dinamik.
Tetapi semasa menggunakan APISIX, mungkin terdapat senario di mana anda mungkin ingin menambah logik kebenaran kompleks dalam aplikasi anda. Inilah di mana authz-casbin mungkin boleh membantu anda, authz-casbin adalah plugin APISIX yang berdasarkan Lua Casbin yang membolehkan penggunaan kuasa penggunaan berdasarkan pelbagai model kawalan akses. Casbin adalah perpustakaan penggunaan yang menyokong model kawalan akses seperti ACL, RBAC, ABAC. Asalnya ditulis dalam Go, ia telah dipindahkan ke banyak bahasa dan Lua Casbin adalah pelaksanaan Lua bagi Casbin. Pembangunan authz-casbin bermula apabila kami mencadangkan plugin baru untuk penggunaan dalam repositori APISIX (#4674) yang mana ahli teras bersetuju. Dan selepas ulasan yang membantu yang menyebabkan beberapa perubahan dan penambahbaikan utama, PR (#4710) akhirnya digabungkan.
Dalam blog ini, kami akan menggunakan plugin authz-casbin untuk menunjukkan bagaimana anda boleh melaksanakan model penggunaan berdasarkan Kawalan Akses Berdasarkan Peranan (RBAC) dalam APISIX.
PERHATIAN: Anda perlu menggunakan beberapa plugin lain atau alur kerja tersuai untuk mengesahkan pengguna kerana Casbin hanya akan melakukan penggunaan dan bukan pengesahan.
Membuat model
Plugin ini menggunakan tiga parameter untuk membenarkan sebarang permintaan - subjek, objek dan tindakan. Di sini, subjek adalah nilai tajuk nama pengguna, yang boleh menjadi seperti [username: alice]
. Kemudian, objek tersebut adalah laluan URL yang diakses dan tindakan adalah kaedah permintaan yang digunakan.
Katakan kita ingin membuat model dengan tiga sumber pada laluan - /`\`,
/res1\
dan `/res2
`. Dan kita ingin mempunyai model seperti ini:
Ini bermakna semua pengguna (*`\`) seperti contohnya
jack\
boleh mengakses laman utama (/`\`). Dan pengguna dengan kebenaran
admin\
seperti alice`\` dan
bob\
boleh mengakses semua halaman dan sumber (seperti res1`\` dan
res2\
). Juga, mari kita hadkan pengguna tanpa sebarang kebenaran admin untuk menggunakan hanya kaedah permintaan `GET
`. Untuk senario ini, kita boleh menentukan model sebagai:
[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)
Membuat polisi
Dari senario di atas, polisi tersebut akan menjadi:
p, *, /, GET
p, admin, *, *
g, alice, admin
g, bob, admin
Pencocok dari model bermakna:
(g(r.sub, p.sub) || keyMatch(r.sub, p.sub))
: Sama ada subjek permintaan mempunyai peranan sebagai subjek polisi atau subjek permintaan sepadan dengan subjek polisi dalamkeyMatch
.keyMatch
adalah fungsi terbina dalam Lua Casbin, anda boleh melihat penerangan fungsi dan lebih banyak fungsi yang boleh berguna di sini.keyMatch(r.obj, p.obj)
: Objek permintaan sepadan dengan objek polisi (laluan URL di sini).keyMatch(r.act, p.act)
: Tindakan permintaan sepadan dengan tindakan polisi (kaedah permintaan HTTP di sini).
Mengaktifkan plugin pada laluan
Setelah anda mencipta model dan polisi, anda boleh mengaktifkannya pada laluan menggunakan APISIX Admin API. Untuk mengaktifkannya menggunakan laluan fail model dan polisi:
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": "/*"
}'
Di sini, medan nama pengguna adalah nama header yang akan anda gunakan untuk menyampaikan subjek. Sebagai contoh, jika anda akan menyampaikan header nama pengguna sebagai user: alice
, anda akan menggunakan "username": "user"
.
Untuk menggunakan teks model/polisi dan bukannya fail, anda boleh menggunakan medan model
dan policy
sebagai gantinya:
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": "/*"
}'
Mengaktifkan plugin menggunakan model/polisi global
Mungkin terdapat situasi di mana anda mungkin ingin menggunakan konfigurasi model dan polisi tunggal merentasi pelbagai laluan. Anda boleh melakukannya dengan terlebih dahulu menghantar permintaan PUT
untuk menambah konfigurasi model dan polisi ke metadata plugin dengan:
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"
}'
Kemudian, untuk mengaktifkan konfigurasi yang sama pada beberapa rute, hantar permintaan menggunakan 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/*"
}'
Ini akan menambah konfigurasi metadata plugin ke rute tersebut. Anda juga boleh mengemas kini konfigurasi metadata plugin dengan mudah dengan menghantar semula permintaan ke metadata plugin dengan konfigurasi model dan polisi yang dikemas kini, plugin akan mengemas kini semua rute yang menggunakan metadata plugin secara automatik.
Kes Penggunaan
- Kes penggunaan utama plugin ini adalah dalam melaksanakan kebenaran dalam API anda. Anda boleh menambah plugin ini dengan mudah pada mana-mana rute API yang anda gunakan dengan konfigurasi model dan polisi kebenaran anda.
- Jika anda ingin mempunyai model kebenaran tunggal untuk semua API anda, anda boleh menggunakan kaedah model/polisi global. Ini memudahkan pengemaskinian polisi untuk semua rute, kerana anda hanya perlu mengemas kini metadata dalam etcd.
- Manakala jika anda ingin menggunakan model yang berbeza untuk setiap rute yang berbeza, anda boleh menggunakan kaedah rute. Ini berguna apabila laluan API yang berbeza mempunyai set kebenaran pengguna yang berbeza. Anda juga boleh menggunakan ini apabila anda menangani dasar yang lebih besar, kerana ia akan mempercepatkan pengesahan apabila disaring ke dalam pelbagai laluan.