Rework browser sessions
This commit is contained in:
110
src/axum_lib.rs
110
src/axum_lib.rs
@@ -1,5 +1,4 @@
|
||||
use anyhow::{anyhow, Result};
|
||||
use async_redis_session::RedisSessionStore;
|
||||
use axum::{
|
||||
extract::{self, Extension, Form, Path, Query, TypedHeader},
|
||||
http::{
|
||||
@@ -22,7 +21,7 @@ use headers::{
|
||||
};
|
||||
use openidconnect::core::{
|
||||
CoreClientMetadata, CoreClientRegistrationResponse, CoreJsonWebKeySet, CoreProviderMetadata,
|
||||
CoreResponseType, CoreTokenResponse, CoreUserInfoClaims, CoreUserInfoJsonWebToken,
|
||||
CoreTokenResponse, CoreUserInfoClaims, CoreUserInfoJsonWebToken,
|
||||
};
|
||||
use rand::rngs::OsRng;
|
||||
use rsa::{
|
||||
@@ -38,7 +37,6 @@ use tracing::info;
|
||||
|
||||
use super::config;
|
||||
use super::oidc::{self, CustomError};
|
||||
use super::session::*;
|
||||
use ::siwe_oidc::db::*;
|
||||
|
||||
impl IntoResponse for CustomError {
|
||||
@@ -82,14 +80,6 @@ async fn provider_metadata(
|
||||
Ok(oidc::metadata(config.base_url)?.into())
|
||||
}
|
||||
|
||||
// TODO should check Authorization header
|
||||
// Actually, client secret can be
|
||||
// 1. in the POST (currently supported) [x]
|
||||
// 2. Authorization header [x]
|
||||
// 3. JWT [ ]
|
||||
// 4. signed JWT [ ]
|
||||
// according to Keycloak
|
||||
|
||||
async fn token(
|
||||
Form(form): Form<oidc::TokenForm>,
|
||||
bearer: Option<TypedHeader<Authorization<Bearer>>>,
|
||||
@@ -116,43 +106,16 @@ async fn token(
|
||||
Ok(token_response.into())
|
||||
}
|
||||
|
||||
// TODO handle `registration` parameter
|
||||
async fn authorize(
|
||||
session: UserSessionFromSession,
|
||||
Query(params): Query<oidc::AuthorizeParams>,
|
||||
Extension(redis_client): Extension<RedisClient>,
|
||||
) -> Result<(HeaderMap, Redirect), CustomError> {
|
||||
let (nonce, headers) = match session {
|
||||
UserSessionFromSession::Found(nonce) => (nonce, HeaderMap::new()),
|
||||
UserSessionFromSession::Invalid(cookie) => {
|
||||
let mut headers = HeaderMap::new();
|
||||
headers.insert(header::SET_COOKIE, cookie);
|
||||
return Ok((
|
||||
headers,
|
||||
Redirect::to(
|
||||
format!(
|
||||
"/authorize?client_id={}&redirect_uri={}&scope={}&response_type={}&state={}&client_id={}{}",
|
||||
¶ms.client_id,
|
||||
¶ms.redirect_uri.to_string(),
|
||||
¶ms.scope.to_string(),
|
||||
¶ms.response_type.unwrap_or(CoreResponseType::Code).as_ref(),
|
||||
¶ms.state.unwrap_or_default(),
|
||||
¶ms.client_id,
|
||||
¶ms.nonce.map(|n| format!("&nonce={}", n.secret())).unwrap_or_default()
|
||||
)
|
||||
.parse()
|
||||
.map_err(|e| anyhow!("Could not parse URI: {}", e))?,
|
||||
),
|
||||
));
|
||||
}
|
||||
UserSessionFromSession::Created { header, nonce } => {
|
||||
let mut headers = HeaderMap::new();
|
||||
headers.insert(header::SET_COOKIE, header);
|
||||
(nonce, headers)
|
||||
}
|
||||
};
|
||||
|
||||
let url = oidc::authorize(params, nonce, &redis_client).await?;
|
||||
let (url, session_cookie) = oidc::authorize(params, &redis_client).await?;
|
||||
let mut headers = HeaderMap::new();
|
||||
headers.insert(
|
||||
header::SET_COOKIE,
|
||||
session_cookie.to_string().parse().unwrap(),
|
||||
);
|
||||
Ok((
|
||||
headers,
|
||||
Redirect::to(
|
||||
@@ -164,58 +127,16 @@ async fn authorize(
|
||||
}
|
||||
|
||||
async fn sign_in(
|
||||
session: UserSessionFromSession,
|
||||
Query(params): Query<oidc::SignInParams>,
|
||||
TypedHeader(cookies): TypedHeader<headers::Cookie>,
|
||||
Extension(redis_client): Extension<RedisClient>,
|
||||
) -> Result<(HeaderMap, Redirect), CustomError> {
|
||||
let (nonce, headers) = match session {
|
||||
UserSessionFromSession::Found(nonce) => (nonce, HeaderMap::new()),
|
||||
UserSessionFromSession::Invalid(header) => {
|
||||
let mut headers = HeaderMap::new();
|
||||
headers.insert(header::SET_COOKIE, header);
|
||||
return Ok((
|
||||
headers,
|
||||
Redirect::to(
|
||||
format!(
|
||||
"/authorize?client_id={}&redirect_uri={}&scope=openid&response_type=code&state={}",
|
||||
¶ms.client_id.clone(),
|
||||
¶ms.redirect_uri.to_string(),
|
||||
¶ms.state,
|
||||
)
|
||||
.parse()
|
||||
.map_err(|e| anyhow!("Could not parse URI: {}", e))?,
|
||||
),
|
||||
));
|
||||
}
|
||||
UserSessionFromSession::Created { .. } => {
|
||||
return Ok((
|
||||
HeaderMap::new(),
|
||||
Redirect::to(
|
||||
format!(
|
||||
"/authorize?client_id={}&redirect_uri={}&scope=openid&response_type=code&state={}",
|
||||
¶ms.client_id.clone(),
|
||||
¶ms.redirect_uri.to_string(),
|
||||
¶ms.state,
|
||||
)
|
||||
.parse()
|
||||
.map_err(|e| anyhow!("Could not parse URI: {}", e))?,
|
||||
),
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
let url = oidc::sign_in(params, Some(nonce), cookies, &redis_client).await?;
|
||||
|
||||
Ok((
|
||||
headers,
|
||||
Redirect::to(
|
||||
url.as_str()
|
||||
.parse()
|
||||
.map_err(|e| anyhow!("Could not parse URI: {}", e))?,
|
||||
),
|
||||
) -> Result<Redirect, CustomError> {
|
||||
let url = oidc::sign_in(params, cookies, &redis_client).await?;
|
||||
Ok(Redirect::to(
|
||||
url.as_str()
|
||||
.parse()
|
||||
.map_err(|e| anyhow!("Could not parse URI: {}", e))?,
|
||||
))
|
||||
// TODO clear session
|
||||
}
|
||||
|
||||
async fn register(
|
||||
@@ -434,11 +355,6 @@ pub async fn main() {
|
||||
.layer(AddExtensionLayer::new(private_key))
|
||||
.layer(AddExtensionLayer::new(config.clone()))
|
||||
.layer(AddExtensionLayer::new(redis_client))
|
||||
.layer(AddExtensionLayer::new(
|
||||
RedisSessionStore::new(config.redis_url.clone())
|
||||
.unwrap()
|
||||
.with_prefix("async-sessions/"),
|
||||
))
|
||||
.layer(TraceLayer::new_for_http());
|
||||
|
||||
let addr = SocketAddr::from((config.address, config.port));
|
||||
|
||||
Reference in New Issue
Block a user