Skip to content

Commit e944136

Browse files
Reworked Managed Identity Retry Policy to be per-request (#7603)
The same retry policy was previously being used for all Managed Identity sources and requests. The retry policy will now be based on the Managed Identity source, and therefore will be per-request. Future Work: Create an IMDS retry policy to address [this bug](AzureAD/microsoft-authentication-library-for-dotnet#4998).
1 parent e300043 commit e944136

13 files changed

+141
-40
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "minor",
3+
"comment": "Reworked Managed Identity Retry Policy to be per-request, which is based on the Managed Identity source. #7603",
4+
"packageName": "@azure/msal-node",
5+
"email": "[email protected]",
6+
"dependentChangeType": "patch"
7+
}

lib/msal-node/src/client/ManagedIdentityApplication.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ export class ManagedIdentityApplication {
111111
this.logger,
112112
ManagedIdentityApplication.nodeStorage as NodeStorage,
113113
this.networkClient,
114-
this.cryptoProvider
114+
this.cryptoProvider,
115+
this.config.disableInternalRetries
115116
);
116117
}
117118

lib/msal-node/src/client/ManagedIdentityClient.ts

+20-4
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export class ManagedIdentityClient {
3535
private nodeStorage: NodeStorage;
3636
private networkClient: INetworkModule;
3737
private cryptoProvider: CryptoProvider;
38+
private disableInternalRetries: boolean;
3839

3940
private static identitySource?: BaseManagedIdentitySource;
4041
public static sourceName?: ManagedIdentitySourceNames;
@@ -43,12 +44,14 @@ export class ManagedIdentityClient {
4344
logger: Logger,
4445
nodeStorage: NodeStorage,
4546
networkClient: INetworkModule,
46-
cryptoProvider: CryptoProvider
47+
cryptoProvider: CryptoProvider,
48+
disableInternalRetries: boolean
4749
) {
4850
this.logger = logger;
4951
this.nodeStorage = nodeStorage;
5052
this.networkClient = networkClient;
5153
this.cryptoProvider = cryptoProvider;
54+
this.disableInternalRetries = disableInternalRetries;
5255
}
5356

5457
public async sendManagedIdentityTokenRequest(
@@ -64,6 +67,7 @@ export class ManagedIdentityClient {
6467
this.nodeStorage,
6568
this.networkClient,
6669
this.cryptoProvider,
70+
this.disableInternalRetries,
6771
managedIdentityId
6872
);
6973
}
@@ -126,6 +130,7 @@ export class ManagedIdentityClient {
126130
nodeStorage: NodeStorage,
127131
networkClient: INetworkModule,
128132
cryptoProvider: CryptoProvider,
133+
disableInternalRetries: boolean,
129134
managedIdentityId: ManagedIdentityId
130135
): BaseManagedIdentitySource {
131136
const source =
@@ -134,35 +139,46 @@ export class ManagedIdentityClient {
134139
nodeStorage,
135140
networkClient,
136141
cryptoProvider,
142+
disableInternalRetries,
137143
managedIdentityId
138144
) ||
139145
AppService.tryCreate(
140146
logger,
141147
nodeStorage,
142148
networkClient,
143-
cryptoProvider
149+
cryptoProvider,
150+
disableInternalRetries
144151
) ||
145152
MachineLearning.tryCreate(
146153
logger,
147154
nodeStorage,
148155
networkClient,
149-
cryptoProvider
156+
cryptoProvider,
157+
disableInternalRetries
150158
) ||
151159
CloudShell.tryCreate(
152160
logger,
153161
nodeStorage,
154162
networkClient,
155163
cryptoProvider,
164+
disableInternalRetries,
156165
managedIdentityId
157166
) ||
158167
AzureArc.tryCreate(
159168
logger,
160169
nodeStorage,
161170
networkClient,
162171
cryptoProvider,
172+
disableInternalRetries,
163173
managedIdentityId
164174
) ||
165-
Imds.tryCreate(logger, nodeStorage, networkClient, cryptoProvider);
175+
Imds.tryCreate(
176+
logger,
177+
nodeStorage,
178+
networkClient,
179+
cryptoProvider,
180+
disableInternalRetries
181+
);
166182
if (!source) {
167183
throw createManagedIdentityError(
168184
ManagedIdentityErrorCodes.unableToCreateSource

lib/msal-node/src/client/ManagedIdentitySources/AppService.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,17 @@ export class AppService extends BaseManagedIdentitySource {
3434
nodeStorage: NodeStorage,
3535
networkClient: INetworkModule,
3636
cryptoProvider: CryptoProvider,
37+
disableInternalRetries: boolean,
3738
identityEndpoint: string,
3839
identityHeader: string
3940
) {
40-
super(logger, nodeStorage, networkClient, cryptoProvider);
41+
super(
42+
logger,
43+
nodeStorage,
44+
networkClient,
45+
cryptoProvider,
46+
disableInternalRetries
47+
);
4148

4249
this.identityEndpoint = identityEndpoint;
4350
this.identityHeader = identityHeader;
@@ -60,7 +67,8 @@ export class AppService extends BaseManagedIdentitySource {
6067
logger: Logger,
6168
nodeStorage: NodeStorage,
6269
networkClient: INetworkModule,
63-
cryptoProvider: CryptoProvider
70+
cryptoProvider: CryptoProvider,
71+
disableInternalRetries: boolean
6472
): AppService | null {
6573
const [identityEndpoint, identityHeader] =
6674
AppService.getEnvironmentVariables();
@@ -90,6 +98,7 @@ export class AppService extends BaseManagedIdentitySource {
9098
nodeStorage,
9199
networkClient,
92100
cryptoProvider,
101+
disableInternalRetries,
93102
identityEndpoint,
94103
identityHeader
95104
);

lib/msal-node/src/client/ManagedIdentitySources/AzureArc.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,16 @@ export class AzureArc extends BaseManagedIdentitySource {
7474
nodeStorage: NodeStorage,
7575
networkClient: INetworkModule,
7676
cryptoProvider: CryptoProvider,
77+
disableInternalRetries: boolean,
7778
identityEndpoint: string
7879
) {
79-
super(logger, nodeStorage, networkClient, cryptoProvider);
80+
super(
81+
logger,
82+
nodeStorage,
83+
networkClient,
84+
cryptoProvider,
85+
disableInternalRetries
86+
);
8087

8188
this.identityEndpoint = identityEndpoint;
8289
}
@@ -122,6 +129,7 @@ export class AzureArc extends BaseManagedIdentitySource {
122129
nodeStorage: NodeStorage,
123130
networkClient: INetworkModule,
124131
cryptoProvider: CryptoProvider,
132+
disableInternalRetries: boolean,
125133
managedIdentityId: ManagedIdentityId
126134
): AzureArc | null {
127135
const [identityEndpoint, imdsEndpoint] =
@@ -181,6 +189,7 @@ export class AzureArc extends BaseManagedIdentitySource {
181189
nodeStorage,
182190
networkClient,
183191
cryptoProvider,
192+
disableInternalRetries,
184193
identityEndpoint
185194
);
186195
}

lib/msal-node/src/client/ManagedIdentitySources/BaseManagedIdentitySource.ts

+20-4
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import {
3232
createManagedIdentityError,
3333
} from "../../error/ManagedIdentityError.js";
3434
import { isIso8601 } from "../../utils/TimeUtils.js";
35+
import { HttpClientWithRetries } from "../../network/HttpClientWithRetries.js";
3536

3637
/**
3738
* Managed Identity User Assigned Id Query Parameter Names
@@ -50,17 +51,20 @@ export abstract class BaseManagedIdentitySource {
5051
private nodeStorage: NodeStorage;
5152
private networkClient: INetworkModule;
5253
private cryptoProvider: CryptoProvider;
54+
private disableInternalRetries: boolean;
5355

5456
constructor(
5557
logger: Logger,
5658
nodeStorage: NodeStorage,
5759
networkClient: INetworkModule,
58-
cryptoProvider: CryptoProvider
60+
cryptoProvider: CryptoProvider,
61+
disableInternalRetries: boolean
5962
) {
6063
this.logger = logger;
6164
this.nodeStorage = nodeStorage;
6265
this.networkClient = networkClient;
6366
this.cryptoProvider = cryptoProvider;
67+
this.disableInternalRetries = disableInternalRetries;
6468
}
6569

6670
abstract createRequest(
@@ -151,20 +155,32 @@ export abstract class BaseManagedIdentitySource {
151155
networkRequest.computeParametersBodyString();
152156
}
153157

158+
/**
159+
* Initializes the network client helper based on the retry policy configuration.
160+
* If internal retries are disabled, it uses the provided network client directly.
161+
* Otherwise, it wraps the network client with an HTTP client that supports retries.
162+
*/
163+
const networkClientHelper: INetworkModule = this.disableInternalRetries
164+
? this.networkClient
165+
: new HttpClientWithRetries(
166+
this.networkClient,
167+
networkRequest.retryPolicy
168+
);
169+
154170
const reqTimestamp = TimeUtils.nowSeconds();
155171
let response: NetworkResponse<ManagedIdentityTokenResponse>;
156172
try {
157173
// Sources that send POST requests: Cloud Shell
158174
if (networkRequest.httpMethod === HttpMethod.POST) {
159175
response =
160-
await this.networkClient.sendPostRequestAsync<ManagedIdentityTokenResponse>(
176+
await networkClientHelper.sendPostRequestAsync<ManagedIdentityTokenResponse>(
161177
networkRequest.computeUri(),
162178
networkRequestOptions
163179
);
164180
// Sources that send GET requests: App Service, Azure Arc, IMDS, Service Fabric
165181
} else {
166182
response =
167-
await this.networkClient.sendGetRequestAsync<ManagedIdentityTokenResponse>(
183+
await networkClientHelper.sendGetRequestAsync<ManagedIdentityTokenResponse>(
168184
networkRequest.computeUri(),
169185
networkRequestOptions
170186
);
@@ -189,7 +205,7 @@ export abstract class BaseManagedIdentitySource {
189205
const serverTokenResponse: ServerAuthorizationTokenResponse =
190206
await this.getServerTokenResponseAsync(
191207
response,
192-
this.networkClient,
208+
networkClientHelper,
193209
networkRequest,
194210
networkRequestOptions
195211
);

lib/msal-node/src/client/ManagedIdentitySources/CloudShell.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,16 @@ export class CloudShell extends BaseManagedIdentitySource {
3333
nodeStorage: NodeStorage,
3434
networkClient: INetworkModule,
3535
cryptoProvider: CryptoProvider,
36+
disableInternalRetries: boolean,
3637
msiEndpoint: string
3738
) {
38-
super(logger, nodeStorage, networkClient, cryptoProvider);
39+
super(
40+
logger,
41+
nodeStorage,
42+
networkClient,
43+
cryptoProvider,
44+
disableInternalRetries
45+
);
3946

4047
this.msiEndpoint = msiEndpoint;
4148
}
@@ -52,6 +59,7 @@ export class CloudShell extends BaseManagedIdentitySource {
5259
nodeStorage: NodeStorage,
5360
networkClient: INetworkModule,
5461
cryptoProvider: CryptoProvider,
62+
disableInternalRetries: boolean,
5563
managedIdentityId: ManagedIdentityId
5664
): CloudShell | null {
5765
const [msiEndpoint] = CloudShell.getEnvironmentVariables();
@@ -89,6 +97,7 @@ export class CloudShell extends BaseManagedIdentitySource {
8997
nodeStorage,
9098
networkClient,
9199
cryptoProvider,
100+
disableInternalRetries,
92101
msiEndpoint
93102
);
94103
}

lib/msal-node/src/client/ManagedIdentitySources/Imds.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,16 @@ export class Imds extends BaseManagedIdentitySource {
3434
nodeStorage: NodeStorage,
3535
networkClient: INetworkModule,
3636
cryptoProvider: CryptoProvider,
37+
disableInternalRetries: boolean,
3738
identityEndpoint: string
3839
) {
39-
super(logger, nodeStorage, networkClient, cryptoProvider);
40+
super(
41+
logger,
42+
nodeStorage,
43+
networkClient,
44+
cryptoProvider,
45+
disableInternalRetries
46+
);
4047

4148
this.identityEndpoint = identityEndpoint;
4249
}
@@ -45,7 +52,8 @@ export class Imds extends BaseManagedIdentitySource {
4552
logger: Logger,
4653
nodeStorage: NodeStorage,
4754
networkClient: INetworkModule,
48-
cryptoProvider: CryptoProvider
55+
cryptoProvider: CryptoProvider,
56+
disableInternalRetries: boolean
4957
): Imds {
5058
let validatedIdentityEndpoint: string;
5159

@@ -88,6 +96,7 @@ export class Imds extends BaseManagedIdentitySource {
8896
nodeStorage,
8997
networkClient,
9098
cryptoProvider,
99+
disableInternalRetries,
91100
validatedIdentityEndpoint
92101
);
93102
}

lib/msal-node/src/client/ManagedIdentitySources/MachineLearning.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,17 @@ export class MachineLearning extends BaseManagedIdentitySource {
3131
nodeStorage: NodeStorage,
3232
networkClient: INetworkModule,
3333
cryptoProvider: CryptoProvider,
34+
disableInternalRetries: boolean,
3435
msiEndpoint: string,
3536
secret: string
3637
) {
37-
super(logger, nodeStorage, networkClient, cryptoProvider);
38+
super(
39+
logger,
40+
nodeStorage,
41+
networkClient,
42+
cryptoProvider,
43+
disableInternalRetries
44+
);
3845

3946
this.msiEndpoint = msiEndpoint;
4047
this.secret = secret;
@@ -54,7 +61,8 @@ export class MachineLearning extends BaseManagedIdentitySource {
5461
logger: Logger,
5562
nodeStorage: NodeStorage,
5663
networkClient: INetworkModule,
57-
cryptoProvider: CryptoProvider
64+
cryptoProvider: CryptoProvider,
65+
disableInternalRetries: boolean
5866
): MachineLearning | null {
5967
const [msiEndpoint, secret] = MachineLearning.getEnvironmentVariables();
6068

@@ -83,6 +91,7 @@ export class MachineLearning extends BaseManagedIdentitySource {
8391
nodeStorage,
8492
networkClient,
8593
cryptoProvider,
94+
disableInternalRetries,
8695
msiEndpoint,
8796
secret
8897
);

lib/msal-node/src/client/ManagedIdentitySources/ServiceFabric.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,17 @@ export class ServiceFabric extends BaseManagedIdentitySource {
3434
nodeStorage: NodeStorage,
3535
networkClient: INetworkModule,
3636
cryptoProvider: CryptoProvider,
37+
disableInternalRetries: boolean,
3738
identityEndpoint: string,
3839
identityHeader: string
3940
) {
40-
super(logger, nodeStorage, networkClient, cryptoProvider);
41+
super(
42+
logger,
43+
nodeStorage,
44+
networkClient,
45+
cryptoProvider,
46+
disableInternalRetries
47+
);
4148

4249
this.identityEndpoint = identityEndpoint;
4350
this.identityHeader = identityHeader;
@@ -66,6 +73,7 @@ export class ServiceFabric extends BaseManagedIdentitySource {
6673
nodeStorage: NodeStorage,
6774
networkClient: INetworkModule,
6875
cryptoProvider: CryptoProvider,
76+
disableInternalRetries: boolean,
6977
managedIdentityId: ManagedIdentityId
7078
): ServiceFabric | null {
7179
const [identityEndpoint, identityHeader, identityServerThumbprint] =
@@ -107,6 +115,7 @@ export class ServiceFabric extends BaseManagedIdentitySource {
107115
nodeStorage,
108116
networkClient,
109117
cryptoProvider,
118+
disableInternalRetries,
110119
identityEndpoint,
111120
identityHeader
112121
);

0 commit comments

Comments
 (0)