Skip to content

Failes with BAD_REQUEST when Authorization header contains Basic #4

@mickem

Description

@mickem

Hello,

I am trying to achieve both basic authentication and jwt authentication.
And my idea for this was to have two middlewares one capturing basic and one capturing bearer.

This does not work because the following function:

req.headers().typed_try_get::<Authorization<Bearer>>()

Does not try to get the "bearer Authorization header", instead it tries to get the Authorization header (regardless of what it is) and then parses that assuming it is a Bearer token which will fail when we have an Authorization Basic header and instead return BAD_REQUEST.

So in effect the JWT layer fails with BAD_REQUEST on a header containing "Authorization: Basic" which makes it impossible to use in conjunction with an additional middle ware acting on the Authorization header.

Not sure if this is a bug or an intended behaviour, but as the middleware allows requests without Authorization header through I assume it is a bug.

An easy fix for this would be to manually check the header like so (pseudo code):

        if let Some(header) = req.headers().get(AUTHORIZATION) {
            if let Ok(header_string) = header.to_str() {
                if header_string.starts_with("Bearer ") {
                    let bearer = match Bearer::decode(header) {
                        Some(bearer) => bearer,
                        None => {
                            return Self::Future::Error;
                        }
                    };
                    let decoding_key_fn = self.decoding_key_fn.clone();
                    let decoding_key_future =
                        Box::pin(async move { decoding_key_fn.decoding_key().await });
                    return Self::Future::HasTokenWaitingForDecodingKey {
                        bearer,
                        request: req,
                        decoding_key_future,
                        validation: self.validation.clone(),
                        service: self.inner.clone(),
                        _phantom: self._phantom,
                    };
                }
            }
        }
        let future = self.inner.call(req);
        Self::Future::WaitForFuture { future }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions