项目作者: casbin-rs

项目描述 :
Casbin Actix-web access control middleware
高级语言: Rust
项目地址: git://github.com/casbin-rs/actix-casbin-auth.git
创建时间: 2020-04-08T08:56:51Z
项目社区:https://github.com/casbin-rs/actix-casbin-auth

开源协议:

下载


Actix Casbin Middleware

Crates.io
Docs
CI
codecov

Casbin access control middleware for actix-web framework

Install

Add dependencies

  1. cargo add actix-rt
  2. cargo add actix-web
  3. cargo add actix-casbin --no-default-features --features runtime-async-std
  4. cargo add actix-casbin-auth --no-default-features --features runtime-async-std

Requirement

Casbin only takes charge of permission control, so you need to implement an Authentication Middleware to identify user.

You should put actix_casbin_auth::CasbinVals which contains subject(username) and domain(optional) into Extension.

For example:

  1. use std::cell::RefCell;
  2. use std::pin::Pin;
  3. use std::rc::Rc;
  4. use std::task::{Context, Poll};
  5. use actix_service::{Service, Transform};
  6. use actix_web::{dev::ServiceRequest, dev::ServiceResponse, Error, HttpMessage};
  7. use futures::future::{ok, Future, Ready};
  8. use actix_casbin_auth::CasbinVals;
  9. pub struct FakeAuth;
  10. impl<S: 'static, B> Transform<S> for FakeAuth
  11. where
  12. S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
  13. S::Future: 'static,
  14. B: 'static,
  15. {
  16. type Response = ServiceResponse<B>;
  17. type Error = Error;
  18. type InitError = ();
  19. type Transform = FakeAuthMiddleware<S>;
  20. type Future = Ready<Result<Self::Transform, Self::InitError>>;
  21. fn new_transform(&self, service: S) -> Self::Future {
  22. ok(FakeAuthMiddleware {
  23. service: Rc::new(RefCell::new(service)),
  24. })
  25. }
  26. }
  27. pub struct FakeAuthMiddleware<S> {
  28. service: Rc<RefCell<S>>,
  29. }
  30. impl<S, B> Service for FakeAuthMiddleware<S>
  31. where
  32. S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
  33. S::Future: 'static,
  34. B: 'static,
  35. {
  36. type Response = ServiceResponse<B>;
  37. type Error = Error;
  38. type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;
  39. fn poll_ready(&mut self, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
  40. self.service.poll_ready(cx)
  41. }
  42. fn call(&mut self, req: ServiceRequest) -> Self::Future {
  43. let mut svc = self.service.clone();
  44. Box::pin(async move {
  45. let vals = CasbinVals {
  46. subject: String::from("alice"),
  47. domain: None,
  48. };
  49. req.extensions_mut().insert(vals);
  50. svc.call(req).await
  51. })
  52. }
  53. }
  54. `

Example

  1. use actix_casbin_auth::casbin::{DefaultModel, FileAdapter, Result};
  2. use actix_casbin_auth::CasbinService;
  3. use actix_web::{web, App, HttpResponse, HttpServer};
  4. use actix_casbin_auth::casbin::function_map::key_match2;
  5. #[allow(dead_code)]
  6. mod fake_auth;
  7. #[actix_rt::main]
  8. async fn main() -> Result<()> {
  9. let m = DefaultModel::from_file("examples/rbac_with_pattern_model.conf")
  10. .await
  11. .unwrap();
  12. let a = FileAdapter::new("examples/rbac_with_pattern_policy.csv"); //You can also use diesel-adapter or sqlx-adapter
  13. let casbin_middleware = CasbinService::new(m, a).await?;
  14. casbin_middleware
  15. .write()
  16. .await
  17. .get_role_manager()
  18. .write()
  19. .unwrap()
  20. .matching_fn(Some(key_match2), None);
  21. HttpServer::new(move || {
  22. App::new()
  23. .wrap(casbin_middleware.clone())
  24. .wrap(FakeAuth)
  25. .route("/pen/1", web::get().to(|| HttpResponse::Ok()))
  26. .route("/book/{id}", web::get().to(|| HttpResponse::Ok()))
  27. })
  28. .bind("127.0.0.1:8080")?
  29. .run()
  30. .await?;
  31. Ok(())
  32. }

License

This project is licensed under