Skip to content

Commit

Permalink
tracing: friendly name for spans
Browse files Browse the repository at this point in the history
Co-authored-by: Trong Huu Nguyen <trong.huu.nguyen@nav.no>
  • Loading branch information
kimtore and tronghn committed Nov 19, 2024
1 parent 3922e51 commit 7ed9dc7
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 15 deletions.
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ MASKINPORTEN_JWKS_URI=http://localhost:8080/maskinporten/jwks

AZURE_ENABLED=true
AZURE_APP_CLIENT_ID=client-id
AZURE_APP_CLIENT_JWK='{"p":"_LNnIjBshCrFuxtjUC2KKzg_NTVv26UZh5j12_9r5mYTxb8yW047jOYFEGvIdMkTRLGOBig6fLWzgd62lnLainzV35J6K6zr4jQfTldLondlkldMR6nQrp1KfnNUuRbKvzpNKkhl12-f1l91l0tCx3s4blztvWgdzN2xBfvWV68","kty":"RSA","q":"9MIWsbIA3WjiR_Ful5FM8NCgb6JdS2D6ySHVepoNI-iAPilcltF_J2orjfLqAxeztTskPi45wtF_-eV4GIYSzvMo-gFiXLMrvEa7WaWizMi_7Bu9tEk3m_f3IDLN9lwULYoebkDbiXx6GOiuj0VkuKz8ckYFNKLCMP9QRLFff-0","d":"J6UX848X8tNz-09PFvcFDUVqak32GXzoPjnuDjBsxNUvG7LxenLmM_i8tvYl0EW9Ztn4AiCqJUoHw5cX3jz_mSqGl7ciaDedpKm_AetcZwHiEuT1EpSKRPMmOMQSqcJqXrdbbWB8gdUrnTKZIlJCfj7yqgT16ypC43TnwjA0UwxhG5pHaYjKI3pPdoHg2BzA-iubHjVn15Sz7-pnjBmeGDbEFa7ADY-1yPHCmqqvPKTNhoCNW6RpG34Id9hXslPa3X-7pAhJrDBd0_NPlktSA2rUkifYiZURhHR5ijhe0v3uw6kYP8f_foVm_C8O1ExkxXh9Dg8KDZ89dbsSOtBc0Q","e":"AQAB","use":"sig","kid":"l7C_WJgbZ_6e59vPrFETAehX7Dsp7fIyvSV4XhotsGs","qi":"cQFN5q5WhYkzgd1RS0rGqvpX1AkmZMrLv2MW04gSfu0dDwpbsSAu8EUCQW9oA4pr6V7R9CBSu9kdN2iY5SR-hZvEad5nDKPV1F3TMQYv5KpRiS_0XhfV5PcolUJVO_4p3h8d-mo2hh1Sw2fairAKOzvnwJCQ6DFkiY7H1cqwA54","dp":"YTql9AGtvyy158gh7jeXcgmySEbHQzvDFulDr-IXIg8kjHGEbp0rTIs0Z50RA95aC5RFkRjpaBKBfvaySjDm5WIi6GLzntpp6B8l7H6qG1jVO_la4Df2kzjx8LVvY8fhOrKz_hDdHodUeKdCF3RdvWMr00ruLnJhBPJHqoW7cwE","alg":"RS256","dq":"IZA4AngRbEtEtG7kJn6zWVaSmZxfRMXwvgIYvy4-3Qy2AVA0tS3XTPVfMaD8_B2U9CY_CxPVseR-sysHc_12uNBZbycfcOzU84WTjXCMSZ7BysPnGMDtkkLHra-p1L29upz1HVNhh5H9QEswHM98R2LZX2ZAsn4bORLZ1AGqweU","n":"8ZqUp5Cs90XpNn8tJBdUUxdGH4bjqKjFj8lyB3x50RpTuECuwzX1NpVqyFENDiEtMja5fdmJl6SErjnhj6kbhcmfmFibANuG-0WlV5yMysdSbocd75C1JQbiPdpHdXrijmVFMfDnoZTQ-ErNsqqngTNkn5SXBcPenli6Cf9MTSchZuh_qFj_B7Fp3CWKehTiyBcLlNOIjYsXX8WQjZkWKGpQ23AWjZulngWRektLcRWuEKTWaRBtbAr3XAfSmcqTICrebaD3IMWKHDtvzHAt_pt4wnZ06clgeO2Wbc980usnpsF7g8k9p81RcbS4JEZmuuA9NCmOmbyADXwgA9_-Aw"}'
AZURE_APP_JWK='{"p":"_LNnIjBshCrFuxtjUC2KKzg_NTVv26UZh5j12_9r5mYTxb8yW047jOYFEGvIdMkTRLGOBig6fLWzgd62lnLainzV35J6K6zr4jQfTldLondlkldMR6nQrp1KfnNUuRbKvzpNKkhl12-f1l91l0tCx3s4blztvWgdzN2xBfvWV68","kty":"RSA","q":"9MIWsbIA3WjiR_Ful5FM8NCgb6JdS2D6ySHVepoNI-iAPilcltF_J2orjfLqAxeztTskPi45wtF_-eV4GIYSzvMo-gFiXLMrvEa7WaWizMi_7Bu9tEk3m_f3IDLN9lwULYoebkDbiXx6GOiuj0VkuKz8ckYFNKLCMP9QRLFff-0","d":"J6UX848X8tNz-09PFvcFDUVqak32GXzoPjnuDjBsxNUvG7LxenLmM_i8tvYl0EW9Ztn4AiCqJUoHw5cX3jz_mSqGl7ciaDedpKm_AetcZwHiEuT1EpSKRPMmOMQSqcJqXrdbbWB8gdUrnTKZIlJCfj7yqgT16ypC43TnwjA0UwxhG5pHaYjKI3pPdoHg2BzA-iubHjVn15Sz7-pnjBmeGDbEFa7ADY-1yPHCmqqvPKTNhoCNW6RpG34Id9hXslPa3X-7pAhJrDBd0_NPlktSA2rUkifYiZURhHR5ijhe0v3uw6kYP8f_foVm_C8O1ExkxXh9Dg8KDZ89dbsSOtBc0Q","e":"AQAB","use":"sig","kid":"l7C_WJgbZ_6e59vPrFETAehX7Dsp7fIyvSV4XhotsGs","qi":"cQFN5q5WhYkzgd1RS0rGqvpX1AkmZMrLv2MW04gSfu0dDwpbsSAu8EUCQW9oA4pr6V7R9CBSu9kdN2iY5SR-hZvEad5nDKPV1F3TMQYv5KpRiS_0XhfV5PcolUJVO_4p3h8d-mo2hh1Sw2fairAKOzvnwJCQ6DFkiY7H1cqwA54","dp":"YTql9AGtvyy158gh7jeXcgmySEbHQzvDFulDr-IXIg8kjHGEbp0rTIs0Z50RA95aC5RFkRjpaBKBfvaySjDm5WIi6GLzntpp6B8l7H6qG1jVO_la4Df2kzjx8LVvY8fhOrKz_hDdHodUeKdCF3RdvWMr00ruLnJhBPJHqoW7cwE","alg":"RS256","dq":"IZA4AngRbEtEtG7kJn6zWVaSmZxfRMXwvgIYvy4-3Qy2AVA0tS3XTPVfMaD8_B2U9CY_CxPVseR-sysHc_12uNBZbycfcOzU84WTjXCMSZ7BysPnGMDtkkLHra-p1L29upz1HVNhh5H9QEswHM98R2LZX2ZAsn4bORLZ1AGqweU","n":"8ZqUp5Cs90XpNn8tJBdUUxdGH4bjqKjFj8lyB3x50RpTuECuwzX1NpVqyFENDiEtMja5fdmJl6SErjnhj6kbhcmfmFibANuG-0WlV5yMysdSbocd75C1JQbiPdpHdXrijmVFMfDnoZTQ-ErNsqqngTNkn5SXBcPenli6Cf9MTSchZuh_qFj_B7Fp3CWKehTiyBcLlNOIjYsXX8WQjZkWKGpQ23AWjZulngWRektLcRWuEKTWaRBtbAr3XAfSmcqTICrebaD3IMWKHDtvzHAt_pt4wnZ06clgeO2Wbc980usnpsF7g8k9p81RcbS4JEZmuuA9NCmOmbyADXwgA9_-Aw"}'
AZURE_OPENID_CONFIG_ISSUER=http://localhost:8080/azuread
AZURE_OPENID_CONFIG_TOKEN_ENDPOINT=http://localhost:8080/azuread/token
AZURE_OPENID_CONFIG_JWKS_URI=http://localhost:8080/azuread/jwks
Expand Down
2 changes: 1 addition & 1 deletion src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ impl App {
let parent_context = propagator.extract(&HeaderExtractor(request.headers()));

let root_span = info_span!(
"http_request",
"Handle incoming request",
method = ?request.method(),
path,
);
Expand Down
7 changes: 4 additions & 3 deletions src/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ use tracing::instrument;
(status = INTERNAL_SERVER_ERROR, description = "Server error", body = ErrorResponse, content_type = "application/json"),
)
)]
#[instrument(skip_all)]
#[instrument(skip_all, name = "Handle /api/v1/token")]
pub async fn token(State(state): State<HandlerState>, JsonOrForm(request): JsonOrForm<TokenRequest>) -> Result<impl IntoResponse, ApiError> {
for provider in state.providers {
if !provider.read().await.should_handle_token_request(&request) {
Expand Down Expand Up @@ -102,7 +102,7 @@ pub async fn token(State(state): State<HandlerState>, JsonOrForm(request): JsonO
(status = INTERNAL_SERVER_ERROR, description = "Server error", body = ErrorResponse, content_type = "application/json"),
)
)]
#[instrument(skip_all)]
#[instrument(skip_all, name = "Handle /api/v1/token/exchange")]
pub async fn token_exchange(State(state): State<HandlerState>, JsonOrForm(request): JsonOrForm<TokenExchangeRequest>) -> Result<impl IntoResponse, ApiError> {
for provider in state.providers {
if !provider.read().await.should_handle_token_exchange_request(&request) {
Expand Down Expand Up @@ -152,7 +152,7 @@ pub async fn token_exchange(State(state): State<HandlerState>, JsonOrForm(reques
),
)
)]
#[instrument(skip_all)]
#[instrument(skip_all, name = "Handle /api/v1/introspect")]
pub async fn introspect(State(state): State<HandlerState>, JsonOrForm(request): JsonOrForm<IntrospectRequest>) -> Result<impl IntoResponse, Json<IntrospectResponse>> {
for provider in state.providers {
if !provider.read().await.should_handle_introspect_request(&request) {
Expand Down Expand Up @@ -293,6 +293,7 @@ where
{
type Rejection = ApiError;

#[instrument(skip_all, name = "Deserialize request")]
async fn from_request(req: axum::extract::Request, state: &S) -> Result<Self, Self::Rejection> {
let content_type_header = req.headers().get(CONTENT_TYPE);
let content_type = content_type_header.and_then(|value| value.to_str().ok());
Expand Down
17 changes: 9 additions & 8 deletions src/identity_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ pub struct Provider<R, A> {
private_jwk: Option<jwt::EncodingKey>,
client_assertion_header: Option<jwt::Header>,
upstream_jwks: jwks::Jwks,
http_client: reqwest::Client,
_fake_request: PhantomData<R>,
_fake_assertion: PhantomData<A>,
}
Expand Down Expand Up @@ -295,14 +296,15 @@ where
token_endpoint,
client_assertion_header,
upstream_jwks,
http_client: reqwest::Client::default(),
identity_provider_kind: kind,
private_jwk: client_private_jwk,
_fake_request: Default::default(),
_fake_assertion: Default::default(),
})
}

#[instrument(skip_all)]
#[instrument(skip_all, name = "Create assertion for token signing request")]
fn create_assertion(&self, target: String) -> Option<String> {
let assertion = A::new(self.token_endpoint.as_ref()?.clone(), self.client_id.clone(), target);
serialize(assertion, self.client_assertion_header.as_ref()?, self.private_jwk.as_ref()?).ok()
Expand All @@ -323,7 +325,7 @@ where
client_id: Some(self.client_id.clone()),
user_token: None,
};
self.get_token_with_config(token_request).await
self.get_token_from_idprovider(token_request).await
}

async fn exchange_token(&self, request: TokenExchangeRequest) -> Result<TokenResponse, ApiError> {
Expand All @@ -333,19 +335,18 @@ where
client_id: Some(self.client_id.clone()),
user_token: Some(request.user_token),
};
self.get_token_with_config(token_request).await
self.get_token_from_idprovider(token_request).await
}

async fn introspect(&mut self, token: String) -> IntrospectResponse {
self.upstream_jwks.validate(&token).await.map(IntrospectResponse::new).unwrap_or_else(IntrospectResponse::new_invalid)
}

#[instrument(skip_all)]
async fn get_token_with_config(&self, config: TokenRequestBuilderParams) -> Result<TokenResponse, ApiError> {
#[instrument(skip_all, name = "Request token from upstream identity provider")]
async fn get_token_from_idprovider(&self, config: TokenRequestBuilderParams) -> Result<TokenResponse, ApiError> {
let params = R::token_request(config).ok_or(ApiError::Sign)?;

let client = reqwest::Client::new();
let response = client
let response = self.http_client
.post(self.token_endpoint.clone().ok_or(ApiError::TokenRequestUnsupported(self.identity_provider_kind))?)
.header("accept", "application/json")
.form(&params)
Expand Down Expand Up @@ -374,7 +375,7 @@ pub trait ProviderHandler: ShouldHandler + Send + Sync {
async fn get_token(&self, request: TokenRequest) -> Result<TokenResponse, ApiError>;
async fn exchange_token(&self, request: TokenExchangeRequest) -> Result<TokenResponse, ApiError>;
async fn introspect(&mut self, token: String) -> IntrospectResponse;
async fn get_token_with_config(&self, config: TokenRequestBuilderParams) -> Result<TokenResponse, ApiError>;
async fn get_token_from_idprovider(&self, config: TokenRequestBuilderParams) -> Result<TokenResponse, ApiError>;
}
pub trait ShouldHandler: Send + Sync {
fn should_handle_token_request(&self, _request: &TokenRequest) -> bool {
Expand Down
4 changes: 2 additions & 2 deletions src/jwks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ impl Jwks {
}

/// Pull a new version of the JWKS from the original endpoint.
#[instrument(skip_all)]
#[instrument(skip_all, name="Refresh JWKS")]
pub async fn refresh(&mut self) -> Result<(), Error> {
let new_jwks = Self::new(&self.issuer, &self.endpoint, self.required_audience.clone()).await?;
self.keys = new_jwks.keys;
Expand All @@ -90,7 +90,7 @@ impl Jwks {
/// Check a JWT against a JWKS.
/// Returns the JWT's claims on success.
/// May update the list of signing keys if the key ID is not found.
#[instrument(skip_all)]
#[instrument(skip_all, name="Validate token signature and claims")]
pub async fn validate(&mut self, token: &str) -> Result<HashMap<String, Value>, Error> {
let key_id = jwt::decode_header(token).map_err(Error::InvalidTokenHeader)?.kid.ok_or(Error::MissingKeyIDInTokenHeader)?;

Expand Down

0 comments on commit 7ed9dc7

Please sign in to comment.