From 1a7544f030e905161e46735e2541c78ec9694c70 Mon Sep 17 00:00:00 2001 From: David Mulder Date: Fri, 19 Apr 2024 10:51:39 -0600 Subject: [PATCH 1/3] Failure to initiate MFA can leave garbage in cookies If an MFA attempt fails, we need to clear out the cookies, otherwise subsequent authentication attempts will hang due to the garbage in the cookie store. Signed-off-by: David Mulder --- Cargo.toml | 1 + src/auth.rs | 31 ++++++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 5e2bbe5..e0b3317 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,3 +35,4 @@ kanidm-hsm-crypto = { version = "^0.2.0", optional = true } regex = "^1.10.3" zeroize = { version = "^1.7.0", features = ["zeroize_derive"] } scraper = "0.19.0" +reqwest_cookie_store = "0.7.0" diff --git a/src/auth.rs b/src/auth.rs index 384ed19..a56d20b 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -2,6 +2,7 @@ use crate::error::{ErrorResponse, MsalError}; use base64::engine::general_purpose::URL_SAFE_NO_PAD; use base64::Engine; use reqwest::{header, Client, Url}; +use reqwest_cookie_store::{CookieStore, CookieStoreMutex}; use scraper::{Html, Selector}; use serde::de::{self, MapAccess, Visitor}; use serde::{Deserialize, Deserializer, Serialize}; @@ -9,6 +10,7 @@ use serde_json::{from_str as json_from_str, json, Value}; use std::fmt; use std::marker::PhantomData; use std::str::FromStr; +use std::sync::Arc; use tracing::info; use urlencoding::encode as url_encode; use uuid::Uuid; @@ -738,18 +740,21 @@ impl SessionKey { struct ClientApplication { client: Client, + cookie_store: Arc, client_id: String, authority: String, } impl ClientApplication { fn new(client_id: &str, authority: Option<&str>) -> Result { + let cookie_store = Arc::new(CookieStoreMutex::new(CookieStore::new(None))); let client = reqwest::Client::builder() - .cookie_store(true) + .cookie_provider(std::sync::Arc::clone(&cookie_store)) .build() .map_err(|e| MsalError::RequestFailed(format!("{}", e)))?; Ok(ClientApplication { client, + cookie_store, client_id: client_id.to_string(), authority: match authority { Some(authority) => authority.to_string(), @@ -1137,6 +1142,30 @@ impl PublicClientApplication { password: &str, scopes: Vec<&str>, resource: Option<&str>, + ) -> Result { + match self + .initiate_acquire_token_by_mfa_flow_internal(username, password, scopes, resource) + .await + { + Ok(res) => Ok(res), + Err(e) => { + /* If we fail to reset the Cookie store here, subsequent + * auth requests will fail */ + let mut cookie_store = self.app.cookie_store.lock().map_err(|e| { + MsalError::GeneralFailure(format!("Failed to lock and clear the cookie store. Subsequent authentications will fail: {:?}", e)) + })?; + cookie_store.clear(); + Err(e) + } + } + } + + async fn initiate_acquire_token_by_mfa_flow_internal( + &self, + username: &str, + password: &str, + scopes: Vec<&str>, + resource: Option<&str>, ) -> Result { let request_id = Uuid::new_v4().to_string(); let auth_config = self From 348237907b7baa3ccf35ce8a3c320ad6ba7db8ec Mon Sep 17 00:00:00 2001 From: David Mulder Date: Fri, 19 Apr 2024 10:53:47 -0600 Subject: [PATCH 2/3] Version 0.1.17 Signed-off-by: David Mulder --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index e0b3317..552df96 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "msal" description = "Microsoft Authentication Library for Rust" -version = "0.1.16" +version = "0.1.17" edition = "2021" authors = [ "David Mulder " From c546a0c17627eda3f69768e14890a6fbce19ed80 Mon Sep 17 00:00:00 2001 From: David Mulder Date: Fri, 19 Apr 2024 10:56:24 -0600 Subject: [PATCH 3/3] Eliminate duplicate github checks Signed-off-by: David Mulder --- .github/workflows/build.yml | 5 ++--- .github/workflows/clippy.yml | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 16ad40e..215c4f4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,10 +3,9 @@ name: Build # Trigger the workflow on push or pull request "on": - push: - branches-ignore: - - main pull_request: + branches: + - main env: SCCACHE_GHA_ENABLED: "true" diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml index d8914bb..e3d7e81 100644 --- a/.github/workflows/clippy.yml +++ b/.github/workflows/clippy.yml @@ -3,10 +3,9 @@ name: Clippy # Trigger the workflow on push or pull request "on": - push: - branches-ignore: - - main pull_request: + branches: + - main env: SCCACHE_GHA_ENABLED: "true"