Skip to content

Commit 068f6cb

Browse files
trwalketrwalke
andauthored
Enabling Arlington automation tests (#1672)
* adding Arlington USGov tests * Adding ROPC and OBO test for arlington * Addressing PR comments * clean up * Addressing comments * Fixing tests * Fixing test Co-authored-by: trwalke <[email protected]>
1 parent 806d423 commit 068f6cb

File tree

10 files changed

+198
-46
lines changed

10 files changed

+198
-46
lines changed

tests/Microsoft.Identity.Test.Common/TestConstants.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,10 @@ public static IDictionary<string, string> ExtraQueryParameters
146146

147147
public const string MsalCCAKeyVaultUri = "https://buildautomation.vault.azure.net/secrets/AzureADIdentityDivisionTestAgentSecret/";
148148
public const string MsalOBOKeyVaultUri = "https://buildautomation.vault.azure.net/secrets/IdentityDivisionDotNetOBOServiceSecret/";
149+
public const string MsalArlingtonOBOKeyVaultUri = "https://msidlabs.vault.azure.net:443/secrets/ARLMSIDLAB1-IDLASBS-App-CC-Secret";
149150
public const string FociApp1 = "https://buildautomation.vault.azure.net/secrets/automation-foci-app1/";
150151
public const string FociApp2 = "https://buildautomation.vault.azure.net/secrets/automation-foci-app2/";
152+
public const string MsalArlingtonCCAKeyVaultUri = "https://msidlabs.vault.azure.net:443/secrets/ARLMSIDLAB1-IDLASBS-App-CC-Secret";
151153

152154
public enum AuthorityType { B2C };
153155
public static string[] s_prodEnvAliases = new string[] {

tests/Microsoft.Identity.Test.Integration.net45/HeadlessTests/ConfidentialClientIntegrationTests.cs

Lines changed: 93 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,28 @@ namespace Microsoft.Identity.Test.Integration.HeadlessTests
3131
public class ConfidentialClientIntegrationTests
3232
{
3333
private static readonly string[] s_scopes = { "User.Read" };
34-
private static readonly string[] s_oboServiceScope = { "api://23c64cd8-21e4-41dd-9756-ab9e2c23f58c/access_as_user" };
34+
private static readonly string[] s_publicCloudOBOServiceScope = { "api://23c64cd8-21e4-41dd-9756-ab9e2c23f58c/access_as_user" };
35+
private static readonly string[] s_arlingtonOBOServiceScope = { "https://arlmsidlab1.us/IDLABS_APP_Confidential_Client/user_impersonation" };
3536
private static readonly string[] s_keyvaultScope = { "https://vault.azure.net/.default" };
3637
private static readonly string[] s_adfsScopes = { "openid", "profile" };
3738

3839
//TODO: acquire scenario specific client ids from the lab resonse
39-
private const string ConfidentialClientID = "16dab2ba-145d-4b1b-8569-bf4b9aed4dc8";
40+
private const string PublicCloudPublicClientIDOBO = "be9b0186-7dfd-448a-a944-f771029105bf";
41+
private const string PublicCloudConfidentialClientIDOBO = "23c64cd8-21e4-41dd-9756-ab9e2c23f58c";
42+
private const string PublicCloudConfidentialClientID = "16dab2ba-145d-4b1b-8569-bf4b9aed4dc8";
43+
private const string ArlingtonConfidentialClientIDOBO = "c0555d2d-02f2-4838-802e-3463422e571d";
44+
private const string ArlingtonPublicClientIDOBO = "cb7faed4-b8c0-49ee-b421-f5ed16894c83";
45+
private const string ArlingtonAuthority = "https://login.microsoftonline.us/45ff0c17-f8b5-489b-b7fd-2fedebbec0c4";
46+
47+
private const string PublicCloudHost = "https://login.microsoftonline.com/";
48+
private const string ArlingtonCloudHost = "https://login.microsoftonline.us/";
4049

4150
private const string RedirectUri = "https://login.microsoftonline.com/common/oauth2/nativeclient";
42-
private const string TestAuthority = "https://login.windows.net/72f988bf-86f1-41af-91ab-2d7cd011db47";
51+
private const string PublicCloudTestAuthority = "https://login.windows.net/72f988bf-86f1-41af-91ab-2d7cd011db47";
4352
private const string AdfsCertName = "IDLABS-APP-Confidential-Client-Cert-OnPrem";
4453
private KeyVaultSecretsProvider _keyVault;
45-
private string _ccaSecret;
54+
private static string _publicCloudCcaSecret;
55+
private static string _arlingtonCCASecret;
4656

4757
[ClassInitialize]
4858
public static void ClassInitialize(TestContext context)
@@ -58,7 +68,8 @@ public void TestInitialize()
5868
if (_keyVault == null)
5969
{
6070
_keyVault = new KeyVaultSecretsProvider();
61-
_ccaSecret = _keyVault.GetSecret(TestConstants.MsalCCAKeyVaultUri).Value;
71+
_publicCloudCcaSecret = _keyVault.GetSecret(TestConstants.MsalCCAKeyVaultUri).Value;
72+
_arlingtonCCASecret = _keyVault.GetSecret(TestConstants.MsalArlingtonCCAKeyVaultUri).Value;
6273
}
6374
}
6475

@@ -67,7 +78,7 @@ public void TestInitialize()
6778
public async Task GetAuthorizationRequestUrl_ReturnsUri_Async()
6879
{
6980
var cca = ConfidentialClientApplicationBuilder
70-
.Create(ConfidentialClientID)
81+
.Create(PublicCloudConfidentialClientID)
7182
.WithRedirectUri(RedirectUri)
7283
.Build();
7384

@@ -82,7 +93,7 @@ public async Task GetAuthorizationRequestUrl_ReturnsUri_Async()
8293

8394
CoreAssert.AreEqual("offline_access openid profile User.Read", uriParams1["scope"], uriParams2["scope"]);
8495
CoreAssert.AreEqual("code", uriParams1["response_type"], uriParams2["response_type"]);
85-
CoreAssert.AreEqual(ConfidentialClientID, uriParams1["client_id"], uriParams2["client_id"]);
96+
CoreAssert.AreEqual(PublicCloudConfidentialClientID, uriParams1["client_id"], uriParams2["client_id"]);
8697
CoreAssert.AreEqual(RedirectUri, uriParams1["redirect_uri"], uriParams2["redirect_uri"]);
8798
CoreAssert.AreEqual("select_account", uriParams1["prompt"], uriParams2["prompt"]);
8899

@@ -98,10 +109,10 @@ public async Task ConfidentialClientWithCertificateTestAsync()
98109
AuthenticationResult authResult;
99110
IConfidentialClientApplication confidentialApp;
100111
X509Certificate2 cert = GetCertificate();
101-
var confidentialClientAuthority = TestAuthority;
112+
var confidentialClientAuthority = PublicCloudTestAuthority;
102113

103114
confidentialApp = ConfidentialClientApplicationBuilder
104-
.Create(ConfidentialClientID)
115+
.Create(PublicCloudConfidentialClientID)
105116
.WithAuthority(new Uri(confidentialClientAuthority), true)
106117
.WithCertificate(cert)
107118
.Build();
@@ -134,10 +145,10 @@ public async Task ConfidentialClientWithRSACertificateTestAsync()
134145
AuthenticationResult authResult;
135146
IConfidentialClientApplication confidentialApp;
136147
X509Certificate2 cert = GetCertificate(true);
137-
var confidentialClientAuthority = TestAuthority;
148+
var confidentialClientAuthority = PublicCloudTestAuthority;
138149

139150
confidentialApp = ConfidentialClientApplicationBuilder
140-
.Create(ConfidentialClientID)
151+
.Create(PublicCloudConfidentialClientID)
141152
.WithAuthority(new Uri(confidentialClientAuthority), true)
142153
.WithCertificate(cert)
143154
.Build();
@@ -166,12 +177,27 @@ public async Task ConfidentialClientWithRSACertificateTestAsync()
166177
[TestMethod]
167178
public async Task ConfidentialClientWithClientSecretTestAsync()
168179
{
169-
var confidentialClientAuthority = TestAuthority;
180+
await RunTestWithClientSecretAsync(PublicCloudConfidentialClientID,
181+
PublicCloudTestAuthority,
182+
_publicCloudCcaSecret).ConfigureAwait(false);
183+
}
184+
185+
[TestMethod]
186+
public async Task ArlingtonConfidentialClientWithClientSecretTestAsync()
187+
{
188+
await RunTestWithClientSecretAsync(ArlingtonConfidentialClientIDOBO,
189+
ArlingtonAuthority,
190+
_arlingtonCCASecret).ConfigureAwait(false);
191+
}
192+
193+
public async Task RunTestWithClientSecretAsync(string clientID, string authority, string secret)
194+
{
195+
var confidentialClientAuthority = authority;
170196

171197
var confidentialApp = ConfidentialClientApplicationBuilder
172-
.Create(ConfidentialClientID)
198+
.Create(clientID)
173199
.WithAuthority(new Uri(confidentialClientAuthority), true)
174-
.WithClientSecret(_ccaSecret)
200+
.WithClientSecret(secret)
175201
.Build();
176202
var appCacheRecorder = confidentialApp.AppTokenCache.RecordAccess();
177203

@@ -196,13 +222,13 @@ public async Task ConfidentialClientWithClientSecretTestAsync()
196222
[TestMethod]
197223
public async Task ConfidentialClientWithNoDefaultClaimsTestAsync()
198224
{
199-
var confidentialClientAuthority = TestAuthority;
225+
var confidentialClientAuthority = PublicCloudTestAuthority;
200226
var claims = GetClaims();
201227

202228
X509Certificate2 cert = GetCertificate();
203229

204230
var confidentialApp = ConfidentialClientApplicationBuilder
205-
.Create(ConfidentialClientID)
231+
.Create(PublicCloudConfidentialClientID)
206232
.WithAuthority(new Uri(confidentialClientAuthority), true)
207233
.WithClientClaims(cert, claims, false)
208234
.Build();
@@ -219,13 +245,13 @@ public async Task ConfidentialClientWithNoDefaultClaimsTestAsync()
219245
[TestMethod]
220246
public async Task ConfidentialClientWithDefaultClaimsTestAsync()
221247
{
222-
var confidentialClientAuthority = TestAuthority;
248+
var confidentialClientAuthority = PublicCloudTestAuthority;
223249
var claims = GetClaims(false);
224250

225251
X509Certificate2 cert = GetCertificate();
226252

227253
var confidentialApp = ConfidentialClientApplicationBuilder
228-
.Create(ConfidentialClientID)
254+
.Create(PublicCloudConfidentialClientID)
229255
.WithAuthority(new Uri(confidentialClientAuthority), true)
230256
.WithClientClaims(cert, claims)
231257
.Build();
@@ -247,13 +273,13 @@ public async Task ConfidentialClientWithDefaultClaimsTestAsync()
247273
[TestMethod]
248274
public async Task ConfidentialClientWithSignedAssertionTestAsync()
249275
{
250-
var confidentialClientAuthority = TestAuthority;
276+
var confidentialClientAuthority = PublicCloudTestAuthority;
251277
var claims = GetClaims();
252278

253279
var confidentialApp = ConfidentialClientApplicationBuilder
254-
.Create(ConfidentialClientID)
280+
.Create(PublicCloudConfidentialClientID)
255281
.WithAuthority(new Uri(confidentialClientAuthority), true)
256-
.WithClientAssertion(GetSignedClientAssertionUsingMsalInternal(ConfidentialClientID, claims))
282+
.WithClientAssertion(GetSignedClientAssertionUsingMsalInternal(PublicCloudConfidentialClientID, claims))
257283
.Build();
258284

259285
var appCacheRecorder = confidentialApp.AppTokenCache.RecordAccess();
@@ -312,10 +338,10 @@ private static IDictionary<string, string> GetClaims(bool useDefaultClaims = tru
312338
{
313339
{ "aud", TestConstants.ClientCredentialAudience },
314340
{ "exp", exp.ToString(CultureInfo.InvariantCulture) },
315-
{ "iss", ConfidentialClientID.ToString(CultureInfo.InvariantCulture) },
341+
{ "iss", PublicCloudConfidentialClientID.ToString(CultureInfo.InvariantCulture) },
316342
{ "jti", Guid.NewGuid().ToString() },
317343
{ "nbf", nbf.ToString(CultureInfo.InvariantCulture) },
318-
{ "sub", ConfidentialClientID.ToString(CultureInfo.InvariantCulture) },
344+
{ "sub", PublicCloudConfidentialClientID.ToString(CultureInfo.InvariantCulture) },
319345
{ "ip", "192.168.2.1" }
320346
};
321347
}
@@ -361,6 +387,12 @@ public async Task WebAPIAccessingGraphOnBehalfOfUserTestAsync()
361387
}
362388

363389
[TestMethod]
390+
public async Task ArlingtonWebAPIAccessingGraphOnBehalfOfUserTestAsync()
391+
{
392+
var labResponse = await LabUserHelper.GetArlingtonUserAsync().ConfigureAwait(false);
393+
await RunOnBehalfOfTestAsync(labResponse).ConfigureAwait(false);
394+
}
395+
364396
[TestCategory(TestCategories.ADFS)]
365397
public async Task WebAPIAccessingGraphOnBehalfOfADFS2019UserTestAsync()
366398
{
@@ -470,25 +502,52 @@ private static string GetSignedClientAssertionUsingWilson(
470502

471503
private async Task RunOnBehalfOfTestAsync(LabResponse labResponse)
472504
{
473-
var user = labResponse.User;
505+
LabUser user = labResponse.User;
506+
string oboHost;
507+
string secret;
508+
string authority;
509+
string publicClientID;
510+
string confidentialClientID;
511+
string[] oboScope;
512+
513+
switch (labResponse.User.AzureEnvironment)
514+
{
515+
case AzureEnvironment.azureusgovernment:
516+
oboHost = ArlingtonCloudHost;
517+
secret = _keyVault.GetSecret(TestConstants.MsalArlingtonOBOKeyVaultUri).Value;
518+
authority = labResponse.Lab.Authority + "organizations";
519+
publicClientID = ArlingtonPublicClientIDOBO;
520+
confidentialClientID = ArlingtonConfidentialClientIDOBO;
521+
oboScope = s_arlingtonOBOServiceScope;
522+
break;
523+
default:
524+
oboHost = PublicCloudHost;
525+
secret = _keyVault.GetSecret(TestConstants.MsalOBOKeyVaultUri).Value;
526+
authority = TestConstants.AuthorityOrganizationsTenant;
527+
publicClientID = PublicCloudPublicClientIDOBO;
528+
confidentialClientID = PublicCloudConfidentialClientIDOBO;
529+
oboScope = s_publicCloudOBOServiceScope;
530+
break;
531+
}
474532

475-
var secret = _keyVault.GetSecret(TestConstants.MsalOBOKeyVaultUri).Value;
476533
//TODO: acquire scenario specific client ids from the lab resonse
477-
var publicClientID = "be9b0186-7dfd-448a-a944-f771029105bf";
478-
var oboConfidentialClientID = "23c64cd8-21e4-41dd-9756-ab9e2c23f58c";
479534

480535
SecureString securePassword = new NetworkCredential("", user.GetOrFetchPassword()).SecurePassword;
481536

482-
var msalPublicClient = PublicClientApplicationBuilder.Create(publicClientID).WithAuthority(TestConstants.AuthorityOrganizationsTenant).WithRedirectUri(TestConstants.RedirectUri).Build();
537+
var msalPublicClient = PublicClientApplicationBuilder.Create(publicClientID)
538+
.WithAuthority(authority)
539+
.WithRedirectUri(TestConstants.RedirectUri)
540+
.Build();
483541

484-
AuthenticationResult authResult = await msalPublicClient
485-
.AcquireTokenByUsernamePassword(s_oboServiceScope, user.Upn, securePassword)
486-
.ExecuteAsync(CancellationToken.None)
487-
.ConfigureAwait(false);
542+
var builder = msalPublicClient.AcquireTokenByUsernamePassword(oboScope, user.Upn, securePassword);
543+
544+
builder.WithAuthority(authority);
545+
546+
var authResult = await builder.ExecuteAsync().ConfigureAwait(false);
488547

489548
var confidentialApp = ConfidentialClientApplicationBuilder
490-
.Create(oboConfidentialClientID)
491-
.WithAuthority(new Uri("https://login.microsoftonline.com/" + authResult.TenantId), true)
549+
.Create(confidentialClientID)
550+
.WithAuthority(new Uri(oboHost + authResult.TenantId), true)
492551
.WithClientSecret(secret)
493552
.Build();
494553

tests/Microsoft.Identity.Test.Integration.net45/HeadlessTests/UsernamePasswordIntegrationTests.cs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
using Microsoft.Identity.Test.Common.Core.Helpers;
1414
using Microsoft.Identity.Test.Integration.net45.Infrastructure;
1515
using Microsoft.Identity.Test.LabInfrastructure;
16-
using Microsoft.Identity.Test.Unit;
16+
using Microsoft.Identity.Test.Unit;
1717
using Microsoft.VisualStudio.TestTools.UnitTesting;
1818

1919
namespace Microsoft.Identity.Test.Integration.HeadlessTests
@@ -59,6 +59,20 @@ public async Task ROPC_AAD_Async()
5959
await RunHappyPathTestAsync(labResponse).ConfigureAwait(false);
6060
}
6161

62+
[TestMethod]
63+
public async Task ARLINGTON_ROPC_AAD_Async()
64+
{
65+
var labResponse = await LabUserHelper.GetArlingtonUserAsync().ConfigureAwait(false);
66+
await RunHappyPathTestAsync(labResponse).ConfigureAwait(false);
67+
}
68+
69+
[TestMethod]
70+
public async Task ARLINGTON_ROPC_ADFS_Async()
71+
{
72+
var labResponse = await LabUserHelper.GetArlingtonADFSUserAsync().ConfigureAwait(false);
73+
await RunHappyPathTestAsync(labResponse).ConfigureAwait(false);
74+
}
75+
6276
[TestMethod]
6377
public async Task ROPC_ADFSv4Federated_Async()
6478
{
@@ -82,8 +96,8 @@ public async Task AcquireTokenFromAdfsUsernamePasswordAsync()
8296
var user = labResponse.User;
8397

8498
SecureString securePassword = new NetworkCredential("", user.GetOrFetchPassword()).SecurePassword;
85-
86-
var msalPublicClient = PublicClientApplicationBuilder.Create(Adfs2019LabConstants.PublicClientId).WithAdfsAuthority(Adfs2019LabConstants.Authority).Build();
99+
100+
var msalPublicClient = PublicClientApplicationBuilder.Create(Adfs2019LabConstants.PublicClientId).WithAdfsAuthority(Adfs2019LabConstants.Authority).Build();
87101
AuthenticationResult authResult = await msalPublicClient.AcquireTokenByUsernamePassword(s_scopes, user.Upn, securePassword).ExecuteAsync().ConfigureAwait(false);
88102
Assert.IsNotNull(authResult);
89103
Assert.IsNotNull(authResult.AccessToken);
@@ -172,7 +186,7 @@ private async Task CheckTelemetryHeadersAsync(
172186
Assert.IsNotNull(authResult.AccessToken);
173187
Assert.IsNotNull(authResult.IdToken);
174188
Assert.IsTrue(string.Equals(labResponse.User.Upn, authResult.Account.Username, StringComparison.InvariantCultureIgnoreCase));
175-
AssertTelemetryHeaders(factory, true);
189+
AssertTelemetryHeaders(factory, true, labResponse);
176190
}
177191

178192
private async Task RunAcquireTokenWithUsernameIncorrectPasswordAsync(
@@ -209,8 +223,8 @@ private async Task RunHappyPathTestAsync(LabResponse labResponse)
209223
var factory = new HttpSnifferClientFactory();
210224
var msalPublicClient = PublicClientApplicationBuilder
211225
.Create(labResponse.App.AppId)
212-
.WithAuthority(Authority)
213226
.WithHttpClientFactory(factory)
227+
.WithAuthority(labResponse.Lab.Authority, "organizations")
214228
.Build();
215229

216230
AuthenticationResult authResult = await msalPublicClient
@@ -223,7 +237,7 @@ private async Task RunHappyPathTestAsync(LabResponse labResponse)
223237
Assert.IsNotNull(authResult.AccessToken);
224238
Assert.IsNotNull(authResult.IdToken);
225239
Assert.IsTrue(string.Equals(labResponse.User.Upn, authResult.Account.Username, StringComparison.InvariantCultureIgnoreCase));
226-
AssertTelemetryHeaders(factory, false);
240+
AssertTelemetryHeaders(factory, false, labResponse);
227241
// If test fails with "user needs to consent to the application, do an interactive request" error,
228242
// Do the following:
229243
// 1) Add in code to pull the user's password before creating the SecureString, and put a breakpoint there.
@@ -233,9 +247,9 @@ private async Task RunHappyPathTestAsync(LabResponse labResponse)
233247
// 4) After successful log-in, remove the password line you added in with step 1, and run the integration test again.
234248
}
235249

236-
private void AssertTelemetryHeaders(HttpSnifferClientFactory factory, bool IsFailure)
250+
private void AssertTelemetryHeaders(HttpSnifferClientFactory factory, bool IsFailure, LabResponse labResponse)
237251
{
238-
var (req, res) = factory.RequestsAndResponses.Single(x => x.Item1.RequestUri.AbsoluteUri == "https://login.microsoftonline.com/organizations/oauth2/v2.0/token" &&
252+
var (req, res) = factory.RequestsAndResponses.Single(x => x.Item1.RequestUri.AbsoluteUri == labResponse.Lab.Authority + "organizations/oauth2/v2.0/token" &&
239253
x.Item2.StatusCode == HttpStatusCode.OK);
240254

241255
var telemetryLastValue = req.Headers.Single(h => h.Key == TelemetryConstants.XClientLastTelemetry).Value;

0 commit comments

Comments
 (0)