Skip to content

Commit 65ef3f7

Browse files
authored
Move managed identity credentials behind ManagedIdentityCredential (Azure#2409)
1 parent d5df353 commit 65ef3f7

File tree

9 files changed

+509
-31
lines changed

9 files changed

+509
-31
lines changed

sdk/identity/.dict.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ appservice
33
azureauth
44
clientcertificate
55
clientsecret
6+
cloudshell
67
imds
8+
managedidentity
79
msal
10+
replacen
811
workloadidentity

sdk/identity/azure_identity/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
- Removed `get_subscription()` and `get_tenant()` from `AzureCliCredential`.
1818
- `WorkloadIdentityCredential` constructors moved some parameters to an `Option<ClientAssertionCredentialOptions>` parameter.
1919
- Removed `clear_cache()` from all credential types
20+
- Replaced `AppServiceManagedIdentityCredential`, `VirtualMachineManagedIdentityCredential`, and `ImdsId` with `ManagedIdentityCredential` and `UserAssignedId`
2021

2122
### Bugs Fixed
2223

sdk/identity/azure_identity/README.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ authentication flows. For more details on this scenario see [Configure an applic
7878

7979
```rust no_run
8080
use azure_core::credentials::{AccessToken, TokenCredential};
81-
use azure_identity::{ClientAssertion, ClientAssertionCredential, ImdsId, TokenCredentialOptions, VirtualMachineManagedIdentityCredential};
81+
use azure_identity::{ClientAssertion, ClientAssertionCredential, TokenCredentialOptions, ManagedIdentityCredential};
8282
use std::sync::Arc;
8383

8484
#[derive(Debug)]
@@ -104,10 +104,7 @@ impl ClientAssertion for VmClientAssertion {
104104
#[tokio::main]
105105
async fn main() -> Result<(), Box<dyn std::error::Error>> {
106106
let assertion = VmClientAssertion {
107-
credential: VirtualMachineManagedIdentityCredential::new(
108-
ImdsId::SystemAssigned,
109-
TokenCredentialOptions::default(),
110-
)?,
107+
credential: ManagedIdentityCredential::new(None)?,
111108
scope: String::from("api://AzureADTokenExchange/.default"),
112109
};
113110

sdk/identity/azure_identity/examples/specific_credential.rs

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ use azure_core::{
99
#[cfg(not(target_arch = "wasm32"))]
1010
use azure_identity::AzureCliCredential;
1111
use azure_identity::{
12-
AppServiceManagedIdentityCredential, ImdsId, TokenCredentialOptions,
13-
VirtualMachineManagedIdentityCredential, WorkloadIdentityCredential,
12+
ManagedIdentityCredential, TokenCredentialOptions, WorkloadIdentityCredential,
1413
};
1514
use std::sync::Arc;
1615

@@ -49,17 +48,15 @@ const AZURE_CREDENTIAL_KIND: &str = "AZURE_CREDENTIAL_KIND";
4948
mod azure_credential_kinds {
5049
#[cfg(not(target_arch = "wasm32"))]
5150
pub const AZURE_CLI: &str = "azurecli";
52-
pub const VIRTUAL_MACHINE: &str = "virtualmachine";
53-
pub const APP_SERVICE: &str = "appservice";
51+
pub const MANAGED_IDENTITY: &str = "managedidentity";
5452
pub const WORKLOAD_IDENTITY: &str = "workloadidentity";
5553
}
5654

5755
#[derive(Debug)]
5856
enum SpecificAzureCredentialKind {
5957
#[cfg(not(target_arch = "wasm32"))]
6058
AzureCli(Arc<AzureCliCredential>),
61-
VirtualMachine(Arc<VirtualMachineManagedIdentityCredential>),
62-
AppService(Arc<AppServiceManagedIdentityCredential>),
59+
ManagedIdentity(Arc<ManagedIdentityCredential>),
6360
WorkloadIdentity(Arc<WorkloadIdentityCredential>),
6461
}
6562

@@ -70,10 +67,7 @@ impl TokenCredential for SpecificAzureCredentialKind {
7067
match self {
7168
#[cfg(not(target_arch = "wasm32"))]
7269
SpecificAzureCredentialKind::AzureCli(credential) => credential.get_token(scopes).await,
73-
SpecificAzureCredentialKind::VirtualMachine(credential) => {
74-
credential.get_token(scopes).await
75-
}
76-
SpecificAzureCredentialKind::AppService(credential) => {
70+
SpecificAzureCredentialKind::ManagedIdentity(credential) => {
7771
credential.get_token(scopes).await
7872
}
7973
SpecificAzureCredentialKind::WorkloadIdentity(credential) => {
@@ -97,21 +91,16 @@ impl SpecificAzureCredential {
9791
let source: SpecificAzureCredentialKind =
9892
// case insensitive and allow spaces
9993
match credential_type.replace(' ', "").to_lowercase().as_str() {
100-
azure_credential_kinds::APP_SERVICE => {
101-
AppServiceManagedIdentityCredential::new(options)
102-
.map(SpecificAzureCredentialKind::AppService)
94+
azure_credential_kinds::MANAGED_IDENTITY => {
95+
ManagedIdentityCredential::new(None)
96+
.map(SpecificAzureCredentialKind::ManagedIdentity)
10397
.with_context(ErrorKind::Credential, || {
10498
format!(
10599
"unable to create AZURE_CREDENTIAL_KIND of {}",
106-
azure_credential_kinds::APP_SERVICE
100+
azure_credential_kinds::MANAGED_IDENTITY
107101
)
108102
})?
109103
}
110-
azure_credential_kinds::VIRTUAL_MACHINE => {
111-
SpecificAzureCredentialKind::VirtualMachine(
112-
VirtualMachineManagedIdentityCredential::new(ImdsId::SystemAssigned, options)?,
113-
)
114-
}
115104
#[cfg(not(target_arch = "wasm32"))]
116105
azure_credential_kinds::AZURE_CLI => AzureCliCredential::new(Some(options.into()))
117106
.map(SpecificAzureCredentialKind::AzureCli)

sdk/identity/azure_identity/src/credentials/app_service_managed_identity_credential.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ pub struct AppServiceManagedIdentityCredential {
1919
}
2020

2121
impl AppServiceManagedIdentityCredential {
22-
pub fn new(options: impl Into<TokenCredentialOptions>) -> azure_core::Result<Arc<Self>> {
22+
pub fn new(
23+
id: ImdsId,
24+
options: impl Into<TokenCredentialOptions>,
25+
) -> azure_core::Result<Arc<Self>> {
2326
let options = options.into();
2427
let env = options.env();
2528
let endpoint = &env
@@ -43,7 +46,7 @@ impl AppServiceManagedIdentityCredential {
4346
API_VERSION,
4447
SECRET_HEADER,
4548
SECRET_ENV,
46-
ImdsId::SystemAssigned,
49+
id,
4750
),
4851
}))
4952
}

sdk/identity/azure_identity/src/credentials/imds_managed_identity_credentials.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4-
use crate::{credentials::cache::TokenCache, TokenCredentialOptions};
4+
use crate::{credentials::cache::TokenCache, env::Env, TokenCredentialOptions, UserAssignedId};
55
use azure_core::{
66
credentials::{AccessToken, Secret, TokenCredential},
77
error::{http_response_from_body, Error, ErrorKind},
@@ -31,6 +31,16 @@ pub enum ImdsId {
3131
MsiResId(String),
3232
}
3333

34+
impl From<UserAssignedId> for ImdsId {
35+
fn from(user_assigned_id: UserAssignedId) -> Self {
36+
match user_assigned_id {
37+
UserAssignedId::ClientId(client_id) => ImdsId::ClientId(client_id),
38+
UserAssignedId::ObjectId(object_id) => ImdsId::ObjectId(object_id),
39+
UserAssignedId::ResourceId(resource_id) => ImdsId::MsiResId(resource_id),
40+
}
41+
}
42+
}
43+
3444
/// Attempts authentication using a managed identity that has been assigned to the deployment environment.
3545
///
3646
/// This authentication type works in Azure VMs, App Service and Azure Functions applications, as well as the Azure Cloud Shell
@@ -45,6 +55,7 @@ pub(crate) struct ImdsManagedIdentityCredential {
4555
secret_env: String,
4656
id: ImdsId,
4757
cache: TokenCache,
58+
env: Env,
4859
}
4960

5061
impl ImdsManagedIdentityCredential {
@@ -65,6 +76,7 @@ impl ImdsManagedIdentityCredential {
6576
secret_env: secret_env.to_owned(),
6677
id,
6778
cache: TokenCache::new(),
79+
env: options.env().clone(),
6880
}
6981
}
7082

@@ -90,7 +102,7 @@ impl ImdsManagedIdentityCredential {
90102

91103
req.insert_header("metadata", "true");
92104

93-
let msi_secret = std::env::var(&self.secret_env);
105+
let msi_secret = self.env.var(&self.secret_env);
94106
if let Ok(val) = msi_secret {
95107
req.insert_header(self.secret_header.clone(), val);
96108
};

sdk/identity/azure_identity/src/credentials/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@ mod options;
2121
mod virtual_machine_managed_identity_credential;
2222
mod workload_identity_credentials;
2323

24-
pub use app_service_managed_identity_credential::*;
24+
pub(crate) use app_service_managed_identity_credential::*;
2525
#[cfg(not(target_arch = "wasm32"))]
2626
pub use azure_cli_credentials::*;
2727
pub use client_assertion_credentials::*;
2828
#[cfg(feature = "client_certificate")]
2929
pub use client_certificate_credentials::*;
3030
pub use default_azure_credentials::*;
31-
pub use imds_managed_identity_credentials::ImdsId;
31+
pub(crate) use imds_managed_identity_credentials::ImdsId;
3232
pub(crate) use imds_managed_identity_credentials::*;
3333
pub use options::*;
34-
pub use virtual_machine_managed_identity_credential::*;
34+
pub(crate) use virtual_machine_managed_identity_credential::*;
3535
pub use workload_identity_credentials::*;

sdk/identity/azure_identity/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ mod chained_token_credential;
1010
mod credentials;
1111
mod env;
1212
mod federated_credentials_flow;
13+
mod managed_identity_credential;
1314
mod oauth2_http_client;
1415
mod refresh_token;
1516
mod timeout;
@@ -18,6 +19,7 @@ use azure_core::{error::ErrorKind, Error, Result};
1819
pub use azure_pipelines_credential::*;
1920
pub use chained_token_credential::*;
2021
pub use credentials::*;
22+
pub use managed_identity_credential::*;
2123
use std::borrow::Cow;
2224

2325
fn validate_not_empty<C>(value: &str, message: C) -> Result<()>
@@ -108,3 +110,9 @@ fn test_validate_tenant_id() {
108110
assert!(validate_tenant_id("A-1.z").is_ok());
109111
assert!(validate_tenant_id("7b795fb9-09d3-42f4-a494-38864f99ba3c").is_ok());
110112
}
113+
114+
#[cfg(test)]
115+
mod tests {
116+
pub const LIVE_TEST_RESOURCE: &str = "https://management.azure.com";
117+
pub const LIVE_TEST_SCOPES: &[&str] = &["https://management.azure.com/.default"];
118+
}

0 commit comments

Comments
 (0)