Skip to content

Commit 79234e2

Browse files
authored
Bogavril/aui (#5404)
* Agentic AI integration tests * 2 * 3 * 4 * Update tests * Address PR
1 parent 833ce41 commit 79234e2

File tree

1 file changed

+139
-0
lines changed
  • tests/Microsoft.Identity.Test.Integration.netcore/HeadlessTests

1 file changed

+139
-0
lines changed
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
using System;
4+
using System.Diagnostics;
5+
using System.Security.Cryptography.X509Certificates;
6+
using System.Threading.Tasks;
7+
using Microsoft.Identity.Client;
8+
using Microsoft.Identity.Client.Extensibility;
9+
using Microsoft.Identity.Test.LabInfrastructure;
10+
using Microsoft.Identity.Test.Unit;
11+
using Microsoft.VisualStudio.TestTools.UnitTesting;
12+
13+
namespace Microsoft.Identity.Test.Integration.HeadlessTests
14+
{
15+
[TestClass]
16+
public class Agentic
17+
{
18+
const string ClientId = "d15884b6-a447-4dd5-a5a5-a668c49f6300"; // agent app
19+
const string TenantId = "31a58c3b-ae9c-4448-9e8f-e9e143e800df";
20+
const string AgentIdentity = "d84da24a-2ea2-42b8-b5ab-8637ec208024";
21+
const string UserUpn = "[email protected]";
22+
private const string TokenExchangeUrl = "api://AzureADTokenExchange/.default";
23+
private const string Scope = "https://graph.microsoft.com/.default";
24+
25+
[TestMethod]
26+
public async Task AgentUserIdentityGetsTokenForGraphTest()
27+
{
28+
await AgentUserIdentityGetsTokenForGraphAsync().ConfigureAwait(false);
29+
}
30+
31+
[TestMethod]
32+
public async Task AgentGetsAppTokenForGraphTest()
33+
{
34+
await AgentGetsAppTokenForGraph().ConfigureAwait(false);
35+
}
36+
37+
private static async Task AgentGetsAppTokenForGraph()
38+
{
39+
var cca = ConfidentialClientApplicationBuilder
40+
.Create(AgentIdentity)
41+
.WithAuthority("https://login.microsoftonline.com/", TenantId)
42+
.WithCacheOptions(CacheOptions.EnableSharedCacheOptions)
43+
.WithExperimentalFeatures(true)
44+
.WithClientAssertion((AssertionRequestOptions _) => GetAppCredentialAsync(AgentIdentity))
45+
.Build();
46+
47+
var result = await cca.AcquireTokenForClient([Scope])
48+
.ExecuteAsync()
49+
.ConfigureAwait(false);
50+
51+
Trace.WriteLine($"FMI app credential from : {result.AuthenticationResultMetadata.TokenSource}");
52+
}
53+
54+
private static async Task AgentUserIdentityGetsTokenForGraphAsync()
55+
{
56+
var cca = ConfidentialClientApplicationBuilder
57+
.Create(AgentIdentity)
58+
.WithAuthority("https://login.microsoftonline.com/", TenantId)
59+
.WithCacheOptions(CacheOptions.EnableSharedCacheOptions)
60+
.WithExperimentalFeatures(true)
61+
.WithExtraQueryParameters("slice=first")
62+
.WithClientAssertion((AssertionRequestOptions _) => GetAppCredentialAsync(AgentIdentity))
63+
.Build();
64+
65+
var result = await (cca as IByUsernameAndPassword).AcquireTokenByUsernamePassword([Scope], UserUpn, "no_password")
66+
.OnBeforeTokenRequest(
67+
async (request) =>
68+
{
69+
string userFicAssertion = await GetUserFic().ConfigureAwait(false);
70+
request.BodyParameters["user_federated_identity_credential"] = userFicAssertion;
71+
request.BodyParameters["grant_type"] = "user_fic";
72+
73+
// remove the password
74+
request.BodyParameters.Remove("password");
75+
76+
if (request.BodyParameters.TryGetValue("client_secret", out var secret)
77+
&& secret.Equals("default", StringComparison.OrdinalIgnoreCase))
78+
{
79+
request.BodyParameters.Remove("client_secret");
80+
}
81+
}
82+
)
83+
.ExecuteAsync()
84+
.ConfigureAwait(false);
85+
86+
IAccount account = await cca.GetAccountAsync(result.Account.HomeAccountId.Identifier).ConfigureAwait(false);
87+
var result2 = await cca.AcquireTokenSilent([Scope], account).ExecuteAsync().ConfigureAwait(false);
88+
89+
Assert.IsTrue(result2.AuthenticationResultMetadata.TokenSource == TokenSource.Cache, "Token should be from cache");
90+
}
91+
92+
private static async Task<string> GetAppCredentialAsync(string fmiPath)
93+
{
94+
Assert.IsNotNull(fmiPath, "fmiPath cannot be null");
95+
X509Certificate2 cert = CertificateHelper.FindCertificateByName(TestConstants.AutomationTestCertName);
96+
97+
var cca1 = ConfidentialClientApplicationBuilder
98+
.Create(ClientId)
99+
.WithAuthority("https://login.microsoftonline.com/", TenantId)
100+
.WithCacheOptions(CacheOptions.EnableSharedCacheOptions)
101+
.WithExperimentalFeatures(true)
102+
.WithCertificate(cert, sendX5C: true) //sendX5c enables SN+I auth which is required for FMI flows
103+
.Build();
104+
105+
var result = await cca1.AcquireTokenForClient([TokenExchangeUrl])
106+
.WithFmiPath(fmiPath)
107+
.ExecuteAsync()
108+
.ConfigureAwait(false);
109+
110+
Trace.WriteLine($"FMI app credential from : {result.AuthenticationResultMetadata.TokenSource}");
111+
112+
return result.AccessToken;
113+
}
114+
115+
private static async Task<string> GetUserFic()
116+
{
117+
var cca1 = ConfidentialClientApplicationBuilder
118+
.Create(AgentIdentity)
119+
.WithAuthority("https://login.microsoftonline.com/", TenantId)
120+
.WithExperimentalFeatures(true)
121+
.WithCacheOptions(CacheOptions.EnableSharedCacheOptions)
122+
.WithClientAssertion(async (AssertionRequestOptions a) =>
123+
{
124+
Assert.AreEqual(AgentIdentity, a.ClientAssertionFmiPath);
125+
var cred = await GetAppCredentialAsync(a.ClientAssertionFmiPath).ConfigureAwait(false);
126+
return cred;
127+
})
128+
.Build();
129+
130+
var result = await cca1.AcquireTokenForClient([TokenExchangeUrl])
131+
.WithFmiPathForClientAssertion(AgentIdentity)
132+
.ExecuteAsync().ConfigureAwait(false);
133+
134+
Trace.WriteLine($"User FIC credential from : {result.AuthenticationResultMetadata.TokenSource}");
135+
136+
return result.AccessToken;
137+
}
138+
}
139+
}

0 commit comments

Comments
 (0)