RomainMichau / ActixWeb_openIDConnect

Lightweight async OpenID Connect (OIDC) client and middleware for Actix-Web.
5 stars 2 forks source link

Authorization error doesn't send CORS headers along with response #5

Open OfficialVreesie opened 2 months ago

OfficialVreesie commented 2 months ago

When using the OIDC middleware, I don't get the configured Actix CORS headers in my frontend when the redirect_to_auth() method is called. This is causing CORS policy issues, since I am both running rust and the frontend application on localhost.

Here is how I configured my CORS:

async fn start_server(settings: Arc<Settings>, app_state: Data<AppState>) -> std::io::Result<()> {
    let should_auth = |req: &ServiceRequest| {
        let path = req.path();
        !path.starts_with("/api/oidc/login")
            && !path.starts_with("/api/oidc/token")
            && !path.starts_with("/api/oidc/logout")
            && req.method() != actix_web::http::Method::OPTIONS
    };

    let openid = ActixWebOpenId::init(
        settings.oidc.clientid.clone(),
        settings.oidc.clientsecret.clone(),
        format!(
            "http://{}:{}/oidc/callback",
            settings.frontend.host, settings.frontend.port
        ),
        settings.oidc.issuer.clone(),
        should_auth,
        Some("http://localhost:9292/login".to_string()),
        vec!["openid".to_string(), "groups".to_string()],
    )
    .await;

    HttpServer::new(move || {
        let cors = Cors::default()
            .allowed_origin("http://localhost:9292")
            .allowed_origin("http://127.0.0.1:9292")
            .allowed_methods(vec!["GET", "POST", "DELETE", "PUT", "OPTIONS"])
            .allowed_headers(vec![
                header::AUTHORIZATION,
                header::ACCEPT,
                header::CONTENT_TYPE,
                header::ORIGIN,
            ])
            .max_age(3600)
            .supports_credentials()
            .send_wildcard();

        App::new()
            .wrap(
                SessionMiddleware::builder(
                    CookieSessionStore::default(),
                    cookie::Key::from(get_decoded_cookie_key(&app_state).as_slice()),
                )
                .cookie_secure(false)
                .build(),
            )
            .wrap(Logger::default())
            .wrap(cors) // <---- This is my CORS header, placed before the middleware so that the headers can be set
            .wrap(openid.get_middleware()) // <---- Apply the OpenID Connect middleware
            .configure(openid.configure_open_id())
            .app_data(app_state.clone())
            .service(
                web::scope("/api")
                    .route("/oidc/login", web::get().to(oidc_login))
                    .route("/oidc/token", web::post().to(oidc_token))
                    .route("/oidc/token", web::post().to(oidc_logout))
            )
    })
    .bind("0.0.0.0:9191")?
    .run()
    .await
}

Can you make sure that these headers can remain, when returning unauthorized errors?

DMoscicki commented 1 month ago

@OfficialVreesie did you try Cors::permissive() ?? its not recommended to use in production