Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rapidoc OAuth redirect URL doesn't work #886

Open
aminya opened this issue Mar 17, 2024 · 1 comment
Open

Rapidoc OAuth redirect URL doesn't work #886

aminya opened this issue Mar 17, 2024 · 1 comment

Comments

@aminya
Copy link

aminya commented Mar 17, 2024

I am trying to integrate Auth0 into Rapidoc. I have added the following OAuth2 implementations, but none of them work. The issue is that Auth0 redirects back to oauth-receiver.html with the access token information, but this file doesn't exist. I tried to create this manually and serve it using actix_files, but it doesn't seem to fix the issue.

Could be related to rapi-doc/RapiDoc#777

use utoipa::{
  openapi::{
    security::{
      AuthorizationCode, ClientCredentials, Flow, HttpAuthScheme, HttpBuilder, Implicit, OAuth2,
      Scopes, SecurityScheme,
    },
    Components,
  },
  Modify, OpenApi,
};

#[derive(OpenApi)]
#[openapi(
        paths(
			...
        ),
        modifiers(&SecurityAddon)
    )]
pub struct ApiDoc;

struct SecurityAddon;

impl Modify for SecurityAddon {
  fn modify(&self, openapi: &mut utoipa::openapi::OpenApi) {
    if openapi.components.is_none() {
      openapi.components = Some(Components::new());
    }

    let auth0_domain = std::env::var("AUTH0_DOMAIN").unwrap();
    let api_audience = std::env::var("AUTH0_AUDIENCE").unwrap();

    openapi.components.as_mut().unwrap().add_security_scheme(
      "bearerAuth",
      SecurityScheme::OAuth2(OAuth2::new([
        Flow::Implicit(Implicit::new(
          format!("{auth0_domain}/authorize?audience={api_audience}",),
          Scopes::from_iter([
            ("openid", "OpenId"),
            ("profile", "Profile"),
            ("email", "Email"),
          ]),
        )),
        Flow::AuthorizationCode(AuthorizationCode::new(
          format!("{auth0_domain}/authorize?audience={api_audience}",),
          format!("{auth0_domain}/oauth/token"),
          Scopes::from_iter([
            ("openid", "OpenId"),
            ("profile", "Profile"),
            ("email", "Email"),
          ]),
        )),
      ])),
    );
  }
}

And in my services, I have:

app.service(RapiDoc::with_openapi("/api/v1/openapi2.json", openapi.clone()).path("/docs"))
@juhaku
Copy link
Owner

juhaku commented Sep 7, 2024

For utoia-rapidocs side there's not much to what comes to the implementation to serve the RapiDoc and OpenAPI spec via actix-web it literally implements HttpServiceFactory which is attached by end users to the App::new().service(...) The implementation literally looks like this:

impl HttpServiceFactory for RapiDoc {
    fn register(self, config: &mut actix_web::dev::AppService) {
        let html = self.to_html();

        async fn serve_rapidoc(rapidoc: Data<String>) -> impl Responder {
            HttpResponse::Ok()
                .content_type("text/html")
                .body(rapidoc.to_string())
        }

        Resource::new(self.path.as_ref()) // < -- serve the rapidocs html file from `path`,  `RapiDoc` default to /.
            .guard(Get())
            .app_data(Data::new(html))
            .to(serve_rapidoc)
            .register(config);

        if let Some(openapi) = self.openapi { // If there is openapi serve the openapi according to the spec url
            async fn serve_openapi(openapi: Data<String>) -> impl Responder {
                HttpResponse::Ok()
                    .content_type("application/json")
                    .body(openapi.into_inner().to_string())
            }

            Resource::new(self.spec_url.as_ref())
                .guard(Get())
                .app_data(Data::new(
                    openapi.to_json().expect("Should serialize to JSON"),
                ))
                .to(serve_openapi)
                .register(config);
        }
    }
}

So my rough guess is the something is not configured correctly for the request is not pointing to or returning to correct place.

Note! The paths for RapiDoc is defined from the root (/) of the application always. So adding RapiDoc under some scoped service might cause some issues. And the paths need to be checked manually.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants