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

feat: add token introspection #18

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion baffao-proxy/config/example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ client_id = "client_id"
client_secret = "client_secret"
authorization_redirect_uri = "http://127.0.0.1:3000/oauth/callback"
authorization_endpoint = "http://127.0.0.1:4444/oauth2/auth"
token_endpoint = "http://127.0.0.1/oauth2/token"
token_endpoint = "http://127.0.0.1:3000/oauth2/token"
introspection_endpoint = "http://127.0.0.1:3000/oauth2/introspect"
redirect_uri = "http://127.0.0.1:3000/"
1 change: 1 addition & 0 deletions baffao-proxy/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ async fn main() {
let app = Router::new()
.route("/oauth/authorize", get(oauth::authorize))
.route("/oauth/callback", get(oauth::callback))
.route("/oauth/introspect", get(oauth::introspect))
.route("/session", get(session::get_session))
.fallback(any(proxy::handler))
.layer(
Expand Down
7 changes: 7 additions & 0 deletions baffao-proxy/src/oauth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,10 @@ pub async fn callback(

(updated_jar, Redirect::temporary(&url.to_string()))
}

pub async fn introspect(
jar: CookieJar,
State(handler): State<OAuthHttpHandler>,
) -> impl IntoResponse {
handler.introspect(jar).await;
}
13 changes: 13 additions & 0 deletions baffao/src/handlers/introspect.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use axum_extra::extract::CookieJar;
use reqwest::StatusCode;

use crate::oauth::{IntrospectionTokenResponse, OAuthHttpHandler};

pub async fn oauth2_introspect(
handler: OAuthHttpHandler,
jar: CookieJar,
) -> (CookieJar, StatusCode, Option<IntrospectionTokenResponse>) {

Check warning on line 9 in baffao/src/handlers/introspect.rs

View workflow job for this annotation

GitHub Actions / cargo fmt & test

Diff in /home/runner/work/baffao/baffao/baffao/src/handlers/introspect.rs
let (updated_jar, response) = handler.introspect(jar).await;

(updated_jar, response.to_owned().map_or_else(|| StatusCode::UNAUTHORIZED, |_| StatusCode::OK), response)
}
2 changes: 2 additions & 0 deletions baffao/src/handlers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
pub use authorize::{oauth2_authorize, AuthorizationQuery};
pub use callback::{oauth2_callback, AuthorizationCallbackQuery};
pub use get_session::get_session_from_cookie;
pub use introspect::oauth2_introspect;
pub use proxy::proxy;

mod authorize;
mod callback;
mod get_session;
mod introspect;
mod proxy;
28 changes: 23 additions & 5 deletions baffao/src/oauth/client.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
use anyhow::{Context, Error};

Check warning on line 1 in baffao/src/oauth/client.rs

View workflow job for this annotation

GitHub Actions / cargo fmt & test

Diff in /home/runner/work/baffao/baffao/baffao/src/oauth/client.rs
use oauth2::{
basic::BasicClient, reqwest::async_http_client, AuthType, AuthUrl, AuthorizationCode, ClientId,
ClientSecret, CsrfToken, PkceCodeChallenge, PkceCodeVerifier, RedirectUrl, RefreshToken, Scope,
TokenUrl,
basic::BasicClient, reqwest::async_http_client, AccessToken as OAuthAccessToken, AuthType, AuthUrl, AuthorizationCode, ClientId, ClientSecret, CsrfToken, IntrospectionUrl, PkceCodeChallenge, PkceCodeVerifier, RedirectUrl, RefreshToken, Scope, TokenUrl
};
use reqwest::Url;

use super::{AccessToken, OAuthConfig};
use super::{AccessToken, IntrospectionTokenResponse, OAuthConfig};

pub struct OAuthClient {
config: OAuthConfig,
Expand All @@ -31,7 +29,7 @@
let token_endpoint =
TokenUrl::new(config.token_endpoint.clone()).context("Failed to parse token url")?;

let client = BasicClient::new(
let mut client = BasicClient::new(
ClientId::new(config.client_id.clone()),
Some(ClientSecret::new(config.client_secret.clone())),
auth_url,
Expand All @@ -40,6 +38,12 @@
.set_auth_type(AuthType::RequestBody)
.set_redirect_uri(redirect_uri);

if let Some(introspection_endpoint) = &config.introspection_endpoint {
let introspection_endpoint = IntrospectionUrl::new(introspection_endpoint.clone())
.context("Failed to parse introspection url")?;
client = client.set_introspection_uri(introspection_endpoint);
}

Ok(Self { config, client })
}

Expand Down Expand Up @@ -105,4 +109,18 @@

Ok(response.unwrap())
}

pub async fn introspect_token(

Check warning on line 113 in baffao/src/oauth/client.rs

View workflow job for this annotation

GitHub Actions / cargo fmt & test

Diff in /home/runner/work/baffao/baffao/baffao/src/oauth/client.rs
&self,
token: String,
) -> Result<IntrospectionTokenResponse, Error>
{
let response = self
.client
.introspect(&OAuthAccessToken::new(token))?
.request_async(async_http_client)
.await?;

Ok(response)
}
}
12 changes: 11 additions & 1 deletion baffao/src/oauth/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use chrono::{Duration, Utc};
use oauth2::TokenResponse;

use super::OAuthConfig;
use super::{IntrospectionTokenResponse, OAuthConfig};
use crate::cookies::new_cookie;
use crate::session::{update_session, Session};
use crate::{oauth::OAuthClient, settings::CookiesConfig};
Expand Down Expand Up @@ -128,6 +128,16 @@
Self {
client: self.client.clone(),
cookies_config: self.cookies_config.clone(),
}

Check warning on line 131 in baffao/src/oauth/http.rs

View workflow job for this annotation

GitHub Actions / cargo fmt & test

Diff in /home/runner/work/baffao/baffao/baffao/src/oauth/http.rs
}

pub async fn introspect(&self, jar: CookieJar) -> (CookieJar, Option<IntrospectionTokenResponse>) {
let (updated_jar, access_token) = self.get_or_refresh_token(jar).await.unwrap();
if access_token.is_none() {
return (updated_jar, None)
}

let result = self.client.introspect_token(access_token.unwrap().to_string()).await.unwrap();
(updated_jar, Some(result))
}
}
4 changes: 3 additions & 1 deletion baffao/src/oauth/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
pub use client::OAuthClient;
pub use http::OAuthHttpHandler;

