#http-request #security #http-client #web #http-response #api-client

mauth-client

Sign requests and validate responses using the Medidata MAuth protocol

5 releases (breaking)

new 0.5.0 Dec 10, 2024
0.4.0 Jun 11, 2024
0.3.0 Jan 4, 2024
0.2.0 Feb 17, 2023
0.1.0 Jan 19, 2021

#1858 in Web programming

Download history 2/week @ 2024-09-17 14/week @ 2024-09-24 1/week @ 2024-10-08

328 downloads per month

MIT license

39KB
695 lines

mauth-client

This crate allows users of the Reqwest crate for making HTTP requests to sign those requests with the MAuth protocol, and verify the responses. Usage example:

Note: This crate and Rust support within Medidata is considered experimental. Do not release any code to Production or deploy in a Client-accessible environment without getting approval for the full stack used through the Architecture and Security groups.

use mauth_client::MAuthInfo;
use reqwest::Client;
# async fn send_request() {
let mauth_info = MAuthInfo::from_default_file().unwrap();
let client = Client::new();
let mut req = client.get("https://www.example.com/").build().unwrap();
mauth_info.sign_request(&mut req);
match client.execute(req).await {
    Err(err) => println!("Got error {}", err),
    Ok(response) => println!("Got validated response with body {}", response.text().await.unwrap()),
}
# }

The above code will read your mauth configuration from a file in ~/.mauth_config.yml which format is:

common: &common
  mauth_baseurl: https://<URL of MAUTH SERVER>
  mauth_api_version: v1
  app_uuid: <YOUR APP UUID HERE>
  private_key_file: <PATH TO MAUTH KEY>

The MAuthInfo struct also functions as a outgoing middleware using the reqwest-middleware crate for a simpler API and easier integration with other outgoing middleware:

use mauth_client::MAuthInfo;
use reqwest::Client;
use reqwest_middleware::ClientBuilder;
# async fn send_request() {
let mauth_info = MAuthInfo::from_default_file().unwrap();
let client = ClientBuilder::new(Client::new()).with(mauth_info).build();
match client.get("https://www.example.com/").send().await {
    Err(err) => println!("Got error {}", err),
    Ok(response) => println!("Got validated response with body {}", response.text().await.unwrap()),
}
# }

The optional axum-service feature provides for a Tower Layer and Service that will authenticate incoming requests via MAuth V2 or V1 and provide to the lower layers a validated app_uuid from the request via the ValidatedRequestDetails struct.

There are also optional features tracing-otel-26 and tracing-otel-27 that pair with the axum-service feature to ensure that any outgoing requests for credentials that take place in the context of an incoming web request also include the proper OpenTelemetry span information in any requests to MAudit services. Note that it is critical to use the same version of OpenTelemetry crates as the rest of the project - if you do not, there will be 2 or more instances of the OpenTelemetry global information, and requests may not be traced through properly.

Dependencies

~17–33MB
~518K SLoC