Para garantizar la seguridad de las aplicaciones, utilizamos mecanismos como la autenticación y la autorización. Creo que muchos de ustedes están familiarizados con estos conceptos y en este artículo nos centraremos en el concepto de autorización y modelos de control de acceso relacionados.
Definiciones de términos utilizados en este artículo
Es importante comprender las diferencias entre autorización y autenticación:
– , ( , ).
– , .
– , .
– , , .
(Crate) – Rust.
El proceso de autorización incluye el concepto de una política de control de acceso , según el cual se determina un conjunto de acciones permisibles de un usuario específico ( sujeto de acceso ) sobre los recursos del sistema ( objeto de acceso ).
Y también el modelo de control de acceso : un esquema general para delimitar el acceso a través de una política de usuario, que elegimos en función de varios factores y requisitos del sistema.
Echemos un vistazo a los modelos básicos de control de acceso:
DAC ( control de acceso discrecional ) - control de acceso selectivo (discrecional)
- , (ACL).
, .
, .
MAC (Mandatory access-control) –
(, ), .
( ), . .
, MAC , ( , ).
RBAC (Role-Based access-control) –
, - . DAC, .
, .
, RBAC PBAC (Permission-Based access-control) , (: READ_DOCUMENT
, WRITE_DOCUMENT
, DELETE_DOCUMENT
) , – .
ABAC (Attribute-Based access-control) –
, , .
, , , , .., .
ABAC , ( ) ( ).
OWASP (Open Web Application Security Project) IBM.
, , .
- Rust?
, - (, actix-web, Rocket tide), Middleware, FromRequest Guard (Filter warp).
, . , .
, . , , .
casbin-rs
Casbin – production-ready , , ( ACL, RBAC, ABAC) .
casbin - PERM (Policy, Effect, Request, Matchers) , , .
# Request definition
[request_definition]
r = sub, obj, act
# Policy definition
[policy_definition]
p = sub, obj, act
# Policy effect
[policy_effect]
e = some(where (p.eft == allow))
# Matchers
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
, -
( ), PERM .
p, alice, data1, read p, bob, data2, write
, .
use casbin::prelude::*;
#[tokio::main]
async fn main() -> () {
let mut e = Enforcer::new("examples/acl_model.conf", "examples/acl_policy.csv").await?;
e.enable_log(true);
let sub = "alice"; // the user that wants to access a resource.
let obj = "data1"; // the resource that is going to be accessed.
let act = "read"; // the operation that the user performs on the resource.
if let Ok(authorized) = e.enforce((sub, obj, act)) {
if authorized {
// permit alice to read data1
} else {
// deny the request
}
} else {
// error occurs
}
}
. , !
, , , , , , , .
, backend Rust. PBAC -, ACL/RBAC.
actix-web-grants
, , , : (ACL), (RBAC/PBAC).
, :
// Sample application with grant protection based on extracting by your custom function
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
let auth = GrantsMiddleware::with_extractor(extract);
App::new()
.wrap(auth)
.service(index)
})
.bind("localhost:8081")?
.run()
.await
}
async fn extract(_req: &ServiceRequest) -> Result<Vec<String>, Error> {
// Here is a place for your code to get user permissions/grants/permissions from a request
// For example from a token or database
// Stub example
Ok(vec![ROLE_ADMIN.to_string()])
}
: JWT-, , .
:
use actix_web_grants::proc_macro::{has_roles};
#[get("/secure")]
#[has_roles("ROLE_ADMIN")]
async fn macro_secured() -> HttpResponse {
HttpResponse::Ok().body("ADMIN_RESPONSE")
}
actix-web-grants, .
, ( wrk) .
RBAC - : , . . GitHub: actix-web-authz-benchmark ( ).
:
|
casbin-rs |
actix-web-grants |
||
Latency |
Req/Sec |
Latency |
Req/Sec |
|
Allowed Endpoint |
6.18 ms |
16.27k |
4.41 ms |
22.69k |
Denied Endpoint |
6.70 ms |
14.98k |
4.94 ms |
20.23k |
rustc: v1.52.0 (stable); CPU: 2,6 GHz 6-Core Intel Core i7; RAM: 16 GB
, , actix-web-grants (endpoints), casbin-rs.
Post Scriptum
Esta biblioteca aún no tiene integraciones con muchos marcos web en su arsenal, pero tengo planes de introducir algunas abstracciones y escribir módulos para otros marcos, hacer algunas mejoras (por ejemplo, la capacidad de heredar roles y admitir tipos personalizados). ¡Cualquier sugerencia y contribución será bienvenida!