mirror of
https://github.com/TECHNOFAB11/jwt-authorizer.git
synced 2025-12-11 23:50:07 +01:00
chore: fmt
This commit is contained in:
parent
ec02b70a99
commit
d8fb138d46
8 changed files with 86 additions and 78 deletions
|
|
@ -28,11 +28,13 @@ async fn main() {
|
||||||
|
|
||||||
// First let's create an authorizer builder from a JWKS Endpoint
|
// First let's create an authorizer builder from a JWKS Endpoint
|
||||||
// User is a struct deserializable from JWT claims representing the authorized user
|
// User is a struct deserializable from JWT claims representing the authorized user
|
||||||
let jwt_auth: JwtAuthorizer<User> = JwtAuthorizer::
|
let jwt_auth: JwtAuthorizer<User> = JwtAuthorizer::from_jwks_url("http://localhost:3000/oidc/jwks")
|
||||||
from_jwks_url("http://localhost:3000/oidc/jwks")
|
// .no_refresh()
|
||||||
// .no_refresh()
|
.refresh(Refresh {
|
||||||
.refresh(Refresh {strategy: RefreshStrategy::Interval, ..Default::default()})
|
strategy: RefreshStrategy::Interval,
|
||||||
.check(claim_checker);
|
..Default::default()
|
||||||
|
})
|
||||||
|
.check(claim_checker);
|
||||||
|
|
||||||
let oidc = Router::new()
|
let oidc = Router::new()
|
||||||
.route("/authorize", post(oidc_provider::authorize))
|
.route("/authorize", post(oidc_provider::authorize))
|
||||||
|
|
|
||||||
|
|
@ -46,9 +46,7 @@ struct JwkSet {
|
||||||
pub async fn jwks() -> Json<Value> {
|
pub async fn jwks() -> Json<Value> {
|
||||||
// let mut ksmap = serde_json::Map::new();
|
// let mut ksmap = serde_json::Map::new();
|
||||||
|
|
||||||
let mut kset = JwkSet {
|
let mut kset = JwkSet { keys: Vec::<Jwk>::new() };
|
||||||
keys: Vec::<Jwk>::new(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let keypair = RsaKeyPair::from_pem(include_bytes!("../../../config/jwtRS256.key")).unwrap();
|
let keypair = RsaKeyPair::from_pem(include_bytes!("../../../config/jwtRS256.key")).unwrap();
|
||||||
let mut pk = keypair.to_jwk_public_key();
|
let mut pk = keypair.to_jwk_public_key();
|
||||||
|
|
@ -64,19 +62,14 @@ pub async fn jwks() -> Json<Value> {
|
||||||
pk.set_key_use("sig");
|
pk.set_key_use("sig");
|
||||||
kset.keys.push(pk);
|
kset.keys.push(pk);
|
||||||
|
|
||||||
let keypair =
|
let keypair = EcKeyPair::from_pem(include_bytes!("../../../config/ec256-private.pem"), Some(EcCurve::P256)).unwrap();
|
||||||
EcKeyPair::from_pem(include_bytes!("../../../config/ec256-private.pem"), Some(EcCurve::P256)).unwrap();
|
|
||||||
let mut pk = keypair.to_jwk_public_key();
|
let mut pk = keypair.to_jwk_public_key();
|
||||||
pk.set_key_id("key-ec");
|
pk.set_key_id("key-ec");
|
||||||
pk.set_algorithm("ES256");
|
pk.set_algorithm("ES256");
|
||||||
pk.set_key_use("sig");
|
pk.set_key_use("sig");
|
||||||
kset.keys.push(pk);
|
kset.keys.push(pk);
|
||||||
|
|
||||||
let keypair = EcKeyPair::from_pem(
|
let keypair = EcKeyPair::from_pem(include_bytes!("../../../config/private_ecdsa_key.pem"), Some(EcCurve::P256)).unwrap();
|
||||||
include_bytes!("../../../config/private_ecdsa_key.pem"),
|
|
||||||
Some(EcCurve::P256),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
let mut pk = keypair.to_jwk_public_key();
|
let mut pk = keypair.to_jwk_public_key();
|
||||||
pk.set_key_id("ec01");
|
pk.set_key_id("ec01");
|
||||||
pk.set_algorithm("ES256");
|
pk.set_algorithm("ES256");
|
||||||
|
|
@ -225,8 +218,8 @@ where
|
||||||
let TypedHeader(Authorization(bearer)) = TypedHeader::<Authorization<Bearer>>::from_request_parts(parts, state)
|
let TypedHeader(Authorization(bearer)) = TypedHeader::<Authorization<Bearer>>::from_request_parts(parts, state)
|
||||||
.await
|
.await
|
||||||
.map_err(|_| AuthError::InvalidToken)?;
|
.map_err(|_| AuthError::InvalidToken)?;
|
||||||
let token_data = decode::<Claims>(bearer.token(), &KEYS.decoding, &Validation::default())
|
let token_data =
|
||||||
.map_err(|_| AuthError::InvalidToken)?;
|
decode::<Claims>(bearer.token(), &KEYS.decoding, &Validation::default()).map_err(|_| AuthError::InvalidToken)?;
|
||||||
|
|
||||||
Ok(token_data.claims)
|
Ok(token_data.claims)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@ use serde::de::DeserializeOwned;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{AuthError, InitError},
|
error::{AuthError, InitError},
|
||||||
jwks::{key_store_manager::KeyStoreManager, KeySource}, Refresh,
|
jwks::{key_store_manager::KeyStoreManager, KeySource},
|
||||||
|
Refresh,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait ClaimsChecker<C> {
|
pub trait ClaimsChecker<C> {
|
||||||
|
|
@ -66,7 +67,10 @@ where
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from(key_source_type: &KeySourceType, claims_checker: Option<FnClaimsChecker<C>>) -> Result<Authorizer<C>, InitError> {
|
pub(crate) fn from(
|
||||||
|
key_source_type: &KeySourceType,
|
||||||
|
claims_checker: Option<FnClaimsChecker<C>>,
|
||||||
|
) -> Result<Authorizer<C>, InitError> {
|
||||||
let key = match key_source_type {
|
let key = match key_source_type {
|
||||||
KeySourceType::RSA(path) => DecodingKey::from_rsa_pem(&read_data(path.as_str())?)?,
|
KeySourceType::RSA(path) => DecodingKey::from_rsa_pem(&read_data(path.as_str())?)?,
|
||||||
KeySourceType::EC(path) => DecodingKey::from_ec_der(&read_data(path.as_str())?),
|
KeySourceType::EC(path) => DecodingKey::from_ec_der(&read_data(path.as_str())?),
|
||||||
|
|
@ -81,7 +85,11 @@ where
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from_jwks_url(url: &str, claims_checker: Option<FnClaimsChecker<C>>, refresh: Refresh) -> Result<Authorizer<C>, InitError> {
|
pub(crate) fn from_jwks_url(
|
||||||
|
url: &str,
|
||||||
|
claims_checker: Option<FnClaimsChecker<C>>,
|
||||||
|
refresh: Refresh,
|
||||||
|
) -> Result<Authorizer<C>, InitError> {
|
||||||
let key_store_manager = KeyStoreManager::new(url, refresh);
|
let key_store_manager = KeyStoreManager::new(url, refresh);
|
||||||
Ok(Authorizer {
|
Ok(Authorizer {
|
||||||
key_source: KeySource::KeyStoreSource(key_store_manager),
|
key_source: KeySource::KeyStoreSource(key_store_manager),
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use axum::{
|
use axum::{
|
||||||
|
body::{self, BoxBody, Empty},
|
||||||
http::StatusCode,
|
http::StatusCode,
|
||||||
response::{IntoResponse, Response}, body::{self, Empty, BoxBody},
|
response::{IntoResponse, Response},
|
||||||
};
|
};
|
||||||
use http::header;
|
use http::header;
|
||||||
use jsonwebtoken::Algorithm;
|
use jsonwebtoken::Algorithm;
|
||||||
|
|
@ -47,7 +48,7 @@ pub enum AuthError {
|
||||||
InvalidClaims(),
|
InvalidClaims(),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn response_wwwauth(status: StatusCode, bearer: &str) -> Response<BoxBody> {
|
fn response_wwwauth(status: StatusCode, bearer: &str) -> Response<BoxBody> {
|
||||||
let mut res = Response::new(body::boxed(Empty::new()));
|
let mut res = Response::new(body::boxed(Empty::new()));
|
||||||
*res.status_mut() = status;
|
*res.status_mut() = status;
|
||||||
let h = if bearer.is_empty() {
|
let h = if bearer.is_empty() {
|
||||||
|
|
@ -60,7 +61,7 @@ fn response_wwwauth(status: StatusCode, bearer: &str) -> Response<BoxBody> {
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
fn response_500() -> Response<BoxBody> {
|
fn response_500() -> Response<BoxBody> {
|
||||||
let mut res = Response::new(body::boxed(Empty::new()));
|
let mut res = Response::new(body::boxed(Empty::new()));
|
||||||
*res.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
|
*res.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
|
||||||
|
|
||||||
|
|
@ -71,38 +72,44 @@ fn response_500() -> Response<BoxBody> {
|
||||||
impl IntoResponse for AuthError {
|
impl IntoResponse for AuthError {
|
||||||
fn into_response(self) -> Response {
|
fn into_response(self) -> Response {
|
||||||
let resp = match self {
|
let resp = match self {
|
||||||
AuthError::JwksRefreshError(err) => {
|
AuthError::JwksRefreshError(err) => {
|
||||||
tracing::error!("AuthErrors::JwksRefreshError: {}", err);
|
tracing::error!("AuthErrors::JwksRefreshError: {}", err);
|
||||||
response_500()
|
response_500()
|
||||||
},
|
}
|
||||||
AuthError::InvalidKey(err) => {
|
AuthError::InvalidKey(err) => {
|
||||||
tracing::error!("AuthErrors::InvalidKey: {}", err);
|
tracing::error!("AuthErrors::InvalidKey: {}", err);
|
||||||
response_500()
|
response_500()
|
||||||
},
|
}
|
||||||
AuthError::JwksSerialisationError(err) => {
|
AuthError::JwksSerialisationError(err) => {
|
||||||
tracing::error!("AuthErrors::JwksSerialisationError: {}", err);
|
tracing::error!("AuthErrors::JwksSerialisationError: {}", err);
|
||||||
response_500()
|
response_500()
|
||||||
},
|
}
|
||||||
AuthError::InvalidKeyAlg(err) => {
|
AuthError::InvalidKeyAlg(err) => {
|
||||||
debug!("AuthErrors::InvalidKeyAlg: {:?}", err);
|
debug!("AuthErrors::InvalidKeyAlg: {:?}", err);
|
||||||
response_wwwauth(StatusCode::UNAUTHORIZED, "error=\"invalid_token\", error_description=\"invalid key algorithm\"")
|
response_wwwauth(
|
||||||
},
|
StatusCode::UNAUTHORIZED,
|
||||||
|
"error=\"invalid_token\", error_description=\"invalid key algorithm\"",
|
||||||
|
)
|
||||||
|
}
|
||||||
AuthError::InvalidKid(err) => {
|
AuthError::InvalidKid(err) => {
|
||||||
debug!("AuthErrors::InvalidKid: {}", err);
|
debug!("AuthErrors::InvalidKid: {}", err);
|
||||||
response_wwwauth(StatusCode::UNAUTHORIZED, "error=\"invalid_token\", error_description=\"invalid kid\"")
|
response_wwwauth(
|
||||||
},
|
StatusCode::UNAUTHORIZED,
|
||||||
|
"error=\"invalid_token\", error_description=\"invalid kid\"",
|
||||||
|
)
|
||||||
|
}
|
||||||
AuthError::InvalidToken(err) => {
|
AuthError::InvalidToken(err) => {
|
||||||
debug!("AuthErrors::InvalidToken: {}", err);
|
debug!("AuthErrors::InvalidToken: {}", err);
|
||||||
response_wwwauth(StatusCode::UNAUTHORIZED, "error=\"invalid_token\"")
|
response_wwwauth(StatusCode::UNAUTHORIZED, "error=\"invalid_token\"")
|
||||||
},
|
}
|
||||||
AuthError::MissingToken() => {
|
AuthError::MissingToken() => {
|
||||||
debug!("AuthErrors::MissingToken");
|
debug!("AuthErrors::MissingToken");
|
||||||
response_wwwauth(StatusCode::UNAUTHORIZED, "")
|
response_wwwauth(StatusCode::UNAUTHORIZED, "")
|
||||||
},
|
}
|
||||||
AuthError::InvalidClaims() => {
|
AuthError::InvalidClaims() => {
|
||||||
debug!("AuthErrors::InvalidClaims");
|
debug!("AuthErrors::InvalidClaims");
|
||||||
response_wwwauth(StatusCode::FORBIDDEN, "error=\"insufficient_scope\"")
|
response_wwwauth(StatusCode::FORBIDDEN, "error=\"insufficient_scope\"")
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
resp
|
resp
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ use crate::error::AuthError;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum RefreshStrategy {
|
pub enum RefreshStrategy {
|
||||||
|
|
||||||
/// refresh periodicaly
|
/// refresh periodicaly
|
||||||
Interval,
|
Interval,
|
||||||
|
|
||||||
|
|
@ -37,7 +36,7 @@ pub struct Refresh {
|
||||||
|
|
||||||
impl Default for Refresh {
|
impl Default for Refresh {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
strategy: RefreshStrategy::KeyNotFound,
|
strategy: RefreshStrategy::KeyNotFound,
|
||||||
refresh_interval: Duration::from_secs(600),
|
refresh_interval: Duration::from_secs(600),
|
||||||
minimal_refresh_interval: Duration::from_secs(30),
|
minimal_refresh_interval: Duration::from_secs(30),
|
||||||
|
|
@ -81,17 +80,15 @@ impl KeyStoreManager {
|
||||||
let mut ks_gard = kstore.lock().await;
|
let mut ks_gard = kstore.lock().await;
|
||||||
let key = match self.refresh.strategy {
|
let key = match self.refresh.strategy {
|
||||||
RefreshStrategy::Interval => {
|
RefreshStrategy::Interval => {
|
||||||
if ks_gard.should_refresh(self.refresh.refresh_interval) && ks_gard.can_refresh(self.refresh.minimal_refresh_interval, self.refresh.retry_interval) {
|
if ks_gard.should_refresh(self.refresh.refresh_interval)
|
||||||
|
&& ks_gard.can_refresh(self.refresh.minimal_refresh_interval, self.refresh.retry_interval)
|
||||||
|
{
|
||||||
ks_gard.refresh(&self.key_url, &[]).await?;
|
ks_gard.refresh(&self.key_url, &[]).await?;
|
||||||
}
|
}
|
||||||
if let Some(ref kid) = header.kid {
|
if let Some(ref kid) = header.kid {
|
||||||
ks_gard
|
ks_gard.find_kid(kid).ok_or_else(|| AuthError::InvalidKid(kid.to_owned()))?
|
||||||
.find_kid(kid)
|
|
||||||
.ok_or_else(|| AuthError::InvalidKid(kid.to_owned()))?
|
|
||||||
} else {
|
} else {
|
||||||
ks_gard
|
ks_gard.find_alg(&header.alg).ok_or(AuthError::InvalidKeyAlg(header.alg))?
|
||||||
.find_alg(&header.alg)
|
|
||||||
.ok_or(AuthError::InvalidKeyAlg(header.alg))?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RefreshStrategy::KeyNotFound => {
|
RefreshStrategy::KeyNotFound => {
|
||||||
|
|
@ -101,11 +98,8 @@ impl KeyStoreManager {
|
||||||
jwk
|
jwk
|
||||||
} else if ks_gard.can_refresh(self.refresh.minimal_refresh_interval, self.refresh.retry_interval) {
|
} else if ks_gard.can_refresh(self.refresh.minimal_refresh_interval, self.refresh.retry_interval) {
|
||||||
ks_gard.refresh(&self.key_url, &[("kid", kid)]).await?;
|
ks_gard.refresh(&self.key_url, &[("kid", kid)]).await?;
|
||||||
ks_gard
|
ks_gard.find_kid(kid).ok_or_else(|| AuthError::InvalidKid(kid.to_owned()))?
|
||||||
.find_kid(kid)
|
|
||||||
.ok_or_else(|| AuthError::InvalidKid(kid.to_owned()))?
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
return Err(AuthError::InvalidKid(kid.to_owned()));
|
return Err(AuthError::InvalidKid(kid.to_owned()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -119,8 +113,7 @@ impl KeyStoreManager {
|
||||||
&self.key_url,
|
&self.key_url,
|
||||||
&[(
|
&[(
|
||||||
"alg",
|
"alg",
|
||||||
&serde_json::to_string(&header.alg)
|
&serde_json::to_string(&header.alg).map_err(|_| AuthError::InvalidKeyAlg(header.alg))?,
|
||||||
.map_err(|_| AuthError::InvalidKeyAlg(header.alg))?,
|
|
||||||
)],
|
)],
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
@ -131,19 +124,15 @@ impl KeyStoreManager {
|
||||||
return Err(AuthError::InvalidKeyAlg(header.alg));
|
return Err(AuthError::InvalidKeyAlg(header.alg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
RefreshStrategy::NoRefresh => {
|
RefreshStrategy::NoRefresh => {
|
||||||
if ks_gard.load_time.is_none() {
|
if ks_gard.load_time.is_none() {
|
||||||
ks_gard.refresh(&self.key_url, &[]).await?;
|
ks_gard.refresh(&self.key_url, &[]).await?;
|
||||||
}
|
}
|
||||||
if let Some(ref kid) = header.kid {
|
if let Some(ref kid) = header.kid {
|
||||||
ks_gard
|
ks_gard.find_kid(kid).ok_or_else(|| AuthError::InvalidKid(kid.to_owned()))?
|
||||||
.find_kid(kid)
|
|
||||||
.ok_or_else(|| AuthError::InvalidKid(kid.to_owned()))?
|
|
||||||
} else {
|
} else {
|
||||||
ks_gard
|
ks_gard.find_alg(&header.alg).ok_or(AuthError::InvalidKeyAlg(header.alg))?
|
||||||
.find_alg(&header.alg)
|
|
||||||
.ok_or(AuthError::InvalidKeyAlg(header.alg))?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -228,8 +217,8 @@ mod tests {
|
||||||
Mock, MockServer, ResponseTemplate,
|
Mock, MockServer, ResponseTemplate,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{RefreshStrategy, Refresh};
|
|
||||||
use crate::jwks::key_store_manager::{KeyStore, KeyStoreManager};
|
use crate::jwks::key_store_manager::{KeyStore, KeyStoreManager};
|
||||||
|
use crate::{Refresh, RefreshStrategy};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn keystore_should_refresh() {
|
fn keystore_should_refresh() {
|
||||||
|
|
@ -252,7 +241,6 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn keystore_can_refresh() {
|
fn keystore_can_refresh() {
|
||||||
|
|
||||||
// FAIL, NO LOAD
|
// FAIL, NO LOAD
|
||||||
let ks = KeyStore {
|
let ks = KeyStore {
|
||||||
jwks: jsonwebtoken::jwk::JwkSet { keys: vec![] },
|
jwks: jsonwebtoken::jwk::JwkSet { keys: vec![] },
|
||||||
|
|
@ -343,7 +331,11 @@ mod tests {
|
||||||
|
|
||||||
let ksm = KeyStoreManager::new(
|
let ksm = KeyStoreManager::new(
|
||||||
&mock_server.uri(),
|
&mock_server.uri(),
|
||||||
Refresh {strategy: RefreshStrategy::Interval, refresh_interval: Duration::from_secs(3000), ..Default::default()}
|
Refresh {
|
||||||
|
strategy: RefreshStrategy::Interval,
|
||||||
|
refresh_interval: Duration::from_secs(3000),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
);
|
);
|
||||||
let r = ksm.get_key(&Header::new(Algorithm::EdDSA)).await;
|
let r = ksm.get_key(&Header::new(Algorithm::EdDSA)).await;
|
||||||
assert!(r.is_ok());
|
assert!(r.is_ok());
|
||||||
|
|
@ -368,7 +360,11 @@ mod tests {
|
||||||
|
|
||||||
let mut ksm = KeyStoreManager::new(
|
let mut ksm = KeyStoreManager::new(
|
||||||
&mock_server.uri(),
|
&mock_server.uri(),
|
||||||
Refresh {strategy: RefreshStrategy::KeyNotFound, ..Default::default()});
|
Refresh {
|
||||||
|
strategy: RefreshStrategy::KeyNotFound,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
// STEP 1: initial (lazy) reloading
|
// STEP 1: initial (lazy) reloading
|
||||||
let r = ksm.get_key(&build_header("key-ed", Algorithm::EdDSA)).await;
|
let r = ksm.get_key(&build_header("key-ed", Algorithm::EdDSA)).await;
|
||||||
|
|
@ -440,7 +436,11 @@ mod tests {
|
||||||
|
|
||||||
let ksm = KeyStoreManager::new(
|
let ksm = KeyStoreManager::new(
|
||||||
&mock_server.uri(),
|
&mock_server.uri(),
|
||||||
Refresh {strategy: RefreshStrategy::NoRefresh, ..Default::default()});
|
Refresh {
|
||||||
|
strategy: RefreshStrategy::NoRefresh,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
// STEP 1: initial (lazy) reloading
|
// STEP 1: initial (lazy) reloading
|
||||||
let r = ksm.get_key(&build_header("key-ed", Algorithm::EdDSA)).await;
|
let r = ksm.get_key(&build_header("key-ed", Algorithm::EdDSA)).await;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use axum::body::BoxBody;
|
use axum::body::BoxBody;
|
||||||
use axum::http::Request;
|
use axum::http::Request;
|
||||||
use axum::response::{Response, IntoResponse};
|
use axum::response::{IntoResponse, Response};
|
||||||
use futures_core::ready;
|
use futures_core::ready;
|
||||||
use futures_util::future::BoxFuture;
|
use futures_util::future::BoxFuture;
|
||||||
use headers::authorization::Bearer;
|
use headers::authorization::Bearer;
|
||||||
|
|
@ -14,10 +14,10 @@ use std::task::{Context, Poll};
|
||||||
use tower_layer::Layer;
|
use tower_layer::Layer;
|
||||||
use tower_service::Service;
|
use tower_service::Service;
|
||||||
|
|
||||||
use crate::{AuthError, RefreshStrategy};
|
|
||||||
use crate::authorizer::{Authorizer, FnClaimsChecker, KeySourceType};
|
use crate::authorizer::{Authorizer, FnClaimsChecker, KeySourceType};
|
||||||
use crate::error::InitError;
|
use crate::error::InitError;
|
||||||
use crate::jwks::key_store_manager::Refresh;
|
use crate::jwks::key_store_manager::Refresh;
|
||||||
|
use crate::{AuthError, RefreshStrategy};
|
||||||
|
|
||||||
/// Authorizer Layer builder
|
/// Authorizer Layer builder
|
||||||
///
|
///
|
||||||
|
|
@ -118,11 +118,11 @@ where
|
||||||
KeySourceType::RSA(_) | KeySourceType::EC(_) | KeySourceType::ED(_) | KeySourceType::Secret(_) => {
|
KeySourceType::RSA(_) | KeySourceType::EC(_) | KeySourceType::ED(_) | KeySourceType::Secret(_) => {
|
||||||
Arc::new(Authorizer::from(key_source_type, self.claims_checker.clone())?)
|
Arc::new(Authorizer::from(key_source_type, self.claims_checker.clone())?)
|
||||||
}
|
}
|
||||||
KeySourceType::Jwks(url) => {
|
KeySourceType::Jwks(url) => Arc::new(Authorizer::from_jwks_url(
|
||||||
Arc::new(
|
url.as_str(),
|
||||||
Authorizer::from_jwks_url(
|
self.claims_checker.clone(),
|
||||||
url.as_str(), self.claims_checker.clone(), self.refresh.unwrap_or_default())?)
|
self.refresh.unwrap_or_default(),
|
||||||
}
|
)?),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(InitError::BuilderError(
|
return Err(InitError::BuilderError(
|
||||||
|
|
@ -162,16 +162,14 @@ where
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
if let Some(bearer) = bearer_o {
|
if let Some(bearer) = bearer_o {
|
||||||
match authorizer.check_auth(bearer.token()).await {
|
match authorizer.check_auth(bearer.token()).await {
|
||||||
Ok(token_data) => {
|
Ok(token_data) => {
|
||||||
// Set `token_data` as a request extension so it can be accessed by other
|
// Set `token_data` as a request extension so it can be accessed by other
|
||||||
// services down the stack.
|
// services down the stack.
|
||||||
request.extensions_mut().insert(token_data);
|
request.extensions_mut().insert(token_data);
|
||||||
|
|
||||||
Ok(request)
|
Ok(request)
|
||||||
},
|
|
||||||
Err(err) => {
|
|
||||||
Err(err.into_response())
|
|
||||||
}
|
}
|
||||||
|
Err(err) => Err(err.into_response()),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(AuthError::MissingToken().into_response())
|
Err(AuthError::MissingToken().into_response())
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ use jsonwebtoken::TokenData;
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
|
|
||||||
pub use self::error::AuthError;
|
pub use self::error::AuthError;
|
||||||
pub use layer::JwtAuthorizer;
|
|
||||||
pub use jwks::key_store_manager::{Refresh, RefreshStrategy};
|
pub use jwks::key_store_manager::{Refresh, RefreshStrategy};
|
||||||
|
pub use layer::JwtAuthorizer;
|
||||||
|
|
||||||
pub mod authorizer;
|
pub mod authorizer;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
max_width=120
|
max_width=125
|
||||||
Loading…
Add table
Add a link
Reference in a new issue