1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-08-07 17:03:01 +03:00

Restore jwks_uri fetching

This commit is contained in:
Quentin Gliech
2022-04-22 15:28:43 +02:00
parent 687c2a97b8
commit 374669fa7d
3 changed files with 40 additions and 7 deletions

3
Cargo.lock generated
View File

@@ -1950,8 +1950,10 @@ dependencies = [
"futures-util", "futures-util",
"headers", "headers",
"http", "http",
"http-body",
"mas-config", "mas-config",
"mas-data-model", "mas-data-model",
"mas-http",
"mas-iana", "mas-iana",
"mas-jose", "mas-jose",
"mas-storage", "mas-storage",
@@ -1965,6 +1967,7 @@ dependencies = [
"sqlx", "sqlx",
"thiserror", "thiserror",
"tokio", "tokio",
"tower",
"tracing", "tracing",
"url", "url",
] ]

View File

@@ -15,6 +15,7 @@ data-encoding = "2.3.2"
futures-util = "0.3.21" futures-util = "0.3.21"
headers = "0.3.7" headers = "0.3.7"
http = "0.2.6" http = "0.2.6"
http-body = "0.4.4"
mime = "0.3.16" mime = "0.3.16"
rand = "0.8.5" rand = "0.8.5"
serde = "1.0.136" serde = "1.0.136"
@@ -24,6 +25,7 @@ serde_json = "1.0.79"
sqlx = "0.5.13" sqlx = "0.5.13"
thiserror = "1.0.30" thiserror = "1.0.30"
tokio = "1.17.0" tokio = "1.17.0"
tower = { version = "0.4.12", features = ["util"] }
tracing = "0.1.34" tracing = "0.1.34"
url = "2.2.2" url = "2.2.2"
@@ -34,5 +36,4 @@ mas-storage = { path = "../storage" }
mas-data-model = { path = "../data-model" } mas-data-model = { path = "../data-model" }
mas-jose = { path = "../jose" } mas-jose = { path = "../jose" }
mas-iana = { path = "../iana" } mas-iana = { path = "../iana" }
mas-http = { path = "../http" }
[features]

View File

@@ -22,15 +22,17 @@ use axum::{
Form, FromRequest, RequestParts, TypedHeader, Form, FromRequest, RequestParts, TypedHeader,
}, },
response::IntoResponse, response::IntoResponse,
BoxError,
}; };
use headers::{authorization::Basic, Authorization}; use headers::{authorization::Basic, Authorization};
use http::StatusCode; use http::StatusCode;
use mas_config::Encrypter; use mas_config::Encrypter;
use mas_data_model::{Client, JwksOrJwksUri, StorageBackend}; use mas_data_model::{Client, JwksOrJwksUri, StorageBackend};
use mas_http::HttpServiceExt;
use mas_iana::oauth::OAuthClientAuthenticationMethod; use mas_iana::oauth::OAuthClientAuthenticationMethod;
use mas_jose::{ use mas_jose::{
DecodedJsonWebToken, DynamicJwksStore, Either, JsonWebTokenParts, JwtHeader, SharedSecret, DecodedJsonWebToken, DynamicJwksStore, Either, JsonWebKeySet, JsonWebTokenParts, JwtHeader,
StaticJwksStore, SharedSecret, StaticJwksStore, VerifyingKeystore,
}; };
use mas_storage::{ use mas_storage::{
oauth2::client::{lookup_client_by_client_id, ClientFetchError}, oauth2::client::{lookup_client_by_client_id, ClientFetchError},
@@ -40,6 +42,7 @@ use serde::{de::DeserializeOwned, Deserialize};
use serde_json::Value; use serde_json::Value;
use sqlx::PgExecutor; use sqlx::PgExecutor;
use thiserror::Error; use thiserror::Error;
use tower::ServiceExt;
static JWT_BEARER_CLIENT_ASSERTION: &str = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"; static JWT_BEARER_CLIENT_ASSERTION: &str = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer";
@@ -169,10 +172,36 @@ impl Credentials {
} }
fn jwks_key_store(jwks: &JwksOrJwksUri) -> Either<StaticJwksStore, DynamicJwksStore> { fn jwks_key_store(jwks: &JwksOrJwksUri) -> Either<StaticJwksStore, DynamicJwksStore> {
match jwks { // Assert that the output is both a VerifyingKeystore and Send
JwksOrJwksUri::Jwks(key_set) => Either::Left(StaticJwksStore::new(key_set.clone())), fn assert<T: Send + VerifyingKeystore>(t: T) -> T {
JwksOrJwksUri::JwksUri(_uri) => todo!(), t
} }
let inner = match jwks {
JwksOrJwksUri::Jwks(jwks) => Either::Left(StaticJwksStore::new(jwks.clone())),
JwksOrJwksUri::JwksUri(uri) => {
let uri = uri.clone();
// TODO: get the client from somewhere else?
let exporter = mas_http::client("fetch-jwks")
.json::<JsonWebKeySet>()
.map_request(move |_: ()| {
http::Request::builder()
.method("GET")
// TODO: change the Uri type in config to avoid reparsing here
.uri(uri.to_string())
.body(http_body::Empty::new())
.unwrap()
})
.map_response(http::Response::into_body)
.map_err(BoxError::from)
.boxed_clone();
Either::Right(DynamicJwksStore::new(exporter))
}
};
assert(inner)
} }
#[derive(Debug, Error)] #[derive(Debug, Error)]