actix_web_security/authentication/scheme/basic/
header_extractor.rs

1//! A default implementation of a authentication extractor for basic authentication.
2
3use actix_web::http::{header, HeaderMap, HeaderValue};
4use async_trait::async_trait;
5
6use crate::authentication::error::error_type::AuthenticationError;
7use crate::authentication::scheme::authentication::Authentication;
8use crate::authentication::scheme::basic::BasicAuthentication;
9use crate::authentication::scheme::header_extractor::{
10    extract_auth_header, AuthorizationHeaderExtractor,
11};
12
13/// The definition of a `BasicAuthenticationExtractor`. The authentication extractor
14/// extracts the authentication information from the authorization header and decodes
15/// the user credentials to be used in the user authentication.
16#[derive(Clone)]
17pub struct BasicAuthenticationExtractor {}
18
19impl BasicAuthenticationExtractor {
20    /// Constructs a new instance of `BasicAuthenticationExtractor`.
21    pub fn new() -> BasicAuthenticationExtractor {
22        BasicAuthenticationExtractor {}
23    }
24
25    fn extract_basic(
26        &self,
27        header: &HeaderValue,
28    ) -> Result<BasicAuthentication, AuthenticationError> {
29        let token = extract_auth_header(header, "Basic", 7)?;
30
31        // Decode the token
32        if let Ok(decoded) = base64::decode(token) {
33            let decoded_str = std::str::from_utf8(&decoded);
34            if let Ok(credentials_str) = decoded_str {
35                let mut credentials = credentials_str.splitn(2, ':');
36
37                let username = credentials
38                    .next()
39                    .ok_or(AuthenticationError::InvalidAuthorizationHeader)?
40                    .to_string();
41
42                let password = credentials
43                    .next()
44                    .ok_or(AuthenticationError::InvalidAuthorizationHeader)?
45                    .to_string();
46
47                return Ok(BasicAuthentication { username, password });
48            }
49        }
50
51        Err(AuthenticationError::InvalidAuthorizationHeader)
52    }
53}
54
55impl Default for BasicAuthenticationExtractor {
56    fn default() -> Self {
57        Self::new()
58    }
59}
60
61#[async_trait]
62impl AuthorizationHeaderExtractor for BasicAuthenticationExtractor {
63    async fn extract_token(
64        &self,
65        headers: &HeaderMap,
66    ) -> Result<Box<dyn Authentication>, AuthenticationError> {
67        let authorization_header = headers.get(header::AUTHORIZATION);
68        let header_value =
69            authorization_header.ok_or(AuthenticationError::AuthorizationHeaderNotSet)?;
70        Ok(Box::new(self.extract_basic(header_value)?))
71    }
72}