Ana içeriğe atla

APISIX'te Casbin kullanarak yetkilendirme

· 5 dakika okuma
Rushikesh Tote

Giriş

APISIX, Nginx ve etcd üzerine kurulu yüksek performanslı ve ölçeklenebilir bir bulut yerel API ağ geçididir. Apache Yazılım Vakfı tarafından yürütülen açık kaynaklı bir projedir. APISIX'in bu kadar iyi olmasının yanı sıra, kimlik doğrulama, izleme, yönlendirme gibi özellikleri uygulamak için kullanılabilecek birçok harika yerleşik eklenti desteği bulunmaktadır. APISIX'teki eklentilerin yeniden başlatmalar olmadan sıcak yüklenebilmesi, onu çok dinamik kılmaktadır.

Ancak APISIX kullanırken, uygulamanızda karmaşık yetkilendirme mantığı eklemek isteyebileceğiniz senaryolar olabilir. İşte burada authz-casbin size yardımcı olabilir, authz-casbin, çeşitli erişim kontrol modellerine dayalı güçlü yetkilendirme sağlayan Lua Casbin tabanlı bir APISIX eklentisidir. Casbin, ACL, RBAC, ABAC gibi erişim kontrol modellerini destekleyen bir yetkilendirme kütüphanesidir. Başlangıçta Go dilinde yazılmış olan Casbin, birçok dilde port edilmiştir ve Lua Casbin, Casbin'in Lua uygulamasıdır. authz-casbin'in geliştirilmesi, APISIX deposunda yetkilendirme için yeni bir eklenti önerdiğimizde (#4674) çekirdek üyelerin de onay vermesiyle başladı. Ve yararlı incelemeler sonucu bazı önemli değişiklikler ve iyileştirmeler yapıldıktan sonra, PR (#4710) nihayet birleştirildi.

Bu blogda, authz-casbin eklentisini kullanarak APISIX'te Rol Tabanlı Erişim Kontrolü (RBAC) temelli bir yetkilendirme modelinin nasıl uygulanabileceğini göstereceğiz.

NOT: Casbin sadece yetkilendirme yapacağı için kullanıcının kimlik doğrulaması için başka bir eklenti veya özel bir iş akışı kullanmanız gerekecektir.

Model Oluşturma

Eklenti, herhangi bir isteği yetkilendirmek için üç parametre kullanır - konu, nesne ve eylem. Burada, konu, kullanıcı adı başlığının değeridir ve [username: alice] gibi bir şey olabilir. Ardından, nesne erişilmekte olan URL yolu ve eylem kullanılan istek yöntemidir.

Diyelim ki /, /res1 ve /res2 yollarında üç kaynakla bir model oluşturmak istiyoruz. Ve şöyle bir model istiyoruz:

resim

Bu, örneğin jack gibi tüm kullanıcıların (*) anasayfasına (/) erişebileceği anlamına gelir. Ve alice ve bob gibi admin izinlerine sahip kullanıcılar tüm sayfalara ve kaynaklara (örneğin res1 ve res2) erişebilir. Ayrıca, admin izni olmayan kullanıcıların sadece GET istek yöntemini kullanmasını kısıtlayalım. Bu senaryo için modeli şu şekilde tanımlayabiliriz:

[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)

Politika oluşturma

Yukarıdaki senaryodan, politika şu şekilde olacaktır:

p, *, /, GET
p, admin, *, *
g, alice, admin
g, bob, admin

Modelden gelen eşleştirici şu anlama gelir:

  1. (g(r.sub, p.sub) || keyMatch(r.sub, p.sub)): İsteğin konusu, politikanın konusu olarak bir rolü taşıyor ya da isteğin konusu, keyMatch içinde politikanın konusuyla eşleşiyor. keyMatch, Lua Casbin'de yerleşik bir fonksiyondur, fonksiyonun açıklamasına ve daha faydalı olabilecek diğer fonksiyonlara buradan göz atabilirsiniz.
  2. keyMatch(r.obj, p.obj): İsteğin nesnesi, politikanın nesnesiyle eşleşiyor (burada URL yolu).
  3. keyMatch(r.act, p.act): İsteğin eylemi, politikanın eylemiyle eşleşiyor (burada HTTP istek metodu).

Eklentiyi rotada etkinleştirme

Modeli ve politikayı oluşturduktan sonra, APISIX Admin API'sini kullanarak bunu bir rotada etkinleştirebilirsiniz. Model ve politika dosyası yollarını kullanarak etkinleştirmek için:

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": "/*"
}'

Burada, kullanıcı adı alanı, konuyu ileteceğiniz başlık adıdır. Örneğin, kullanıcı adı başlığını user: alice olarak iletecekseniz, "username": "user" kullanırsınız.

Dosyalar yerine model/politika metni kullanmak için, model ve policy alanlarını kullanabilirsiniz:

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": "/*"
}'

Eklentiyi global bir model/politika kullanarak etkinleştirme

Birden fazla rotada tek bir model ve politika yapılandırması kullanmak isteyebileceğiniz durumlar olabilir. Bunu, öncelikle model ve politika yapılandırmasını eklentinin meta verilerine eklemek için bir PUT isteği göndererek yapabilirsiniz:

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"
}'

Ve sonra aynı yapılandırmayı bazı rotalarda etkinleştirmek için, Admin API'sini kullanarak bir istek gönderin:

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/*"
}'

Bu, eklenti meta veri yapılandırmasını rotaya ekleyecektir. Eklenti meta veri yapılandırmasını, güncellenmiş model ve politika yapılandırması ile isteği yeniden göndererek kolayca güncelleyebilirsiniz, eklenti otomatik olarak eklenti meta verisini kullanan tüm rotaları güncelleyecektir.

Kullanım Senaryoları

  • Bu eklentinin birincil kullanım senaryosu, API'lerinizde yetkilendirmeyi uygulamak olacaktır. Bu eklentiyi, yetkilendirme modeliniz ve politika yapılandırmanızla kullanmakta olduğunuz herhangi bir API rotasına kolayca ekleyebilirsiniz.
  • Tüm API'leriniz için tek bir yetkilendirme modeline sahip olmak istiyorsanız, global model/politika yöntemini kullanabilirsiniz. Bu, politika güncellemesini tüm rotalar için kolaylaştırır, çünkü sadece etcd'deki meta verileri güncellemeniz yeterlidir.
  • Eğer her farklı rotaya farklı bir model kullanmak istiyorsanız, rota yöntemini kullanabilirsiniz. Bu, farklı API rotalarının farklı kullanıcı izinlerine sahip olduğunda yardımcı olur. Ayrıca, daha büyük politikalarla uğraşırken bunu kullanabilirsiniz, çünkü bu, yetkilendirmeyi birden çok rota filtrelendiğinde daha hızlı yapacaktır.