mod client;

Check warning on line 4 in baffao/src/oauth/mod.rs

View workflow job for this annotation

GitHub Actions / cargo fmt & test

Diff in /home/runner/work/baffao/baffao/baffao/src/oauth/mod.rs
mod http;

use oauth2::{basic::BasicTokenType, EmptyExtraTokenFields, StandardTokenResponse};
use oauth2::{basic::BasicTokenType, EmptyExtraTokenFields, StandardTokenIntrospectionResponse, StandardTokenResponse};

use serde::Deserialize;

Expand All @@ -22,8 +22,10 @@
pub authorization_redirect_uri: String,
pub authorization_endpoint: String,
pub token_endpoint: String,
pub introspection_endpoint: Option<String>,
pub redirect_uri: Option<String>,
pub default_scopes: Option<Vec<String>>,
}

Check warning on line 28 in baffao/src/oauth/mod.rs

View workflow job for this annotation

GitHub Actions / cargo fmt & test

Diff in /home/runner/work/baffao/baffao/baffao/src/oauth/mod.rs

pub type AccessToken = StandardTokenResponse<EmptyExtraTokenFields, BasicTokenType>;
pub type IntrospectionTokenResponse = StandardTokenIntrospectionResponse<EmptyExtraTokenFields, BasicTokenType>;
Loading