Skip to content

Commit fe07e29

Browse files
authored
fix MSI authentication parsing of expires_on (#460)
1 parent 4c23d89 commit fe07e29

File tree

1 file changed

+37
-4
lines changed

1 file changed

+37
-4
lines changed

sdk/identity/src/token_credentials/managed_identity_credentials.rs

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
use super::TokenCredential;
22
use azure_core::TokenResponse;
3-
use chrono::serde::ts_seconds;
4-
use chrono::{DateTime, Utc};
3+
use chrono::{DateTime, TimeZone, Utc};
54
use oauth2::AccessToken;
6-
use serde::Deserialize;
5+
use serde::{
6+
de::{self, Deserializer},
7+
Deserialize,
8+
};
79
use std::str;
810
use url::Url;
911

@@ -86,11 +88,42 @@ impl azure_core::TokenCredential for ManagedIdentityCredential {
8688
}
8789
}
8890

91+
pub fn expires_on_string<'de, D>(deserializer: D) -> Result<DateTime<Utc>, D::Error>
92+
where
93+
D: Deserializer<'de>,
94+
{
95+
let v = String::deserialize(deserializer)?;
96+
let as_i64 = v.parse::<i64>().map_err(de::Error::custom)?;
97+
Ok(Utc.timestamp(as_i64, 0))
98+
}
99+
100+
// NOTE: expires_on is a String version of unix epoch time, not an integer.
101+
// https://docs.microsoft.com/en-us/azure/app-service/overview-managed-identity?tabs=dotnet#rest-protocol-examples
89102
#[derive(Debug, Clone, Deserialize)]
90103
struct MsiTokenResponse {
91104
pub access_token: AccessToken,
92-
#[serde(with = "ts_seconds")]
105+
#[serde(deserialize_with = "expires_on_string")]
93106
pub expires_on: DateTime<Utc>,
94107
pub token_type: String,
95108
pub resource: String,
96109
}
110+
111+
#[cfg(test)]
112+
mod tests {
113+
use super::*;
114+
115+
#[derive(Debug, Deserialize)]
116+
struct TestExpires {
117+
#[serde(deserialize_with = "expires_on_string")]
118+
date: DateTime<Utc>,
119+
}
120+
121+
#[test]
122+
fn check_expires_on_string() {
123+
let as_string = r#"{"date": "1586984735"}"#;
124+
let expected = Utc.ymd(2020, 4, 15).and_hms(21, 5, 35);
125+
let parsed: TestExpires =
126+
serde_json::from_str(as_string).expect("deserialize should succeed");
127+
assert_eq!(expected, parsed.date);
128+
}
129+
}

0 commit comments

Comments
 (0)