fix(OIDC): redirect to frontend, jwt, and callback handling

This commit is contained in:
aaldebs99 2025-10-12 02:15:47 +00:00
parent a23edca938
commit 943a3eefae
3 changed files with 35 additions and 26 deletions

View File

@ -58,7 +58,7 @@ function App(): React.ReactElement {
<CssBaseline /> <CssBaseline />
<Routes> <Routes>
<Route path="/login" element={!user ? <Login /> : <Navigate to="/dashboard" />} /> <Route path="/login" element={!user ? <Login /> : <Navigate to="/dashboard" />} />
<Route path="/auth/oidc/callback" element={<OidcCallback />} /> <Route path="/auth/callback" element={<OidcCallback />} />
<Route <Route
path="/*" path="/*"
element={ element={

View File

@ -14,9 +14,8 @@ const OidcCallback: React.FC = () => {
useEffect(() => { useEffect(() => {
const handleCallback = async () => { const handleCallback = async () => {
try { try {
const code = searchParams.get('code'); const token = searchParams.get('token');
const error = searchParams.get('error'); const error = searchParams.get('error');
const state = searchParams.get('state');
if (error) { if (error) {
setError(`Authentication failed: ${error}`); setError(`Authentication failed: ${error}`);
@ -24,26 +23,18 @@ const OidcCallback: React.FC = () => {
return; return;
} }
if (!code) { if (!token) {
setError('No authorization code received'); setError('No authentication token received from server');
setProcessing(false); setProcessing(false);
return; return;
} }
// Call the backend OIDC callback endpoint // Store the token and set up API authorization
const response = await api.get(`/auth/oidc/callback?code=${code}&state=${state || ''}`); localStorage.setItem('token', token);
api.defaults.headers.common['Authorization'] = `Bearer ${token}`;
if (response.data && response.data.token) { // Redirect to dashboard - the page will reload and AuthContext will pick up the token
// Store the token and user data
localStorage.setItem('token', response.data.token);
api.defaults.headers.common['Authorization'] = `Bearer ${response.data.token}`;
// Redirect to dashboard - the auth context will pick up the token on next page load
window.location.href = '/dashboard'; window.location.href = '/dashboard';
} else {
setError('Invalid response from authentication server');
setProcessing(false);
}
} catch (err: any) { } catch (err: any) {
console.error('OIDC callback error:', err); console.error('OIDC callback error:', err);

View File

@ -1,6 +1,6 @@
use axum::{ use axum::{
extract::{Query, State}, extract::{Query, State},
http::StatusCode, http::{StatusCode, HeaderMap},
response::{IntoResponse, Json, Response, Redirect}, response::{IntoResponse, Json, Response, Redirect},
routing::{get, post}, routing::{get, post},
Router, Router,
@ -188,6 +188,7 @@ async fn oidc_login(State(state): State<Arc<AppState>>) -> Result<Redirect, Stat
)] )]
async fn oidc_callback( async fn oidc_callback(
State(state): State<Arc<AppState>>, State(state): State<Arc<AppState>>,
headers: HeaderMap,
Query(params): Query<OidcCallbackQuery>, Query(params): Query<OidcCallbackQuery>,
) -> Result<Redirect, StatusCode> { ) -> Result<Redirect, StatusCode> {
tracing::info!("OIDC callback called with params: code={:?}, state={:?}, error={:?}", tracing::info!("OIDC callback called with params: code={:?}, state={:?}, error={:?}",
@ -326,8 +327,25 @@ async fn oidc_callback(
// Redirect to frontend with token in URL fragment // Redirect to frontend with token in URL fragment
// The frontend should extract the token and store it // The frontend should extract the token and store it
let redirect_url = format!("/#/auth/callback?token={}", urlencoding::encode(&token)); // Use absolute URL to ensure hash fragment is handled correctly by the browser
tracing::info!("OIDC authentication successful for user: {}, redirecting to: {}", user.username, redirect_url); let host = headers
.get("host")
.and_then(|h| h.to_str().ok())
.unwrap_or("localhost:8000");
// Check if behind a proxy (X-Forwarded-Proto header)
let protocol = headers
.get("x-forwarded-proto")
.and_then(|h| h.to_str().ok())
.unwrap_or("https");
let redirect_url = format!(
"{}://{}/auth/callback?token={}",
protocol,
host,
urlencoding::encode(&token)
);
tracing::info!("OIDC authentication successful for user: {}, redirecting to callback", user.username);
Ok(Redirect::to(&redirect_url)) Ok(Redirect::to(&redirect_url))
} }