jwt auth
This commit is contained in:
parent
cd56e93cb0
commit
a8180ba55b
3 changed files with 54 additions and 24 deletions
26
Cargo.lock
generated
26
Cargo.lock
generated
|
@ -181,19 +181,17 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "axum_oidc"
|
name = "axum_oidc"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://git2.zettoit.eu/pfz4/axum_oidc#89da8cc07fba48a9adcd5821fbc7c527c60ec802"
|
source = "git+https://git2.zettoit.eu/pfz4/axum_oidc#3b9438d1f3cf58c1edb9f503aea4e6d7783194d2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"axum",
|
"axum",
|
||||||
"axum-extra",
|
"axum-extra",
|
||||||
"futures-util",
|
|
||||||
"jsonwebtoken",
|
"jsonwebtoken",
|
||||||
"openidconnect",
|
"openidconnect",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tower",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -807,9 +805,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.14.1"
|
version = "0.14.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12"
|
checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "headers"
|
name = "headers"
|
||||||
|
@ -1006,7 +1004,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897"
|
checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"equivalent",
|
"equivalent",
|
||||||
"hashbrown 0.14.1",
|
"hashbrown 0.14.2",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1728,9 +1726,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "0.38.19"
|
version = "0.38.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "745ecfa778e66b2b63c88a61cb36e0eea109e803b0b86bf9879fbc77c70e86ed"
|
checksum = "67ce50cb2e16c2903e30d1cbccfd8387a74b9d4c938b6a4c5ec6cc7556f7a8a0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.4.1",
|
"bitflags 2.4.1",
|
||||||
"errno",
|
"errno",
|
||||||
|
@ -2114,18 +2112,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.49"
|
version = "1.0.50"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4"
|
checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror-impl"
|
name = "thiserror-impl"
|
||||||
version = "1.0.49"
|
version = "1.0.50"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc"
|
checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -2294,9 +2292,9 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing"
|
name = "tracing"
|
||||||
version = "0.1.39"
|
version = "0.1.40"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ee2ef2af84856a50c1d430afce2fdded0a4ec7eda868db86409b4543df0797f9"
|
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
|
21
src/error.rs
21
src/error.rs
|
@ -1,4 +1,7 @@
|
||||||
use axum::{http::StatusCode, response::IntoResponse};
|
use axum::{
|
||||||
|
http::StatusCode,
|
||||||
|
response::{IntoResponse, Response},
|
||||||
|
};
|
||||||
use log::error;
|
use log::error;
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
@ -26,18 +29,24 @@ pub enum Error {
|
||||||
|
|
||||||
#[error("encryption error")]
|
#[error("encryption error")]
|
||||||
ChaCha,
|
ChaCha,
|
||||||
|
|
||||||
|
#[error("oidc redirect")]
|
||||||
|
Oidc(Response),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoResponse for Error {
|
impl IntoResponse for Error {
|
||||||
fn into_response(self) -> axum::response::Response {
|
fn into_response(self) -> axum::response::Response {
|
||||||
match self {
|
match self {
|
||||||
Self::PhraseInvalid => (StatusCode::BAD_REQUEST, "url is not valid\n"),
|
Self::PhraseInvalid => (StatusCode::BAD_REQUEST, "url is not valid\n").into_response(),
|
||||||
Self::BinNotFound => (StatusCode::NOT_FOUND, "bin does not exist\n"),
|
Self::BinNotFound => (StatusCode::NOT_FOUND, "bin does not exist\n").into_response(),
|
||||||
Self::DataFileExists => (StatusCode::CONFLICT, "bin already contains data\n"),
|
Self::DataFileExists => {
|
||||||
Self::ParseTtl => (StatusCode::BAD_REQUEST, "invalid ttl class\n"),
|
(StatusCode::CONFLICT, "bin already contains data\n").into_response()
|
||||||
|
}
|
||||||
|
Self::ParseTtl => (StatusCode::BAD_REQUEST, "invalid ttl class\n").into_response(),
|
||||||
|
Self::Oidc(response) => response.into_response(),
|
||||||
_ => {
|
_ => {
|
||||||
error!("{:?}", self);
|
error!("{:?}", self);
|
||||||
(StatusCode::INTERNAL_SERVER_ERROR, "internal server error\n")
|
(StatusCode::INTERNAL_SERVER_ERROR, "internal server error\n").into_response()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.into_response()
|
.into_response()
|
||||||
|
|
31
src/main.rs
31
src/main.rs
|
@ -12,11 +12,14 @@ use axum::{
|
||||||
extract::{BodyStream, FromRef, Path, Query, State},
|
extract::{BodyStream, FromRef, Path, Query, State},
|
||||||
headers::ContentType,
|
headers::ContentType,
|
||||||
http::{header, HeaderMap, StatusCode},
|
http::{header, HeaderMap, StatusCode},
|
||||||
response::{Html, IntoResponse, Redirect},
|
response::{Html, IntoResponse, Redirect, Response},
|
||||||
routing::get,
|
routing::get,
|
||||||
Router, TypedHeader,
|
Router, TypedHeader,
|
||||||
};
|
};
|
||||||
use axum_oidc::oidc::{self, EmptyAdditionalClaims, OidcApplication, OidcExtractor};
|
use axum_oidc::{
|
||||||
|
jwt::{Claims, JwtApplication},
|
||||||
|
oidc::{self, EmptyAdditionalClaims, OidcApplication, OidcExtractor},
|
||||||
|
};
|
||||||
use chacha20::{
|
use chacha20::{
|
||||||
cipher::{KeyIvInit, StreamCipher},
|
cipher::{KeyIvInit, StreamCipher},
|
||||||
ChaCha20,
|
ChaCha20,
|
||||||
|
@ -55,6 +58,7 @@ type HandlerResult<T> = Result<T, Error>;
|
||||||
pub struct AppState {
|
pub struct AppState {
|
||||||
application_base: String,
|
application_base: String,
|
||||||
oidc_application: OidcApplication<EmptyAdditionalClaims>,
|
oidc_application: OidcApplication<EmptyAdditionalClaims>,
|
||||||
|
jwt_application: JwtApplication<EmptyAdditionalClaims>,
|
||||||
data: String,
|
data: String,
|
||||||
key_salt: KeySalt,
|
key_salt: KeySalt,
|
||||||
id_salt: IdSalt,
|
id_salt: IdSalt,
|
||||||
|
@ -67,6 +71,12 @@ impl FromRef<AppState> for OidcApplication<EmptyAdditionalClaims> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromRef<AppState> for JwtApplication<EmptyAdditionalClaims> {
|
||||||
|
fn from_ref(input: &AppState) -> Self {
|
||||||
|
input.jwt_application.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
|
||||||
pub struct ExpiryHeapItem {
|
pub struct ExpiryHeapItem {
|
||||||
pub expires_at: u64,
|
pub expires_at: u64,
|
||||||
|
@ -101,6 +111,13 @@ async fn main() {
|
||||||
.await
|
.await
|
||||||
.expect("Oidc Authentication Client");
|
.expect("Oidc Authentication Client");
|
||||||
|
|
||||||
|
let jwt_application = JwtApplication::new(
|
||||||
|
issuer.to_string(),
|
||||||
|
env::var("AUDIENCE").expect("AUDIENCE env var"),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.expect("Jwt Authentication Client");
|
||||||
|
|
||||||
let data_path = env::var("DATA_PATH").expect("DATA_PATH env var");
|
let data_path = env::var("DATA_PATH").expect("DATA_PATH env var");
|
||||||
|
|
||||||
let garbage_collector = GarbageCollector::new(data_path.clone()).await;
|
let garbage_collector = GarbageCollector::new(data_path.clone()).await;
|
||||||
|
@ -109,6 +126,7 @@ async fn main() {
|
||||||
let state: AppState = AppState {
|
let state: AppState = AppState {
|
||||||
application_base,
|
application_base,
|
||||||
oidc_application,
|
oidc_application,
|
||||||
|
jwt_application,
|
||||||
data: data_path,
|
data: data_path,
|
||||||
key_salt: KeySalt::from_str(&env::var("KEY_SALT").expect("KEY_SALT env var"))
|
key_salt: KeySalt::from_str(&env::var("KEY_SALT").expect("KEY_SALT env var"))
|
||||||
.expect("KEY SALT valid hex"),
|
.expect("KEY SALT valid hex"),
|
||||||
|
@ -133,9 +151,14 @@ async fn main() {
|
||||||
|
|
||||||
async fn get_index(
|
async fn get_index(
|
||||||
State(app_state): State<AppState>,
|
State(app_state): State<AppState>,
|
||||||
OidcExtractor { claims, .. }: OidcExtractor<EmptyAdditionalClaims>,
|
oidc_extractor: Result<OidcExtractor<EmptyAdditionalClaims>, axum_oidc::error::Error>,
|
||||||
|
jwt_claims: Option<Claims<EmptyAdditionalClaims>>,
|
||||||
) -> Result<impl IntoResponse, Error> {
|
) -> Result<impl IntoResponse, Error> {
|
||||||
let subject = claims.subject().to_string();
|
let subject = match (oidc_extractor, jwt_claims) {
|
||||||
|
(_, Some(claims)) => claims.sub.to_string(),
|
||||||
|
(Ok(oidc), None) => oidc.claims.subject().to_string(),
|
||||||
|
(Err(err), None) => return Err(Error::Oidc(err.into_response())),
|
||||||
|
};
|
||||||
|
|
||||||
//generate phrase and derive id from it
|
//generate phrase and derive id from it
|
||||||
let phrase = Phrase::random();
|
let phrase = Phrase::random();
|
||||||
|
|
Loading…
Reference in a new issue