@@ -18,7 +18,7 @@ const MSI_API_VERSION: &str = "2019-08-01";
18
18
/// This authentication type works in Azure VMs, App Service and Azure Functions applications, as well as the Azure Cloud Shell
19
19
///
20
20
/// Built up from docs at [https://docs.microsoft.com/azure/app-service/overview-managed-identity#using-the-rest-protocol](https://docs.microsoft.com/azure/app-service/overview-managed-identity#using-the-rest-protocol)
21
- pub struct ManagedIdentityCredential ;
21
+ pub struct ImdsManagedIdentityCredential ;
22
22
23
23
#[ non_exhaustive]
24
24
#[ derive( Debug , thiserror:: Error ) ]
@@ -32,14 +32,16 @@ pub enum ManagedIdentityCredentialError {
32
32
MissingMsiSecret ( std:: env:: VarError ) ,
33
33
#[ error( "Refresh token send error: {0}" ) ]
34
34
SendError ( reqwest:: Error ) ,
35
- #[ error( "Error getting text for refresh token: {0}" ) ]
36
- TextError ( reqwest:: Error ) ,
37
35
#[ error( "Error deserializing refresh token: {0}" ) ]
38
- DeserializeError ( serde_json:: Error ) ,
36
+ DeserializeError ( reqwest:: Error ) ,
37
+ #[ error( "The requested identity has not been assigned to this resource." ) ]
38
+ IdentityUnavailableError ,
39
+ #[ error( "The request failed due to a gateway error." ) ]
40
+ GatewayError ,
39
41
}
40
42
41
43
#[ async_trait:: async_trait]
42
- impl TokenCredential for ManagedIdentityCredential {
44
+ impl TokenCredential for ImdsManagedIdentityCredential {
43
45
type Error = ManagedIdentityCredentialError ;
44
46
45
47
async fn get_token ( & self , resource : & str ) -> Result < TokenResponse , Self :: Error > {
@@ -55,29 +57,33 @@ impl TokenCredential for ManagedIdentityCredential {
55
57
. map_err ( ManagedIdentityCredentialError :: MissingMsiSecret ) ?;
56
58
57
59
let client = reqwest:: Client :: new ( ) ;
58
- let res_body = client
60
+ let response = client
59
61
. get ( msi_endpoint_url)
60
62
. header ( "Metadata" , "true" )
61
63
. header ( "X-IDENTITY-HEADER" , msi_secret)
62
64
. send ( )
63
65
. await
64
- . map_err ( ManagedIdentityCredentialError :: SendError ) ?
65
- . text ( )
66
- . await
67
- . map_err ( ManagedIdentityCredentialError :: TextError ) ?;
68
-
69
- let token_response = serde_json:: from_str :: < MsiTokenResponse > ( & res_body)
70
- . map_err ( ManagedIdentityCredentialError :: DeserializeError ) ?;
71
-
72
- Ok ( TokenResponse :: new (
73
- token_response. access_token ,
74
- token_response. expires_on ,
75
- ) )
66
+ . map_err ( ManagedIdentityCredentialError :: SendError ) ?;
67
+
68
+ match response. status ( ) . as_u16 ( ) {
69
+ 400 => Err ( ManagedIdentityCredentialError :: IdentityUnavailableError ) ,
70
+ 502 | 504 => Err ( ManagedIdentityCredentialError :: GatewayError ) ,
71
+ _ => {
72
+ let token_response = response
73
+ . json :: < MsiTokenResponse > ( )
74
+ . await
75
+ . map_err ( ManagedIdentityCredentialError :: DeserializeError ) ?;
76
+ Ok ( TokenResponse :: new (
77
+ token_response. access_token ,
78
+ token_response. expires_on ,
79
+ ) )
80
+ }
81
+ }
76
82
}
77
83
}
78
84
79
85
#[ async_trait:: async_trait]
80
- impl azure_core:: TokenCredential for ManagedIdentityCredential {
86
+ impl azure_core:: TokenCredential for ImdsManagedIdentityCredential {
81
87
async fn get_token (
82
88
& self ,
83
89
resource : & str ,
0 commit comments