Skip to content

Commit 212d2cc

Browse files
committed
Log out browser sessions when receiving a backchannel logout notification
1 parent 35497cb commit 212d2cc

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

crates/handlers/src/upstream_oauth2/backchannel_logout.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use axum::{
1212
};
1313
use hyper::StatusCode;
1414
use mas_axum_utils::record_error;
15-
use mas_data_model::UpstreamOAuthProvider;
15+
use mas_data_model::{UpstreamOAuthProvider, UpstreamOAuthProviderOnBackchannelLogout};
1616
use mas_jose::{
1717
claims::{self, Claim, TimeOptions},
1818
jwt::JwtDecodeError,
@@ -23,6 +23,7 @@ use mas_oidc_client::{
2323
};
2424
use mas_storage::{
2525
BoxClock, BoxRepository, Pagination, upstream_oauth2::UpstreamOAuthSessionFilter,
26+
user::BrowserSessionFilter,
2627
};
2728
use oauth2_types::errors::{ClientError, ClientErrorCode};
2829
use serde::Deserialize;
@@ -229,6 +230,9 @@ pub(crate) async fn post(
229230
filter = filter.with_sid_claim(sid);
230231
}
231232

233+
// Load the corresponding authentication sessions, by batches of 100s. It's
234+
// VERY unlikely that we'll ever have more that 100 sessions for a single
235+
// logout notification, but we'll handle it anyway.
232236
let mut cursor = Pagination::first(100);
233237
let mut sessions = Vec::new();
234238
loop {
@@ -244,7 +248,21 @@ pub(crate) async fn post(
244248
}
245249
}
246250

247-
tracing::info!(sub, sid, %provider.id, "Backchannel logout received, found {} corresponding sessions", sessions.len());
251+
tracing::info!(sub, sid, %provider.id, "Backchannel logout received, found {} corresponding authentication sessions", sessions.len());
252+
253+
match provider.on_backchannel_logout {
254+
UpstreamOAuthProviderOnBackchannelLogout::DoNothing => {
255+
tracing::warn!(%provider.id, "Provider configured to do nothing on backchannel logout");
256+
}
257+
UpstreamOAuthProviderOnBackchannelLogout::LogoutBrowserOnly => {
258+
let filter =
259+
BrowserSessionFilter::new().authenticated_by_upstream_sessions_only(&sessions);
260+
let affected = repo.browser_session().finish_bulk(&clock, filter).await?;
261+
tracing::info!("Finished {affected} browser sessions");
262+
}
263+
}
264+
265+
repo.save().await?;
248266

249267
Ok(())
250268
}

0 commit comments

Comments
 (0)