web-dev-qa-db-ja.com

ACTIX-WEBで保護されたルートを作成する方法

ユーザーがいくつかのルートの許可を持っているかどうかを確認する必要があります。私は3つの "Scopes"を作成しました(guest、auth-user、admin)、今度はこれらのルートにアクセスするかどうかを確認する方法はわかりません。

Auth Middlewareを実装しようとしています。このミドルウェアは、ユーザーに正しいCookieまたはTokenがあるかどうかを確認する必要があります。 (リクエストヘッダーからCookieを印刷することができます)、iインポート方法、actix_identityを使用し、このミドルウェア内のIDパラメータにアクセスする方法はありません。

私の問題はActix-Identityに関してだけではなく、ミドルウェアの中にパラメータを渡すことができません。

#[actix_rt::main]
async fn main() -> std::io::Result<()> {

    let cookie_key = conf.server.key;

    // Register http routes
    let mut server = HttpServer::new(move || {
        App::new()
            // Enable logger
            .wrap(Logger::default())
            .wrap(IdentityService::new(
                CookieIdentityPolicy::new(cookie_key.as_bytes())
                    .name("auth-cookie")
                    .path("/")
                    .secure(false),
            ))
            //limit the maximum amount of data that server will accept
            .data(web::JsonConfig::default().limit(4096))
            //normal routes
            .service(web::resource("/").route(web::get().to(status)))
            // .configure(routes)
            .service(
                web::scope("/api")
                    // guest endpoints
                    .service(web::resource("/user_login").route(web::post().to(login)))
                    .service(web::resource("/user_logout").route(web::post().to(logout)))
                    // admin endpoints
                    .service(
                        web::scope("/admin")
                            // .wrap(AdminAuthMiddleware)
                            .service(
                                web::resource("/create_admin").route(web::post().to(create_admin)),
                            )
                            .service(
                                web::resource("/delete_admin/{username}/{_:/?}")
                                    .route(web::delete().to(delete_admin)),
                            ),
                    )
                    //user auth routes
                    .service(
                        web::scope("/auth")
                            // .wrap(UserAuthMiddleware)
                            .service(web::resource("/get_user").route(web::get().to(get_user))),
                    ),
            )
    });

    // Enables us to hot reload the server
    let mut listenfd = ListenFd::from_env();
    server = if let Some(l) = listenfd.take_tcp_listener(0).unwrap() {
        server.listen(l)?
    } else {
        server.bind(ip)?
    };

    server.run().await
 _

私が試したリソース:

  1. ACTIX APIの認証ミドルウェアを作成する https://www.jamesbaum.co.uk/blether/creating-authentication-middleware-actix-rust-react/

  2. ミドルウェアでのACTIX-WEBトークン検証 https://users.rust-lang.org/t/actix-web-token-validation-in-middleware/38205

  3. Actixミドルウェアの例 https://github.com/actix/examples/tree/master/middleware

多分私は完全に間違っていると思います、そしてAuth-Middlewareは私の問題の最善の解決策ではありません。私が「保護されたルート」を作成するのを手伝うことができることを願っています

7
Karol

私は Actix-Web Argants クレートはあなたに最適です。 Guard、または手続き型マクロを使用して承認を確認できます( github の例)。また、既存の承認ミドルウェアとも正しく統合されています(actix-web-httpauthなど)。

わかりやすくするための例のカップル:

  • proc-macro Way.
#[get("/secure")]
#[has_permissions("ROLE_ADMIN")]
async fn macro_secured() -> HttpResponse {
    HttpResponse::Ok().body("ADMIN_RESPONSE")
}
  • Guardウェイ
App::new()
    .wrap(GrantsMiddleware::with_extractor(extract))
    .service(web::resource("/admin")
            .to(|| async { HttpResponse::Ok().finish() })
            .guard(PermissionGuard::new("ROLE_ADMIN".to_string())))

そしてあなたはまた Actix-Casbin-auth (ACTIXに統合されたCasbinの実装)を見ることもできます。

1
DDtKey

まあこれは実際には最新のActix-Webバージョン3.0で達成するのは非常に困難です。私がしたことは、CookieIdentityPolicyミドルウェアを actix-web 1. バージョンからコピーし、それを私の好みに変更しました。ただし、これはプラグと再生コードではありません。 こちらここ それの私のバージョンです。一般的に私はActix-Webを避け、バックグラウンドでスパウンするためにスレッド/アクターを起こし、それがhttp要求を実行することは悪夢です。その後、結果をハンドラーでさらにそれ以上共有しようとしています。

1
Qubasa

代わりに抽出器を試してください

Actix 3でこのパターンを実装しようとしているミドルウェアを使用しようとして、基本的にはガードを作ってからミドルウェアからハンドラにデータを渡す方法を考え出しました。それは痛みを伴うかつ最終的に私はそれではなくActixに対して働いていたことに気づきました。

最後に、ハンドラへの情報を取得する方法は、構造体(AuthedUser、おそらく?)を作成し、その構造体上のFromRequest形質を実装することを学びました。

次に、関数シグネチャのAuthedUserを要求するすべてのハンドラはauthゲートされ、ユーザーがログインしている場合はAuthedUserのユーザー情報がFromRequest::from_request 方法。

ACTIXは、FromRequest _を実装するこれらの構造体を指しますextractors。ガイドにもっと注意を払うことができるのは少し魔法です。

1
Doug Bradshaw