diff --git a/src/auth.rs b/src/auth.rs
index 583961c..d51cb7a 100644
@@ -5679,38 +5778,51 @@ impl BrokerClientApplication {
let text;
(text, resp) = self.app.await_working(resp).await?;
if resp.status().is_redirection() {
- let document = Html::parse_document(&text);
- let selector = Selector::parse("a[href]").map_err(|_| {
- MsalError::InvalidParse("Failed parsing auth code response".to_string())
- })?;
- if let Some(element) = document.select(&selector).next() {
- if let Some(href_encoded) = element.value().attr("href") {
- let href = percent_decode_str(href_encoded)
- .decode_utf8()
- .map_err(|e| {
- MsalError::URLFormatFailed(format!("Failed decoding url: {:?}", e))
- })?;
- if let Ok(url) = Url::parse(&href) {
- return url
- .query_pairs()
- .find_map(|(key, value)| {
+ // Parse HTML in its own scope so Html is dropped before any await.
+ // Html uses non-atomic reference counting and is not Send.
+ let auth_code_result: Option<String> = {
+ let document = Html::parse_document(&text);
+ let selector = Selector::parse("a[href]").map_err(|_| {
+ MsalError::InvalidParse("Failed parsing auth code response".to_string())
+ })?;
+ if let Some(element) = document.select(&selector).next() {
+ if let Some(href_encoded) = element.value().attr("href") {
+ let href = percent_decode_str(href_encoded)
+ .decode_utf8()
+ .map_err(|e| {
+ MsalError::URLFormatFailed(format!("Failed decoding url: {:?}", e))
+ })?;
+ if let Ok(url) = Url::parse(&href) {
+ url.query_pairs().find_map(|(key, value)| {
if key == "code" {
Some(value.into_owned())
} else {
None
}
})
- .ok_or(MsalError::GeneralFailure(
- "Authorization code not found".to_string(),
- ));
+ } else {
+ None
+ }
+ } else {
+ None
}
+ } else {
+ None
}
+ }; // Html document dropped here
+
+ if let Some(code) = auth_code_result {
+ return Ok(code);
}
// MS may have returned an AuthConfig here with an error attached.
// Return the error from that AuthConfig if possible. If a required
- // password change is indicated, raise an error.
- match self.app.parse_auth_config(&text, false, false) {
+ // password change is indicated, raise an error. If ConvergedTFA is
+ // returned, MFA is required for this user.
+ // Note: parse_auth_config uses Html internally but is synchronous,
+ // so the Html is dropped before we return the AuthConfig.
+ let auth_config_result = self.app.parse_auth_config(&text, false, false);
+ match auth_config_result {
#[cfg(feature = "changepassword")]
Err(MsalError::ChangePassword) => return Err(MsalError::ChangePassword),
Err(MsalError::AADSTSError(e)) => return Err(MsalError::AADSTSError(e)),
@@ -5742,8 +5854,12 @@ impl BrokerClientApplication {
// MS may have returned an AuthConfig here with an error attached.
// Return the error from that AuthConfig if possible. If a required
- // password change is indicated, raise an error.
- match self.app.parse_auth_config(&text, false, false) {
+ // password change is indicated, raise an error. If ConvergedTFA is
+ // returned, MFA is required for this user.
+ // Note: parse_auth_config uses Html internally but is synchronous,
+ // so the Html is dropped before we return the AuthConfig.
+ let auth_config_result = self.app.parse_auth_config(&text, false, false);
+ match auth_config_result {
#[cfg(feature = "changepassword")]
Err(MsalError::ChangePassword) => return Err(MsalError::ChangePassword),
Err(MsalError::AADSTSError(e)) => return Err(MsalError::AADSTSError(e)),