1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-30 10:32:55 +01:00

fix: broken stream when authentication failed (#260)

* fix: broken http stream when authentication failed

Signed-off-by: Roland Ma <rolandma@outlook.com>

* remove unchanged

Signed-off-by: Roland Ma <rolandma@outlook.com>

* Update CHANGES.md

* Update CHANGES.md

* Update CHANGES.md

Co-authored-by: Rob Ede <robjtede@icloud.com>
This commit is contained in:
Roland 2022-07-19 08:40:01 +08:00 committed by GitHub
parent 553c2bfb92
commit 417c06b00e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 28 additions and 19 deletions

View File

@ -1,8 +1,11 @@
# Changes # Changes
## Unreleased - 2022-xx-xx ## Unreleased - 2022-xx-xx
- Auth validator functions now need to return `(Error, ServiceRequest)` in error cases. [#260]
- Minimum supported Rust version (MSRV) is now 1.57 due to transitive `time` dependency. - Minimum supported Rust version (MSRV) is now 1.57 due to transitive `time` dependency.
[#260]: https://github.com/actix/actix-extras/pull/260
## 0.6.0 - 2022-03-01 ## 0.6.0 - 2022-03-01
- Update `actix-web` dependency to `4`. - Update `actix-web` dependency to `4`.

View File

@ -3,7 +3,10 @@ use actix_web::{middleware, web, App, Error, HttpServer};
use actix_web_httpauth::extractors::basic::BasicAuth; use actix_web_httpauth::extractors::basic::BasicAuth;
use actix_web_httpauth::middleware::HttpAuthentication; use actix_web_httpauth::middleware::HttpAuthentication;
async fn validator(req: ServiceRequest, _credentials: BasicAuth) -> Result<ServiceRequest, Error> { async fn validator(
req: ServiceRequest,
_credentials: BasicAuth,
) -> Result<ServiceRequest, (Error, ServiceRequest)> {
Ok(req) Ok(req)
} }

View File

@ -5,7 +5,7 @@ use actix_web_httpauth::{extractors::bearer::BearerAuth, middleware::HttpAuthent
async fn ok_validator( async fn ok_validator(
req: ServiceRequest, req: ServiceRequest,
credentials: BearerAuth, credentials: BearerAuth,
) -> Result<ServiceRequest, Error> { ) -> Result<ServiceRequest, (Error, ServiceRequest)> {
eprintln!("{:?}", credentials); eprintln!("{:?}", credentials);
Ok(req) Ok(req)
} }

View File

@ -39,7 +39,7 @@ impl<T, F, O> HttpAuthentication<T, F>
where where
T: AuthExtractor, T: AuthExtractor,
F: Fn(ServiceRequest, T) -> O, F: Fn(ServiceRequest, T) -> O,
O: Future<Output = Result<ServiceRequest, Error>>, O: Future<Output = Result<ServiceRequest, (Error, ServiceRequest)>>,
{ {
/// Construct `HttpAuthentication` middleware with the provided auth extractor `T` and /// Construct `HttpAuthentication` middleware with the provided auth extractor `T` and
/// validation callback `F`. /// validation callback `F`.
@ -54,7 +54,7 @@ where
impl<F, O> HttpAuthentication<basic::BasicAuth, F> impl<F, O> HttpAuthentication<basic::BasicAuth, F>
where where
F: Fn(ServiceRequest, basic::BasicAuth) -> O, F: Fn(ServiceRequest, basic::BasicAuth) -> O,
O: Future<Output = Result<ServiceRequest, Error>>, O: Future<Output = Result<ServiceRequest, (Error, ServiceRequest)>>,
{ {
/// Construct `HttpAuthentication` middleware for the HTTP "Basic" authentication scheme. /// Construct `HttpAuthentication` middleware for the HTTP "Basic" authentication scheme.
/// ///
@ -70,7 +70,7 @@ where
/// async fn validator( /// async fn validator(
/// req: ServiceRequest, /// req: ServiceRequest,
/// credentials: BasicAuth, /// credentials: BasicAuth,
/// ) -> Result<ServiceRequest, Error> { /// ) -> Result<ServiceRequest, (Error, ServiceRequest)> {
/// // All users are great and more than welcome! /// // All users are great and more than welcome!
/// Ok(req) /// Ok(req)
/// } /// }
@ -85,7 +85,7 @@ where
impl<F, O> HttpAuthentication<bearer::BearerAuth, F> impl<F, O> HttpAuthentication<bearer::BearerAuth, F>
where where
F: Fn(ServiceRequest, bearer::BearerAuth) -> O, F: Fn(ServiceRequest, bearer::BearerAuth) -> O,
O: Future<Output = Result<ServiceRequest, Error>>, O: Future<Output = Result<ServiceRequest, (Error, ServiceRequest)>>,
{ {
/// Construct `HttpAuthentication` middleware for the HTTP "Bearer" authentication scheme. /// Construct `HttpAuthentication` middleware for the HTTP "Bearer" authentication scheme.
/// ///
@ -96,7 +96,7 @@ where
/// # use actix_web_httpauth::middleware::HttpAuthentication; /// # use actix_web_httpauth::middleware::HttpAuthentication;
/// # use actix_web_httpauth::extractors::bearer::{Config, BearerAuth}; /// # use actix_web_httpauth::extractors::bearer::{Config, BearerAuth};
/// # use actix_web_httpauth::extractors::{AuthenticationError, AuthExtractorConfig}; /// # use actix_web_httpauth::extractors::{AuthenticationError, AuthExtractorConfig};
/// async fn validator(req: ServiceRequest, credentials: BearerAuth) -> Result<ServiceRequest, Error> { /// async fn validator(req: ServiceRequest, credentials: BearerAuth) -> Result<ServiceRequest, (Error, ServiceRequest)> {
/// if credentials.token() == "mF_9.B5f-4.1JqM" { /// if credentials.token() == "mF_9.B5f-4.1JqM" {
/// Ok(req) /// Ok(req)
/// } else { /// } else {
@ -105,7 +105,7 @@ where
/// .unwrap_or_else(Default::default) /// .unwrap_or_else(Default::default)
/// .scope("urn:example:channel=HBO&urn:example:rating=G,PG-13"); /// .scope("urn:example:channel=HBO&urn:example:rating=G,PG-13");
/// ///
/// Err(AuthenticationError::from(config).into()) /// Err((AuthenticationError::from(config).into(), req))
/// } /// }
/// } /// }
/// ///
@ -121,7 +121,7 @@ where
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static, S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
S::Future: 'static, S::Future: 'static,
F: Fn(ServiceRequest, T) -> O + 'static, F: Fn(ServiceRequest, T) -> O + 'static,
O: Future<Output = Result<ServiceRequest, Error>> + 'static, O: Future<Output = Result<ServiceRequest, (Error, ServiceRequest)>> + 'static,
T: AuthExtractor + 'static, T: AuthExtractor + 'static,
B: MessageBody + 'static, B: MessageBody + 'static,
{ {
@ -155,7 +155,7 @@ where
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static, S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
S::Future: 'static, S::Future: 'static,
F: Fn(ServiceRequest, T) -> O + 'static, F: Fn(ServiceRequest, T) -> O + 'static,
O: Future<Output = Result<ServiceRequest, Error>> + 'static, O: Future<Output = Result<ServiceRequest, (Error, ServiceRequest)>> + 'static,
T: AuthExtractor + 'static, T: AuthExtractor + 'static,
B: MessageBody + 'static, B: MessageBody + 'static,
{ {
@ -178,9 +178,12 @@ where
} }
}; };
// TODO: alter to remove ? operator; an error response is required for downstream let req = match process_fn(req, credentials).await {
// middleware to do their thing (eg. cors adding headers) Ok(req) => req,
let req = process_fn(req, credentials).await?; Err((err, req)) => {
return Ok(req.error_response(err).map_into_right_body());
}
};
service.call(req).await.map(|res| res.map_into_left_body()) service.call(req).await.map(|res| res.map_into_left_body())
} }
@ -362,10 +365,10 @@ mod tests {
#[actix_web::test] #[actix_web::test]
async fn test_middleware_works_with_app() { async fn test_middleware_works_with_app() {
async fn validator( async fn validator(
_req: ServiceRequest, req: ServiceRequest,
_credentials: BasicAuth, _credentials: BasicAuth,
) -> Result<ServiceRequest, actix_web::Error> { ) -> Result<ServiceRequest, (actix_web::Error, ServiceRequest)> {
Err(ErrorForbidden("You are not welcome!")) Err((ErrorForbidden("You are not welcome!"), req))
} }
let middleware = HttpAuthentication::basic(validator); let middleware = HttpAuthentication::basic(validator);
@ -387,10 +390,10 @@ mod tests {
#[actix_web::test] #[actix_web::test]
async fn test_middleware_works_with_scope() { async fn test_middleware_works_with_scope() {
async fn validator( async fn validator(
_req: ServiceRequest, req: ServiceRequest,
_credentials: BasicAuth, _credentials: BasicAuth,
) -> Result<ServiceRequest, actix_web::Error> { ) -> Result<ServiceRequest, (actix_web::Error, ServiceRequest)> {
Err(ErrorForbidden("You are not welcome!")) Err((ErrorForbidden("You are not welcome!"), req))
} }
let middleware = actix_web::middleware::Compat::new(HttpAuthentication::basic(validator)); let middleware = actix_web::middleware::Compat::new(HttpAuthentication::basic(validator));