actix_web_security/authentication/scheme/bearer/jwt/
header_extractor.rs

1//! A default implementation of a authentication extractor for bearer token based authentication.
2
3use actix_web::http::{header, HeaderMap, HeaderValue};
4use async_trait::async_trait;
5use serde::Deserialize;
6
7use crate::authentication::error::error_type::AuthenticationError;
8use crate::authentication::scheme::authentication::Authentication;
9use crate::authentication::scheme::bearer::jwt::token::decoder::TokenDecoder;
10use crate::authentication::scheme::bearer::jwt::{Claims, JwtBearerAuthentication};
11use crate::authentication::scheme::header_extractor::{
12    extract_auth_header, AuthorizationHeaderExtractor,
13};
14
15/// The definition of a `BearerAuthenticationExtractor`. The authentication extractor
16/// extracts the authentication information from the authorization header and decodes
17/// the token to be used in the user authentication using a token decoder.
18#[derive(Clone)]
19pub struct BearerAuthenticationExtractor<T: for<'b> Deserialize<'b> + Claims> {
20    pub token_decoders: Vec<Box<dyn TokenDecoder<T>>>,
21}
22
23impl<T: for<'b> Deserialize<'b> + Claims> BearerAuthenticationExtractor<T> {
24    /// Constructs a new instance for a given vector of boxed `TokenDecoder` instances.
25    pub fn new(token_decoders: Vec<Box<dyn TokenDecoder<T>>>) -> BearerAuthenticationExtractor<T> {
26        BearerAuthenticationExtractor { token_decoders }
27    }
28
29    fn extract_bearer(&self, header: &HeaderValue) -> Result<String, AuthenticationError> {
30        extract_auth_header(header, "Bearer", 8)
31    }
32}
33
34#[async_trait]
35impl<T: for<'b> Deserialize<'b> + Claims> AuthorizationHeaderExtractor
36    for BearerAuthenticationExtractor<T>
37{
38    async fn extract_token(
39        &self,
40        headers: &HeaderMap,
41    ) -> Result<Box<dyn Authentication>, AuthenticationError> {
42        let authorization_header = headers.get(header::AUTHORIZATION);
43        match authorization_header {
44            Some(header_value) => match self.extract_bearer(header_value) {
45                Ok(extracted_token) => {
46                    for decoder in &self.token_decoders {
47                        if let Ok(decoded_token) = decoder.decode_token(&extracted_token) {
48                            return Ok(Box::new(JwtBearerAuthentication {
49                                token: decoded_token,
50                            }));
51                        }
52                    }
53                    Err(AuthenticationError::InvalidAuthentication)
54                }
55                Err(error) => Err(error),
56            },
57            None => Err(AuthenticationError::AuthorizationHeaderNotSet),
58        }
59    }
60}