Small crate to extend `reqwest` to be able to send with digest auth flow.

Overview

diqwest

This crate extends reqwest to be able to send requests with digest auth flow.

It is currently implemented for async usage only.

When you send the request with digest auth flow this first request will be executed. In case the response is a 401 the www-authenticate header is parsed and the answer is calculated. The initial request is executed again with additional Authorization header. The response will be returned from send_with_digest_auth().

In case the first response is not a 401 this first response is returned from send_with_digest_auth() without any manipulation.

Example

use diqwest::core::WithDigestAuth;
use reqwest::{Client, Response};

// Call `.send_with_digest_auth()` on `RequestBuilder` like `send()`
let response: Response = Client::new()
  .get("url")
  .send_with_digest_auth("username", "password")
  .await?;
Comments
  • Fails if username/password is defined in url

    Fails if username/password is defined in url

    In reqwest, when username/password is provided in url, it seems to use basic authentication. Something like this:

    http://user:pass@host:port/path
    

    My idea was to use .send_with_digest_authentication() using such an url, that way the authentication method would be "automatic":

    • If endpoint was basic, then first response would be OK
    • If endpoint was digest, then second request should do it

    ~~Problem is, reqwest seems to fallback to basic auth because of the user/pass in the url. I tried to patch diqwest in a fork to make sure username/pass are removed for the second request, but it seems that there is no way to access the url from RequestBuilder.~~

    ~~The only way that I can think of this working, is that response from RequestBuilder::build is used. But that needs access to Client::execute.~~

    ~~I don't know if solving this issue is in the scope of this crate, but an automatic authentication process would be a nice to have. Maybe there is another approach?~~

    opened by rcastill 1
  • Bad requests due to full request URI in Authorization header

    Bad requests due to full request URI in Authorization header

    Hi,

    I was not able to get diqwest to successfully work against an embedded device with an HTTP server that requires digest authentication. I was able to get it to work with curl --digest, so I compared the requests generated by curl vs. those generated by reqwest+diqwest.

    It turns out curl generates an Authorization header that looks like:

    Authorization: Digest username="...", realm="...", nonce="...", uri="/cgi-bin/egauge-show?c&T=1639976400,1642654800", cnonce="...", nc=00000001, qop=auth, response="..."
    

    while reqwest+diqwest generates an Authorization header that looks like:

    authorization: Digest username="...", realm="...", nonce="...", uri="http://100.100.0.208/cgi-bin/egauge-show?c&T=1639976400,1642654800", qop=auth, nc=00000001, cnonce="...", response="...", algorithm=MD5
    

    I was able to get diqwest to generate an Authorization header closer to what curl generates with something like this:

    diff --git a/src/core.rs b/src/core.rs
    index 14d714a..2c2e9f5 100644
    --- a/src/core.rs
    +++ b/src/core.rs
    @@ -25,11 +25,24 @@ impl WithDigestAuth for RequestBuilder {
         match first_response.status() {
           StatusCode::UNAUTHORIZED => {
             let request = clone_request_builder(self)?.build()?;
    -        let url = request.url();
    +        let full_url = request.url();
             let method = HttpMethod::from(request.method().as_str());
             let body = request.body().and_then(|b| b.as_bytes());
    -        let answer =
    -          DigestAuthHelper::parse_digest_auth_header(first_response, url.as_str(), method, body, username, password)?;
    +
    +        let mut base_url = full_url.clone();
    +        match base_url.path_segments_mut() {
    +          Ok(mut path) => {
    +            path.clear();
    +          }
    +          Err(_) => {}
    +        }
    +
    +        let url = format!(
    +          "/{}",
    +          base_url.make_relative(&full_url).ok_or(RequestBuilderNotCloneableError)?
    +        );
    +
    +        let answer = DigestAuthHelper::parse_digest_auth_header(first_response, &url, method, body, username, password)?;
     
             Ok(clone_request_builder(self)?.header("Authorization", answer).send().await?)
           }
    

    Is this a bug in diqwest?

    Thanks!

    opened by edmonds 1
  • Added rustls-tls feature export

    Added rustls-tls feature export

    In our use case, we prefer rustls-tls in order to be able to easily cross-compile to targets using static compilation (musl)

    This could be useful for other users

    opened by rcastill 0
  • Establish blocking mode

    Establish blocking mode

    This PR marks a breaking change by establishing a blocking mode as a non default feature (enable it with blocking flag in your Cargo.toml). The package structure changed  so the version upped by one on the major digit.

    The feature is tested in async as well as blocking mode.

    opened by maoertel 0
  • Remove previous Authorization header

    Remove previous Authorization header

    I have the following use-case:

    User gives authenticated url. Something like this: http://user:pass@host:port/path

    If request is submitted with such an Url with reqwest, it will automatically form the "Authorization" header, assuming it's basic authentication.

    The idea is to be able to "automatically detect" if it is basic auth or digest auth.

    In order to implement this, send_with_digest_auth() could remove any previous "Authorization" headers set. But I'm not sure if this is possible. Maybe reqwest adds the header after send_with_digest_auth() acts.

    Is this even something that diqwest should handle?

    Maybe this issue can be brought to reqwest itself?

    opened by rcastill 0
Releases(v1.1.0)
Owner
Mathias Oertel
born, learn, riot, develop
Mathias Oertel
An auth system/library for Rust applications

Rust : Forbidden (WIP) An experimental auth library for Rust applications. Goals This crate is to define a common set of traits and idioms to provide

Mario Montoya 9 Nov 8, 2022
Command line login for SRun Auth Gateway

SRun Login for Rust Command line login for SRun Auth Gateway. Usage ./srun_login AUTH_GW_ENDPOINT AC_ID LOCAL_IP USERNAME PASSWORD eg: ./srun_login "h

lookas 1 Oct 20, 2021
High-level http auth extractors for axum

High-level http auth extractors for axum

Owez 44 Dec 23, 2022
Xbox live authentication flow for Minecraft with Rust.

MC Auth Xbox live authentication flow for Minecraft in Rust. Why? In order to create tools for Minecraft based on rust that implement the user profile

Minecraft Rust 3 Jan 15, 2023
Simple crate to login to Pinterest and get the cookies via Chromiumoxide to simulate a browser

Simple crate to login to Pinterest and get the cookies via Chromiumoxide to simulate a browser (open a real browser actually), to use the Pinterest API without needing a developer account or an API key or anything that costs money :).

Anas 3 Oct 5, 2023
flow-rust-sdk utilizes the Flow gRPC AccessAPI to make requests on the flow blockchain.

Welcome to the Flow-Rust-SDK! We're glad to have you here. There are a few important items that we should cover real quick before you dive in. Version

null 8 Jul 26, 2022
Rust library for HTTP authentication. Parses challenge lists, responds to Basic and Digest challenges. Likely to be extended with server support and additional auth schemes.

Rust library for HTTP authentication. Parses challenge lists, responds to Basic and Digest challenges. Likely to be extended with server support and a

Scott Lamb 3 Jun 10, 2022
zenoh-flow aims at providing a zenoh-based data-flow programming framework for computations that span from the cloud to the device.

Eclipse Zenoh-Flow Zenoh-Flow provides a zenoh-based dataflow programming framework for computations that span from the cloud to the device. ⚠️ This s

null 35 Dec 12, 2022
Rust crate to extend io::Read & io::Write types with progress callbacks

progress-streams Rust crate to provide progress callbacks for types which implement io::Read or io::Write. Examples Reader extern crate progress_strea

Pop!_OS 19 Dec 3, 2022
Expose various non-cryptographic hashing functions with Digest traits

noncrypto-digests Expose various non-cryptographic hashing functions with Digest traits. This allows users to use any hashing function with the same t

Yuri Astrakhan 3 Dec 9, 2023
Zenith - sort of like top or htop but with zoom-able charts, CPU, GPU, network, and disk usage

Zenith - sort of like top or htop but with zoom-able charts, CPU, GPU, network, and disk usage

Benjamin Vaisvil 1.6k Jan 4, 2023
Quickly mint NFT(able)s port forwards remotely

Easy expose A really simple way to expose some service behind a NAT, similar to rathole and frp. WARNING: This does not secure the channel, or even do

Ben Simms 3 Dec 3, 2022
Extend anything with WebAssembly.

Welcome! Please note: this project still under active development. It's usable, but expect some rough edges while work is underway. If you're interest

Extism 1.5k Jan 3, 2023
Mequeue is an executor for MEV bots optimized to be able to process multiple transactions concurrently.

Mequeue Mequeue is an executor for MEV bots optimized to be able to process multiple transactions concurrently. The main goal is to make this executor

null 13 Oct 3, 2023
zink! is a library for developing ink! smart contracts with useful Rust macros that extend functionality and reduce boilerplate code.

zink! Smart Contract Macros This is a helper library for developing ink! smart contracts. It contains useful Rust macros that extend functionality and

Scio Labs 3 Nov 3, 2023
A small unofficial library to send emails using Sendgrid.

sendgrid_thin A thin wrapper around the SendGrid V3 API. It does not use the crate tokio or hyper and is therefore very lightweight and do not interfe

Reinaldo Rozato Junior 3 Nov 17, 2022
This crate allows you to send cypher queries to the REST endpoint of a neo4j database

rusted_cypher Rust crate for accessing the cypher endpoint of a neo4j server This crate allows you to send cypher queries to the REST endpoint of a ne

Livio Ribeiro 68 Dec 1, 2022
Wrapper around reqwest to allow for client middleware chains.

reqwest-middleware A crate implementing a wrapper around reqwest to allow for client middleware chains. Overview The reqwest-middleware client exposes

TrueLayer 113 Dec 7, 2022
An API for getting questions from http://either.io implemented fully in Rust, using reqwest and some regex magic. Provides asynchronous and blocking clients respectively.

eithers_rust An API for getting questions from http://either.io implemented fully in Rust, using reqwest and some regex magic. Provides asynchronous a

null 2 Oct 24, 2021
HTTP microservice using Axum and Reqwest to request the Google Translate TTS endpoint without rate limits

HTTP microservice using Axum and Reqwest to request the Google Translate TTS endpoint without rate limits

Gnome! 5 Oct 5, 2022