public async Task TelemetryAcceptanceTestAsync() { using (_harness = CreateTestHarness()) { _harness.HttpManager.AddInstanceDiscoveryMockHandler(); _app = PublicClientApplicationBuilder.Create(TestConstants.ClientId) .WithHttpManager(_harness.HttpManager) .WithDefaultRedirectUri() .WithLogging((lvl, msg, pii) => Trace.WriteLine($"[MSAL_LOG][{lvl}] {msg}")) .BuildConcrete(); Trace.WriteLine("Step 1. Acquire Token Interactive successful"); var result = await RunAcquireTokenInteractiveAsync(AcquireTokenInteractiveOutcome.Success).ConfigureAwait(false); AssertCurrentTelemetry(result.HttpRequest, ApiIds.AcquireTokenInteractive, CacheRefreshReason.NotApplicable); AssertPreviousTelemetry(result.HttpRequest, expectedSilentCount: 0); Trace.WriteLine("Step 2. Acquire Token Silent successful - AT served from cache"); result = await RunAcquireTokenSilentAsync(AcquireTokenSilentOutcome.SuccessFromCache).ConfigureAwait(false); Assert.IsNull(result.HttpRequest, "No calls are made to the token endpoint"); Trace.WriteLine("Step 3. Acquire Token Silent successful - via refresh_token flow"); result = await RunAcquireTokenSilentAsync(AcquireTokenSilentOutcome.SuccessViaRefreshGrant).ConfigureAwait(false); AssertCurrentTelemetry(result.HttpRequest, ApiIds.AcquireTokenSilent, CacheRefreshReason.NoCachedAccessToken); AssertPreviousTelemetry(result.HttpRequest, expectedSilentCount: 1); Trace.WriteLine("Step 4. Acquire Token Silent with force_refresh = true and failure = invalid_grant"); result = await RunAcquireTokenSilentAsync(AcquireTokenSilentOutcome.FailInvalidGrant, forceRefresh : true).ConfigureAwait(false); AssertCurrentTelemetry(result.HttpRequest, ApiIds.AcquireTokenSilent, CacheRefreshReason.ForceRefreshOrClaims); AssertPreviousTelemetry(result.HttpRequest, expectedSilentCount: 0); // invalid grant error puts MSAL in a throttled state - simulate some time passing for this _harness.ServiceBundle.ThrottlingManager.SimulateTimePassing( UiRequiredProvider.s_uiRequiredExpiration.Add(TimeSpan.FromSeconds(1))); Guid step4Correlationid = result.Correlationid; Trace.WriteLine("Step 5. Acquire Token Silent with force_refresh = true and failure = interaction_required"); result = await RunAcquireTokenSilentAsync(AcquireTokenSilentOutcome.FailInteractionRequired, forceRefresh : true).ConfigureAwait(false); AssertCurrentTelemetry(result.HttpRequest, ApiIds.AcquireTokenSilent, CacheRefreshReason.ForceRefreshOrClaims); AssertPreviousTelemetry( result.HttpRequest, expectedSilentCount: 0, expectedFailedApiIds: new[] { ApiIds.AcquireTokenSilent }, // from step 4 expectedCorrelationIds: new[] { step4Correlationid }, expectedErrors: new[] { "invalid_grant" }); Guid step5CorrelationId = result.Correlationid; Trace.WriteLine("Step 6. Acquire Token Interactive - some /authorization error -> token endpoint not hit"); result = await RunAcquireTokenInteractiveAsync(AcquireTokenInteractiveOutcome.AuthorizationError).ConfigureAwait(false); Assert.IsNull(result.HttpRequest, "No calls are made to the token endpoint"); Guid step6CorrelationId = result.Correlationid; Trace.WriteLine("Step 7. Acquire Token Interactive -> HTTP 5xx error (i.e. AAD is down)"); result = await RunAcquireTokenInteractiveAsync(AcquireTokenInteractiveOutcome.AADUnavailableError).ConfigureAwait(false); Guid step7CorrelationId = result.Correlationid; // we can assert telemetry here, as it will be sent to AAD. However, AAD is down, so it will not record it. AssertCurrentTelemetry(result.HttpRequest, ApiIds.AcquireTokenInteractive, CacheRefreshReason.NotApplicable); AssertPreviousTelemetry( result.HttpRequest, expectedSilentCount: 0, expectedFailedApiIds: new[] { ApiIds.AcquireTokenSilent, ApiIds.AcquireTokenInteractive }, expectedCorrelationIds: new[] { step5CorrelationId, step6CorrelationId }, expectedErrors: new[] { "interaction_required", "user_cancelled" }); // the 5xx error puts MSAL in a throttling state, so "wait" until this clears _harness.ServiceBundle.ThrottlingManager.SimulateTimePassing( HttpStatusProvider.s_throttleDuration.Add(TimeSpan.FromSeconds(1))); Trace.WriteLine("Step 8. Acquire Token Interactive -> Success"); result = await RunAcquireTokenInteractiveAsync(AcquireTokenInteractiveOutcome.Success).ConfigureAwait(false); AssertCurrentTelemetry(result.HttpRequest, ApiIds.AcquireTokenInteractive, CacheRefreshReason.NotApplicable); AssertPreviousTelemetry( result.HttpRequest, expectedSilentCount: 0, expectedFailedApiIds: new[] { ApiIds.AcquireTokenSilent, ApiIds.AcquireTokenInteractive, ApiIds.AcquireTokenInteractive }, expectedCorrelationIds: new[] { step5CorrelationId, step6CorrelationId, step7CorrelationId }, expectedErrors: new[] { "interaction_required", "user_cancelled", "service_not_available" }); Trace.WriteLine("Step 9. Acquire Token Silent with force-refresh false -> successful"); result = await RunAcquireTokenSilentAsync(AcquireTokenSilentOutcome.SuccessViaRefreshGrant, false).ConfigureAwait(false); AssertCurrentTelemetry(result.HttpRequest, ApiIds.AcquireTokenSilent, CacheRefreshReason.NoCachedAccessToken); AssertPreviousTelemetry(result.HttpRequest, expectedSilentCount: 0); } }
public void TestGetAccounts() { var tokenCacheHelper = new TokenCacheHelper(); using (var httpManager = new MockHttpManager()) { PublicClientApplication app = PublicClientApplicationBuilder.Create(TestConstants.ClientId) .WithHttpManager(httpManager) .WithTelemetry(new TraceTelemetryConfig()) .BuildConcrete(); IEnumerable <IAccount> accounts = app.GetAccountsAsync().Result; Assert.IsNotNull(accounts); Assert.IsFalse(accounts.Any()); tokenCacheHelper.PopulateCache(app.UserTokenCacheInternal.Accessor); accounts = app.GetAccountsAsync().Result; Assert.IsNotNull(accounts); Assert.AreEqual(1, accounts.Count()); var atItem = new MsalAccessTokenCacheItem( TestConstants.ProductionPrefCacheEnvironment, TestConstants.ClientId, TestConstants.s_scope.AsSingleString(), TestConstants.Utid, null, new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(3600)), new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(7200)), MockHelpers.CreateClientInfo()); atItem.Secret = atItem.GetKey().ToString(); app.UserTokenCacheInternal.Accessor.SaveAccessToken(atItem); // another cache entry for different uid. user count should be 2. MsalRefreshTokenCacheItem rtItem = new MsalRefreshTokenCacheItem( TestConstants.ProductionPrefCacheEnvironment, TestConstants.ClientId, "someRT", MockHelpers.CreateClientInfo("uId1", "uTId1")); app.UserTokenCacheInternal.Accessor.SaveRefreshToken(rtItem); MsalIdTokenCacheItem idTokenCacheItem = new MsalIdTokenCacheItem( TestConstants.ProductionPrefCacheEnvironment, TestConstants.ClientId, MockHelpers.CreateIdToken(TestConstants.UniqueId, TestConstants.DisplayableId), MockHelpers.CreateClientInfo("uId1", "uTId1"), "uTId1"); app.UserTokenCacheInternal.Accessor.SaveIdToken(idTokenCacheItem); MsalAccountCacheItem accountCacheItem = new MsalAccountCacheItem( TestConstants.ProductionPrefCacheEnvironment, null, MockHelpers.CreateClientInfo("uId1", "uTId1"), null, null, "uTId1", null, null); app.UserTokenCacheInternal.Accessor.SaveAccount(accountCacheItem); Assert.AreEqual(2, app.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count()); accounts = app.GetAccountsAsync().Result; Assert.IsNotNull(accounts); Assert.AreEqual(2, accounts.Count()); // scoped by env // another cache entry for different environment. user count should still be 2. Sovereign cloud user must not be returned rtItem = new MsalRefreshTokenCacheItem( TestConstants.SovereignNetworkEnvironment, TestConstants.ClientId, "someRT", MockHelpers.CreateClientInfo(TestConstants.Uid + "more1", TestConstants.Utid)); app.UserTokenCacheInternal.Accessor.SaveRefreshToken(rtItem); Assert.AreEqual(3, app.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count()); accounts = app.GetAccountsAsync().Result; Assert.IsNotNull(accounts); Assert.AreEqual(2, accounts.Count()); } }
static async Task Main(string[] args) { // Create the MSAL client object (public or confidential, depending on your context) publicClient = PublicClientApplicationBuilder .Create(clientId) .WithAuthority(authority) .WithRedirectUri("http://localhost") .Build(); // Create an authentication provider by passing in a client application and graph scopes. InteractiveAuthenticationProvider authProvider = new InteractiveAuthenticationProvider(publicClient, graphScopes); // Create a new instance of GraphServiceClient with the authentication provider. GraphServiceClient graphClient = new GraphServiceClient(authProvider); // ***************************************** // Requesting a single object like "me" // ***************************************** var me = await graphClient.Me.Request().GetAsync(); Console.WriteLine(me.DisplayName); // ***************************************** // Querying list of data with with Top/Skip // ***************************************** int counter = 0; var users = await graphClient.Users.Request().Select("Id,DisplayName,UserPrincipalName").OrderBy("DisplayName").Top(20).GetAsync(); Console.WriteLine(users.Count); foreach (var user in users) { counter++; Console.WriteLine($"{counter:000} | {user.Id} => {user.DisplayName} <{user.UserPrincipalName}>"); } // ************************************* // Querying list of data with paging // ************************************* counter = 0; var messages = await graphClient.Me.Messages.Request().Select("Id,Subject").OrderBy("Subject").GetAsync(); var messagesIterator = PageIterator <Message> .CreatePageIterator(graphClient, messages, (message) => { counter++; Console.WriteLine($"{counter:000} | {message.Id} => {message.Subject}"); return(counter < 2000); // Stop after 2000 messages }); await messagesIterator.IterateAsync(); // ************************** // Working with batching // ************************** // Define a couple of request var userRequest = graphClient.Me.Request(); var messagesRequest = graphClient.Me.Messages.Request().Select("Id,Subject").OrderBy("Subject").Top(20); // Build a batch var batchRequestContent = new BatchRequestContent(); // Using AddBatchRequestStep adds each request as a step // with no specified order of execution var userRequestId = batchRequestContent.AddBatchRequestStep(userRequest); var messagesRequestId = batchRequestContent.AddBatchRequestStep(messagesRequest); // Process the actual batch request var returnedResponse = await graphClient.Batch.Request().PostAsync(batchRequestContent); // Try to get the responses try { var user = await returnedResponse .GetResponseByIdAsync <User>(userRequestId); Console.WriteLine($"Hello {user.DisplayName}!"); } catch (ServiceException ex) { Console.WriteLine($"Get user failed: {ex.Error.Message}"); } try { var messagesViaBatch = await returnedResponse .GetResponseByIdAsync <UserMessagesCollectionResponse>(messagesRequestId); counter = 0; foreach (var message in messagesViaBatch.Value) { counter++; Console.WriteLine($"{counter:000} | {message.Id} => {message.Subject}"); } } catch (ServiceException ex) { Console.WriteLine($"Get messages failed: {ex.Error.Message}"); } }
internal TokenCache(TokenCachePersistenceOptions options, MsalCacheHelperWrapper cacheHelperWrapper, Func <IPublicClientApplication> publicApplicationFactory = null) { _cacheHelperWrapper = cacheHelperWrapper ?? new MsalCacheHelperWrapper(); _publicClientApplicationFactory = publicApplicationFactory ?? new Func <IPublicClientApplication>(() => PublicClientApplicationBuilder.Create(Guid.NewGuid().ToString()).Build()); if (options is UnsafeTokenCacheOptions inMemoryOptions) { TokenCacheUpdatedAsync = inMemoryOptions.TokenCacheUpdatedAsync; RefreshCacheFromOptionsAsync = inMemoryOptions.RefreshCacheAsync; _lastUpdated = DateTimeOffset.UtcNow; _cacheAccessMap = new ConditionalWeakTable <object, CacheTimestamp>(); } else { _allowUnencryptedStorage = options?.UnsafeAllowUnencryptedStorage ?? false; _name = options?.Name ?? Constants.DefaultMsalTokenCacheName; _persistToDisk = true; } }
static async Task Main(string[] args) { var publicClientApp = PublicClientApplicationBuilder.Create(ClientId) .WithRedirectUri("http://localhost") .WithAuthority(AzureCloudInstance.AzurePublic, Tenant) .Build(); var repo = new GraphGroupRepository(new InteractiveAuthenticationProvider(publicClientApp), new Logger()); bool compareGroups = args.Length == 2; var users = new List <HashSet <AzureADUser> >(); var cycles = new List <SecurityGroupCycle>(); foreach (var groupToTraverse in args.Select(x => Guid.Parse(x))) { Console.WriteLine("Checking group: " + groupToTraverse); if (await repo.GroupExists(groupToTraverse) == false) { Console.WriteLine($"{groupToTraverse} doesn't exist. Skipping."); continue; } var crawler = new SGCrawler(repo); var crawlerUsers = new ConcurrentDictionary <AzureADUser, byte>(); var crawlerGroups = new ConcurrentBag <AzureADGroup>(); var crawlerCycles = new ConcurrentBag <SecurityGroupCycle>(); crawler.FoundUserAction = (user) => { crawlerUsers.TryAdd(user, 0); }; crawler.FoundGroupAction = (group) => { crawlerGroups.Add(group); }; crawler.FoundGroupCycleAction = (cycle) => { crawlerCycles.Add(cycle); }; var stopwatch = Stopwatch.StartNew(); await crawler.CrawlGroup(new AzureADGroup { ObjectId = groupToTraverse }); stopwatch.Stop(); Console.WriteLine($"Found {crawlerUsers.Count} total ({crawlerUsers.Keys.Distinct().Count()} distinct) users in {crawlerGroups.Count} total ({crawlerGroups.Distinct().Count()} distinct) nested groups in {stopwatch.ElapsedMilliseconds} ms."); Console.WriteLine($"Found {crawlerCycles.Count} cycles."); if (crawlerCycles.Any()) { cycles.AddRange(crawlerCycles); foreach (var cycle in crawlerCycles) { Console.WriteLine(cycle); } } if (compareGroups) { users.Add(new HashSet <AzureADUser>(crawlerUsers.Keys)); } } if (compareGroups && users.Count == 2) { Console.WriteLine($"The following users are in {args[0]} but not {args[1]}:"); Console.WriteLine(string.Join(Environment.NewLine, users[0].Except(users[1]))); Console.WriteLine($"The following users are in {args[1]} but not {args[0]}:"); Console.WriteLine(string.Join(Environment.NewLine, users[1].Except(users[0]))); } if (cycles.Any()) { Console.WriteLine($"Found {cycles.Count} cycles across all groups checked."); foreach (var cycle in cycles) { Console.WriteLine(cycle); } } }
public static async Task <string> GetLabAccessTokenAsync(string authority, string[] scopes, LabAccessAuthenticationType authType, string clientId, string certThumbprint, string clientSecret) { AuthenticationResult authResult; IConfidentialClientApplication confidentialApp; X509Certificate2 cert; switch (authType) { case LabAccessAuthenticationType.ClientCertificate: var clientIdForCertAuth = String.IsNullOrEmpty(clientId) ? LabAccessConfidentialClientId : clientId; var certThumbprintForLab = String.IsNullOrEmpty(clientId) ? LabAccessThumbPrint : certThumbprint; cert = CertificateHelper.FindCertificateByThumbprint(certThumbprintForLab); if (cert == null) { throw new InvalidOperationException( "Test setup error - cannot find a certificate in the My store for KeyVault. This is available for Microsoft employees only."); } confidentialApp = ConfidentialClientApplicationBuilder .Create(clientIdForCertAuth) .WithAuthority(new Uri(authority), true) .WithCertificate(cert) .Build(); s_staticCache.Bind(confidentialApp.AppTokenCache); authResult = await confidentialApp .AcquireTokenForClient(scopes) .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); break; case LabAccessAuthenticationType.ClientSecret: var clientIdForSecretAuth = String.IsNullOrEmpty(clientId) ? LabAccessConfidentialClientId : clientId; var clientSecretForLab = String.IsNullOrEmpty(clientId) ? s_secret : clientSecret; confidentialApp = ConfidentialClientApplicationBuilder .Create(clientIdForSecretAuth) .WithAuthority(new Uri(authority), true) .WithClientSecret(clientSecretForLab) .Build(); s_staticCache.Bind(confidentialApp.AppTokenCache); authResult = await confidentialApp .AcquireTokenForClient(scopes) .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); break; case LabAccessAuthenticationType.UserCredential: var clientIdForPublicClientAuth = String.IsNullOrEmpty(clientId) ? LabAccessPublicClientId : clientId; var publicApp = PublicClientApplicationBuilder .Create(clientIdForPublicClientAuth) .WithAuthority(new Uri(authority), true) .Build(); s_staticCache.Bind(publicApp.UserTokenCache); authResult = await publicApp .AcquireTokenByIntegratedWindowsAuth(scopes) .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); break; default: throw new ArgumentOutOfRangeException(); } return(authResult?.AccessToken); }
public void UnifiedCache_RemoveAccountIsApplicationSpecific() { byte[] data = null; using (var httpManager = new MockHttpManager()) { // login to app var app = PublicClientApplicationBuilder.Create(TestConstants.ClientId) .WithAuthority(new Uri(ClientApplicationBase.DefaultAuthority), true) .WithHttpManager(httpManager) .WithTelemetry(new TraceTelemetryConfig()) .BuildConcrete(); app.UserTokenCache.SetBeforeAccess((TokenCacheNotificationArgs args) => { args.TokenCache.DeserializeMsalV3(data); }); app.UserTokenCache.SetAfterAccess((TokenCacheNotificationArgs args) => { data = args.TokenCache.SerializeMsalV3(); }); httpManager.AddInstanceDiscoveryMockHandler(); app.ServiceBundle.ConfigureMockWebUI( AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code")); httpManager.AddSuccessTokenResponseMockHandlerForPost(ClientApplicationBase.DefaultAuthority); AuthenticationResult result = app .AcquireTokenInteractive(TestConstants.s_scope) .ExecuteAsync(CancellationToken.None) .Result; Assert.IsNotNull(result); Assert.AreEqual(1, app.UserTokenCacheInternal.Accessor.GetAllAccounts().Count()); Assert.AreEqual(1, app.GetAccountsAsync().Result.Count()); // login to app1 with same credentials var app1 = PublicClientApplicationBuilder.Create(TestConstants.ClientId2) .WithHttpManager(httpManager) .WithTelemetry(new TraceTelemetryConfig()) .WithAuthority( new Uri(ClientApplicationBase.DefaultAuthority), true).BuildConcrete(); app1.ServiceBundle.ConfigureMockWebUI( AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code")); app1.UserTokenCache.SetBeforeAccess((TokenCacheNotificationArgs args) => { args.TokenCache.DeserializeMsalV3(data); }); app1.UserTokenCache.SetAfterAccess((TokenCacheNotificationArgs args) => { data = args.TokenCache.SerializeMsalV3(); }); httpManager.AddSuccessTokenResponseMockHandlerForPost(ClientApplicationBase.DefaultAuthority); result = app1 .AcquireTokenInteractive(TestConstants.s_scope) .ExecuteAsync(CancellationToken.None) .Result; Assert.IsNotNull(result); // make sure that only one account cache entity was created Assert.AreEqual(1, app1.GetAccountsAsync().Result.Count()); Assert.AreEqual(2, app1.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count()); Assert.AreEqual(2, app1.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count()); Assert.AreEqual(2, app1.UserTokenCacheInternal.Accessor.GetAllIdTokens().Count()); Assert.AreEqual(1, app1.UserTokenCacheInternal.Accessor.GetAllAccounts().Count()); // remove account from app app.RemoveAsync(app.GetAccountsAsync().Result.First()).Wait(); // make sure account removed from app Assert.AreEqual(0, app.GetAccountsAsync().Result.Count()); // make sure account Not removed from app1 Assert.AreEqual(1, app1.GetAccountsAsync().Result.Count()); } }
public OneDrive() { PCA = PublicClientApplicationBuilder.Create(ClientID) .WithRedirectUri($"msal{ClientID}://auth") .Build(); }
[WorkItem(695)] // Fix for https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/695 public void AcquireTokenSilentForceRefreshMultipleTenantsTest() { using (var httpManager = new MockHttpManager()) { PublicClientApplication app = PublicClientApplicationBuilder.Create(MsalTestConstants.ClientId) .WithAuthority(new Uri(ClientApplicationBase.DefaultAuthority), true) .WithHttpManager(httpManager) .BuildConcrete(); var tokenCacheHelper = new TokenCacheHelper(); tokenCacheHelper.PopulateCacheWithOneAccessToken(app.UserTokenCacheInternal.Accessor); httpManager.AddInstanceDiscoveryMockHandler(); httpManager.AddMockHandlerForTenantEndpointDiscovery(MsalTestConstants.AuthorityCommonTenant); httpManager.AddMockHandler( new MockHttpMessageHandler() { ExpectedMethod = HttpMethod.Post, ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage( MsalTestConstants.UniqueId, MsalTestConstants.DisplayableId, MsalTestConstants.Scope.ToArray()) }); // ForceRefresh=true, so skip cache lookup of Access Token // Use refresh token to acquire a new Access Token Task <AuthenticationResult> task = app .AcquireTokenSilent( MsalTestConstants.Scope.ToArray(), new Account(MsalTestConstants.UserIdentifier, MsalTestConstants.DisplayableId, null)) .WithAuthority(MsalTestConstants.AuthorityCommonTenant) .WithForceRefresh(true) .ExecuteAsync(CancellationToken.None); AuthenticationResult result = task.Result; Assert.IsNotNull(result); Assert.AreEqual(MsalTestConstants.DisplayableId, result.Account.Username); Assert.AreEqual(MsalTestConstants.Scope.ToArray().AsSingleString(), result.Scopes.AsSingleString()); Assert.AreEqual(1, app.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count()); Assert.AreEqual(1, app.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count()); httpManager.AddMockHandlerForTenantEndpointDiscovery(MsalTestConstants.AuthorityGuidTenant2); httpManager.AddMockHandler( new MockHttpMessageHandler() { ExpectedMethod = HttpMethod.Post, ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage( MsalTestConstants.UniqueId, MsalTestConstants.DisplayableId, MsalTestConstants.Scope.ToArray()) }); Task <AuthenticationResult> task2 = app .AcquireTokenSilent( MsalTestConstants.Scope.ToArray(), new Account(MsalTestConstants.UserIdentifier, MsalTestConstants.DisplayableId, null)) .WithAuthority(MsalTestConstants.AuthorityGuidTenant2) .WithForceRefresh(true) .ExecuteAsync(CancellationToken.None); // Same user, scopes, clientId, but different authority // Should result in new AccessToken, but same refresh token AuthenticationResult result2 = task2.Result; Assert.IsNotNull(result2); Assert.AreEqual(MsalTestConstants.DisplayableId, result2.Account.Username); Assert.AreEqual(MsalTestConstants.Scope.ToArray().AsSingleString(), result2.Scopes.AsSingleString()); Assert.AreEqual(2, app.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count()); Assert.AreEqual(1, app.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count()); httpManager.AddMockHandlerForTenantEndpointDiscovery(MsalTestConstants.AuthorityGuidTenant); httpManager.AddMockHandler( new MockHttpMessageHandler() { ExpectedMethod = HttpMethod.Post, ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage( MsalTestConstants.UniqueId, MsalTestConstants.DisplayableId, MsalTestConstants.Scope.ToArray()) }); // Same user, scopes, clientId, but different authority // Should result in new AccessToken, but same refresh token Task <AuthenticationResult> task3 = app .AcquireTokenSilent( MsalTestConstants.Scope.ToArray(), new Account(MsalTestConstants.UserIdentifier, MsalTestConstants.DisplayableId, null)) .WithAuthority(MsalTestConstants.AuthorityGuidTenant) .WithForceRefresh(true) .ExecuteAsync(CancellationToken.None); AuthenticationResult result3 = task3.Result; Assert.IsNotNull(result3); Assert.AreEqual(MsalTestConstants.DisplayableId, result3.Account.Username); Assert.AreEqual(MsalTestConstants.Scope.ToArray().AsSingleString(), result3.Scopes.AsSingleString()); Assert.AreEqual(3, app.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count()); Assert.AreEqual(1, app.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count()); // Use same authority as above, number of access tokens should remain constant httpManager.AddMockHandler( new MockHttpMessageHandler() { ExpectedMethod = HttpMethod.Post, ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage( MsalTestConstants.UniqueId, MsalTestConstants.DisplayableId, MsalTestConstants.Scope.ToArray()) }); Task <AuthenticationResult> task4 = app .AcquireTokenSilent( MsalTestConstants.Scope.ToArray(), new Account(MsalTestConstants.UserIdentifier, MsalTestConstants.DisplayableId, null)) .WithAuthority(MsalTestConstants.AuthorityGuidTenant) .WithForceRefresh(true) .ExecuteAsync(CancellationToken.None); AuthenticationResult result4 = task4.Result; Assert.IsNotNull(result4); Assert.AreEqual(MsalTestConstants.DisplayableId, result4.Account.Username); Assert.AreEqual(MsalTestConstants.Scope.ToArray().AsSingleString(), result4.Scopes.AsSingleString()); Assert.AreEqual(3, app.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count()); Assert.AreEqual(1, app.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count()); } }
/// <inheritdoc /> protected override async Task <IEnumerable <CacheExecutorAccountResult> > InternalExecuteAsync(TestInputData testInputData) { string resource = TestInputData.MsGraph; string[] scopes = new[] { resource + "/user.read" }; var results = new List <CacheExecutorAccountResult>(); foreach (var labUserData in testInputData.LabUserDatas) { var app = PublicClientApplicationBuilder .Create(labUserData.ClientId) .WithAuthority(new Uri(labUserData.Authority), true) .WithLogging((LogLevel level, string message, bool containsPii) => { Console.WriteLine("{0}: {1}", level, message); }) .Build(); FileBasedTokenCacheHelper.ConfigureUserCache( testInputData.StorageType, app.UserTokenCache, CommonCacheTestUtils.AdalV3CacheFilePath, CommonCacheTestUtils.MsalV2CacheFilePath, CommonCacheTestUtils.MsalV3CacheFilePath); IEnumerable <IAccount> accounts = await app.GetAccountsAsync().ConfigureAwait(false); IAccount accountToReference = accounts.FirstOrDefault(x => x.Username.Equals(labUserData.Upn, StringComparison.OrdinalIgnoreCase)); try { var result = await app .AcquireTokenSilent(scopes, accountToReference) .WithAuthority(app.Authority) .WithForceRefresh(false) .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); Console.WriteLine($"got token for '{result.Account.Username}' from the cache"); results.Add(new CacheExecutorAccountResult(labUserData.Upn, result.Account.Username, true)); } catch (MsalUiRequiredException) { var result = await app .AcquireTokenByUsernamePassword(scopes, labUserData.Upn, labUserData.Password.ToSecureString()) .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); if (string.IsNullOrWhiteSpace(result.AccessToken)) { results.Add(new CacheExecutorAccountResult(labUserData.Upn, string.Empty, false)); } else { Console.WriteLine($"got token for '{result.Account.Username}' without the cache"); results.Add(new CacheExecutorAccountResult(labUserData.Upn, result.Account.Username, false)); } } } return(results); }
public async Task <IAzureWorkspace?> GetAuthenticatedWorkspaceAsync( IChannel channel, ILogger?logger, string resourceGroupName, string workspaceName, bool refreshCredentials) { if (Type == AzureEnvironmentType.Mock) { channel.Stdout("AZURE_QUANTUM_ENV set to Mock. Using mock Azure workspace rather than connecting to the real service."); return(new MockAzureWorkspace(workspaceName)); } // Find the token cache folder var cacheDirectoryEnvVarName = "AZURE_QUANTUM_TOKEN_CACHE"; var cacheDirectory = System.Environment.GetEnvironmentVariable(cacheDirectoryEnvVarName); if (string.IsNullOrEmpty(cacheDirectory)) { cacheDirectory = Path.Join(System.Environment.GetFolderPath(System.Environment.SpecialFolder.UserProfile), ".azure-quantum"); } // Register the token cache for serialization var cacheFileName = "iqsharp.bin"; var storageCreationProperties = new StorageCreationPropertiesBuilder(cacheFileName, cacheDirectory, ClientId) .WithMacKeyChain( serviceName: "Microsoft.Quantum.IQSharp", accountName: "MSALCache") .WithLinuxKeyring( schemaName: "com.microsoft.quantum.iqsharp", collection: "default", secretLabel: "Credentials used by Microsoft IQ# kernel", attribute1: new KeyValuePair <string, string>("Version", typeof(AzureClient).Assembly.GetName().Version.ToString()), attribute2: new KeyValuePair <string, string>("ProductGroup", "QDK")) .Build(); MsalCacheHelper?cacheHelper; try { cacheHelper = await MsalCacheHelper.CreateAsync(storageCreationProperties); cacheHelper.VerifyPersistence(); } catch (MsalCachePersistenceException e) { // Will occur on Linux if encryption is unavailable. Fallback to unencrypted cache on Linux, as documented here: // https://github.com/AzureAD/microsoft-authentication-extensions-for-dotnet/blob/master/docs/keyring_fallback_proposal.md var unencryptedCacheFileName = "iqsharp-unencrypted.bin"; logger?.LogWarning(e, "Encrypted credential cache is unavailable. Cache will be stored in plaintext at {Path}. Error: {Message}", Path.Combine(cacheDirectory, unencryptedCacheFileName), e.Message); storageCreationProperties = new StorageCreationPropertiesBuilder(unencryptedCacheFileName, cacheDirectory, ClientId) .WithMacKeyChain( serviceName: "Microsoft.Quantum.IQSharp", accountName: "MSALCache") .WithLinuxUnprotectedFile() .Build(); cacheHelper = await MsalCacheHelper.CreateAsync(storageCreationProperties); cacheHelper.VerifyPersistence(); } var msalApp = PublicClientApplicationBuilder.Create(ClientId).WithAuthority(Authority).Build(); cacheHelper.RegisterCache(msalApp.UserTokenCache); // Perform the authentication bool shouldShowLoginPrompt = refreshCredentials; AuthenticationResult?authenticationResult = null; if (!shouldShowLoginPrompt) { try { var accounts = await msalApp.GetAccountsAsync(); authenticationResult = await msalApp.AcquireTokenSilent( Scopes, accounts.FirstOrDefault()).WithAuthority(msalApp.Authority).ExecuteAsync(); } catch (MsalUiRequiredException) { shouldShowLoginPrompt = true; } } if (shouldShowLoginPrompt) { authenticationResult = await msalApp.AcquireTokenWithDeviceCode( Scopes, deviceCodeResult => { channel.Stdout(deviceCodeResult.Message); return(Task.FromResult(0)); }).WithAuthority(msalApp.Authority).ExecuteAsync(); } if (authenticationResult == null) { return(null); } // Construct and return the AzureWorkspace object var credentials = new Rest.TokenCredentials(authenticationResult.AccessToken); var azureQuantumClient = new QuantumClient(credentials) { SubscriptionId = SubscriptionId, ResourceGroupName = resourceGroupName, WorkspaceName = workspaceName, BaseUri = BaseUri, }; var azureQuantumWorkspace = new Azure.Quantum.Workspace( azureQuantumClient.SubscriptionId, azureQuantumClient.ResourceGroupName, azureQuantumClient.WorkspaceName, authenticationResult?.AccessToken, BaseUri); return(new AzureWorkspace(azureQuantumClient, azureQuantumWorkspace)); }
public async Task AcquireTokenSilent_ValidATs_ParallelRequests_Async() { // Arrange const int NumberOfRequests = 10; using (MockHttpAndServiceBundle harness = CreateTestHarness()) { PublicClientApplication pca = PublicClientApplicationBuilder .Create(TestConstants.ClientId) .WithHttpManager(harness.HttpManager) .BuildConcrete(); ConfigureCacheSerialization(pca); var actualUsers = new List <string>(); for (int i = 1; i <= NumberOfRequests; i++) { var user = GetUpn(i); _tokenCacheHelper.PopulateCache(pca.UserTokenCacheInternal.Accessor, GetUid(i), "utid", displayableId: user); actualUsers.Add(user); } byte[] bytes = (pca.UserTokenCacheInternal as ITokenCacheSerializer).SerializeMsalV3(); _inMemoryCache = Encoding.UTF8.GetString(bytes); pca.UserTokenCacheInternal.Accessor.AssertItemCount( expectedAtCount: NumberOfRequests * 2, expectedRtCount: NumberOfRequests, expectedAccountCount: NumberOfRequests, expectedIdtCount: NumberOfRequests, expectedAppMetadataCount: 1); IEnumerable <IAccount> accounts = await pca.GetAccountsAsync().ConfigureAwait(false); AuthenticationResult[] results; // Act using (new PerformanceValidator( NumberOfRequests * (2 * CacheAccessPenaltyMs + 100), "AcquireTokenSilent should take roughly 100ms for its internal logic, " + "plus the time needed to access the cache and all the thread context switches")) { // execute won't start here because IEnumerable is lazy IEnumerable <Task <AuthenticationResult> > tasks = accounts.Select(acc => pca.AcquireTokenSilent(TestConstants.s_scope, acc).ExecuteAsync()); // execution starts here Task <AuthenticationResult>[] taskArray = tasks.ToArray(); // wait for all requests to complete results = await Task.WhenAll(taskArray).ConfigureAwait(false); } // Assert CollectionAssert.AreEquivalent( actualUsers, results.Select(r => r.Account.Username).ToArray()); // Expecting the number of cache accesses to be equal to the number of request plus one for GetAccounts Assert.AreEqual(NumberOfRequests + 1, _afterAccessCalls); Assert.AreEqual(NumberOfRequests + 1, _beforeAccessCalls); // Acquire token silent with valid ATs in the cache -> no data is written Assert.AreEqual(0, _beforeWriteCalls); Assert.AreEqual(0, _afterAccessWriteCalls); } }
public async Task AcquireTokenSilent_ExpiredATs_ParallelRequests_Async() { // Arrange const int NumberOfRequests = 10; // The typical HttpMockHandler used by other tests can't deal with parallel request ParallelRequestMockHanler httpManager = new ParallelRequestMockHanler(); PublicClientApplication pca = PublicClientApplicationBuilder .Create(TestConstants.ClientId) .WithHttpManager(httpManager) .BuildConcrete(); ConfigureCacheSerialization(pca); var actualUsers = new List <string>(); for (int i = 1; i <= NumberOfRequests; i++) { _tokenCacheHelper.PopulateCache( pca.UserTokenCacheInternal.Accessor, GetUid(i), TestConstants.Utid, displayableId: GetUpn(i), rtSecret: i.ToString(CultureInfo.InvariantCulture), // this will help create a valid response expiredAccessTokens: true); actualUsers.Add(GetUpn(i)); } byte[] bytes = (pca.UserTokenCacheInternal as ITokenCacheSerializer).SerializeMsalV3(); _inMemoryCache = Encoding.UTF8.GetString(bytes); pca.UserTokenCacheInternal.Accessor.AssertItemCount( expectedAtCount: NumberOfRequests * 2, expectedRtCount: NumberOfRequests, expectedAccountCount: NumberOfRequests, expectedIdtCount: NumberOfRequests, expectedAppMetadataCount: 1); IEnumerable <IAccount> accounts = await pca.GetAccountsAsync().ConfigureAwait(false); AuthenticationResult[] results; // Act using (new PerformanceValidator( NumberOfRequests * (2 * CacheAccessPenaltyMs + NetworkAccessPenaltyMs /* refresh the RT */ + 100 /* internal logic */) + 2 * NetworkAccessPenaltyMs, /* one time discovery calls */ "AcquireTokenSilent in parallel should take roughly 100ms for its internal logic, " + "plus the time needed to access the cache, the network, and all the thread context switches")) { // execute won't start here because IEnumerable is lazy IEnumerable <Task <AuthenticationResult> > tasks = accounts.Select(acc => pca.AcquireTokenSilent(TestConstants.s_scope, acc).ExecuteAsync()); // execution starts here Task <AuthenticationResult>[] taskArray = tasks.ToArray(); // wait for all requests to complete results = await Task.WhenAll(taskArray).ConfigureAwait(false); } // Assert CollectionAssert.AreEquivalent( actualUsers, results.Select(r => r.Account.Username).ToArray()); // Each task will write tokens Assert.AreEqual(NumberOfRequests, _beforeWriteCalls); Assert.AreEqual(NumberOfRequests, _afterAccessWriteCalls); // Expecting the number of cache accesses to be equal to twice the number of requests // (one for the initial read access, one for when writing the tokens) // plus one for GetAccounts Assert.AreEqual(NumberOfRequests * 2 + 1, _afterAccessCalls); Assert.AreEqual(NumberOfRequests * 2 + 1, _beforeAccessCalls); }
public MicrosoftAuthentication(AuthenticationSettings authSettings) { AuthSettings = authSettings; PublicClientApp = PublicClientApplicationBuilder.Create(AuthSettings.ClientId).WithAuthority(AzureCloudInstance.AzurePublic, AuthSettings.Tenant, true).WithRedirectUri("http://localhost").Build(); }
public async Task TestSerializationViaAsync() { int numBeforeAccessCalls = 0; int numAfterAccessCalls = 0; int numBeforeWriteCalls = 0; byte[] serializedPayload = null; var sb = new StringBuilder(); using (var harness = CreateTestHarness()) { harness.HttpManager.AddInstanceDiscoveryMockHandler(); PublicClientApplication pca = PublicClientApplicationBuilder .Create(TestConstants.ClientId) .WithAuthority(new Uri(ClientApplicationBase.DefaultAuthority), true) .WithHttpManager(harness.HttpManager) .WithTelemetry(new TraceTelemetryConfig()) .BuildConcrete(); pca.UserTokenCache.SetBeforeAccessAsync(async args => { sb.Append("beforeaccess-"); numBeforeAccessCalls++; // Task Delay is so that we have an await within the async callback and also to simulate // some level of time that we did work. await Task.Delay(10).ConfigureAwait(false); }); pca.UserTokenCache.SetAfterAccessAsync(async args => { sb.Append("afteraccess-"); numAfterAccessCalls++; serializedPayload = args.TokenCache.SerializeMsalV3(); await Task.Delay(10).ConfigureAwait(false); }); pca.UserTokenCache.SetBeforeWriteAsync(async args => { sb.Append("beforewrite-"); numBeforeWriteCalls++; await Task.Delay(10).ConfigureAwait(false); }); pca.ServiceBundle.ConfigureMockWebUI( AuthorizationResult.FromUri(pca.AppConfig.RedirectUri + "?code=some-code")); harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(TestConstants.AuthorityCommonTenant); AuthenticationResult result = await pca .AcquireTokenInteractive(TestConstants.s_scope) .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); } Assert.AreEqual("beforeaccess-beforewrite-afteraccess-", sb.ToString()); Assert.AreEqual(1, numBeforeAccessCalls); Assert.AreEqual(1, numAfterAccessCalls); Assert.AreEqual(1, numBeforeWriteCalls); Assert.IsNotNull(serializedPayload); }
public static async Task Run() { ///////////////// // // Configuration // ///////////////// AzureAdOptions azureAdOptions = new AzureAdOptions(); var settingsFilename = System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), "appsettings.json"); var builder = new ConfigurationBuilder() .AddJsonFile(settingsFilename, optional: false) .AddUserSecrets <Program>(); var config = builder.Build(); config.Bind("AzureAd", azureAdOptions); //////////////////////////// // // Graph Client with Logger // //////////////////////////// var logger = new StringBuilderHttpMessageLogger(); /* * Could also use the Console if preferred... * * var logger = new ConsoleHttpMessageLogger(); */ var pca = PublicClientApplicationBuilder .Create(azureAdOptions.ClientId) .WithTenantId(azureAdOptions.TenantId) .Build(); var scopes = new string[] { "https://graph.microsoft.com/Mail.Read" }; IAuthenticationProvider ap = new DeviceCodeProvider(pca, scopes); using (LoggingMessageHandler loggingHandler = new LoggingMessageHandler(logger)) using (HttpProvider hp = new HttpProvider(loggingHandler, false, new Serializer())) { GraphServiceClient graphServiceClient = new GraphServiceClient(ap, hp); //////////////////////////// // // Setup is complete, run the sample // //////////////////////////// var messages = await graphServiceClient .Me .Messages .Request() .Top(1) .GetAsync(); Console.WriteLine($"ID: {messages.CurrentPage[0].Id}"); Console.WriteLine(); var messagesI = await graphServiceClient .Me .Messages .Request() .WithImmutableId() .Top(1) .GetAsync(); Console.WriteLine($"ImmutableId: {messagesI.CurrentPage[0].Id}"); Console.WriteLine(); Console.WriteLine("Press enter to show log"); Console.ReadLine(); Console.WriteLine(); Console.WriteLine(logger.GetLog()); } }
private async Task <AuthenticationResult> AcquireTokenAsync(int userIndex, Metrics localMetrics) { var scopes = new string[] { _options.ApiScopes }; var upn = $"{_options.UsernamePrefix}{userIndex}@{_options.TenantDomain}"; var builder = PublicClientApplicationBuilder .Create(_options.ClientId) .WithAuthority(TestConstants.AadInstance, TestConstants.Organizations); if (_options.EnableMsalLogging) { builder.WithLogging(Logger.Log, LogLevel.Error, false); } var msalPublicClient = builder.Build(); TokenCacheHelper.EnableSerialization(msalPublicClient.UserTokenCache); AuthenticationResult authResult = null; try { try { var identifier = _userAccountIdentifiers[userIndex]; IAccount account = null; if (identifier != null) { var stopwatch = new Stopwatch(); stopwatch.Start(); account = await msalPublicClient.GetAccountAsync(identifier).ConfigureAwait(false); stopwatch.Stop(); localMetrics.TotalMsalLookupTimeInMilliseconds += stopwatch.Elapsed.TotalMilliseconds; } authResult = await msalPublicClient.AcquireTokenSilent(scopes, account).ExecuteAsync(CancellationToken.None).ConfigureAwait(false); return(authResult); } catch (MsalUiRequiredException) { // Delay to prevent spamming the STS with calls. await Task.Delay(_options.RequestDelayInMilliseconds); authResult = await msalPublicClient.AcquireTokenByUsernamePassword( scopes, upn, new NetworkCredential( upn, _options.UserPassword).SecurePassword) .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); _userAccountIdentifiers[userIndex] = authResult.Account.HomeAccountId.Identifier; return(authResult); } } catch (Exception ex) { Console.WriteLine($"Exception in AcquireTokenAsync: {ex}"); } return(authResult); }
public async Task AuthorityMigrationTestAsync() { // make sure that for all network calls "preferred_cache" environment is used // (it is taken from metadata in instance discovery response), // except very first network call - instance discovery using (var httpManager = new MockHttpManager()) { httpManager.AddInstanceDiscoveryMockHandler(); var authorityUri = new Uri( string.Format( CultureInfo.InvariantCulture, "https://{0}/common", MsalTestConstants.ProductionNotPrefEnvironmentAlias)); var app = PublicClientApplicationBuilder .Create(MsalTestConstants.ClientId) .WithAuthority(authorityUri, true) .WithHttpManager(httpManager) .WithUserTokenLegacyCachePersistenceForTest(new TestLegacyCachePersistance()) .WithTelemetry(new TraceTelemetryConfig()) .WithDebugLoggingCallback() .BuildConcrete(); // mock for openId config request httpManager.AddMockHandler(new MockHttpMessageHandler { ExpectedUrl = string.Format(CultureInfo.InvariantCulture, "https://{0}/common/v2.0/.well-known/openid-configuration", MsalTestConstants.ProductionPrefNetworkEnvironment), ExpectedMethod = HttpMethod.Get, ResponseMessage = MockHelpers.CreateOpenIdConfigurationResponse(MsalTestConstants.AuthorityHomeTenant) }); // mock webUi authorization MsalMockHelpers.ConfigureMockWebUI( app.ServiceBundle.PlatformProxy, AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code"), null, MsalTestConstants.ProductionPrefNetworkEnvironment); // mock token request httpManager.AddMockHandler(new MockHttpMessageHandler { ExpectedUrl = string.Format(CultureInfo.InvariantCulture, "https://{0}/home/oauth2/v2.0/token", MsalTestConstants.ProductionPrefNetworkEnvironment), ExpectedMethod = HttpMethod.Post, ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage() }); AuthenticationResult result = app.AcquireTokenInteractive(MsalTestConstants.Scope).ExecuteAsync(CancellationToken.None).Result; // make sure that all cache entities are stored with "preferred_cache" environment // (it is taken from metadata in instance discovery response) await ValidateCacheEntitiesEnvironmentAsync(app.UserTokenCacheInternal, MsalTestConstants.ProductionPrefCacheEnvironment).ConfigureAwait(false); // silent request targeting at, should return at from cache for any environment alias foreach (var envAlias in MsalTestConstants.ProdEnvAliases) { result = await app .AcquireTokenSilent( MsalTestConstants.Scope, app.GetAccountsAsync().Result.First()) .WithAuthority(string.Format(CultureInfo.InvariantCulture, "https://{0}/{1}/", envAlias, MsalTestConstants.Utid)) .WithForceRefresh(false) .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); Assert.IsNotNull(result); } // mock for openId config request for tenant specific authority httpManager.AddMockHandler(new MockHttpMessageHandler { ExpectedUrl = string.Format(CultureInfo.InvariantCulture, "https://{0}/{1}/v2.0/.well-known/openid-configuration", MsalTestConstants.ProductionPrefNetworkEnvironment, MsalTestConstants.Utid), ExpectedMethod = HttpMethod.Get, ResponseMessage = MockHelpers.CreateOpenIdConfigurationResponse(MsalTestConstants.AuthorityUtidTenant) }); // silent request targeting rt should find rt in cache for authority with any environment alias foreach (var envAlias in MsalTestConstants.ProdEnvAliases) { result = null; httpManager.AddMockHandler(new MockHttpMessageHandler() { ExpectedUrl = string.Format(CultureInfo.InvariantCulture, "https://{0}/{1}/oauth2/v2.0/token", MsalTestConstants.ProductionPrefNetworkEnvironment, MsalTestConstants.Utid), ExpectedMethod = HttpMethod.Post, ExpectedPostData = new Dictionary <string, string>() { { "grant_type", "refresh_token" } }, // return not retriable status code ResponseMessage = MockHelpers.CreateInvalidGrantTokenResponseMessage() }); try { result = await app .AcquireTokenSilent( MsalTestConstants.ScopeForAnotherResource, (await app.GetAccountsAsync().ConfigureAwait(false)).First()) .WithAuthority(string.Format(CultureInfo.InvariantCulture, "https://{0}/{1}/", envAlias, MsalTestConstants.Utid)) .WithForceRefresh(false) .ExecuteAsync(CancellationToken.None).ConfigureAwait(false); } catch (MsalUiRequiredException) { } catch (Exception) { Assert.Fail(); } Assert.IsNull(result); } } }
private async Task RunOnBehalfOfTestAsync(LabResponse labResponse) { LabUser user = labResponse.User; string oboHost; string secret; string authority; string publicClientID; string confidentialClientID; string[] oboScope; switch (labResponse.User.AzureEnvironment) { case AzureEnvironment.azureusgovernment: oboHost = ArlingtonCloudHost; secret = _keyVault.GetSecret(TestConstants.MsalArlingtonOBOKeyVaultUri).Value; authority = labResponse.Lab.Authority + "organizations"; publicClientID = ArlingtonPublicClientIDOBO; confidentialClientID = ArlingtonConfidentialClientIDOBO; oboScope = s_arlingtonOBOServiceScope; break; default: oboHost = PublicCloudHost; secret = _keyVault.GetSecret(TestConstants.MsalOBOKeyVaultUri).Value; authority = TestConstants.AuthorityOrganizationsTenant; publicClientID = PublicCloudPublicClientIDOBO; confidentialClientID = PublicCloudConfidentialClientIDOBO; oboScope = s_publicCloudOBOServiceScope; break; } //TODO: acquire scenario specific client ids from the lab response SecureString securePassword = new NetworkCredential("", user.GetOrFetchPassword()).SecurePassword; var msalPublicClient = PublicClientApplicationBuilder.Create(publicClientID) .WithAuthority(authority) .WithRedirectUri(TestConstants.RedirectUri) .WithTestLogging() .Build(); var builder = msalPublicClient.AcquireTokenByUsernamePassword(oboScope, user.Upn, securePassword); builder.WithAuthority(authority); var authResult = await builder.ExecuteAsync().ConfigureAwait(false); var confidentialApp = ConfidentialClientApplicationBuilder .Create(confidentialClientID) .WithAuthority(new Uri(oboHost + authResult.TenantId), true) .WithClientSecret(secret) .WithTestLogging() .Build(); var userCacheRecorder = confidentialApp.UserTokenCache.RecordAccess(); UserAssertion userAssertion = new UserAssertion(authResult.AccessToken); string atHash = userAssertion.AssertionHash; authResult = await confidentialApp.AcquireTokenOnBehalfOf(s_scopes, userAssertion) .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); MsalAssert.AssertAuthResult(authResult, user); Assert.AreEqual(atHash, userCacheRecorder.LastAfterAccessNotificationArgs.SuggestedCacheKey); await confidentialApp.GetAccountsAsync().ConfigureAwait(false); Assert.IsNull(userCacheRecorder.LastAfterAccessNotificationArgs.SuggestedCacheKey); }
/// <summary> /// Generates and returns Access token /// </summary> /// <param name="appSettings">Contains appsettings.json configuration values</param> /// <returns></returns> public static string GetAccessToken(IOptions <ConfigurationModel> appSettings) { AuthenticationResult authenticationResult = null; if (appSettings.Value.AuthenticationMode.Equals("masteruser", StringComparison.InvariantCultureIgnoreCase)) { // Create a public client to authorize the app with the AAD app IPublicClientApplication clientApp = PublicClientApplicationBuilder.Create(appSettings.Value.ClientId).WithAuthority(appSettings.Value.AuthorityUri).Build(); var userAccounts = clientApp.GetAccountsAsync().Result; try { // Retrieve Access token from cache if available authenticationResult = clientApp.AcquireTokenSilent(appSettings.Value.Scope, userAccounts.FirstOrDefault()).ExecuteAsync().Result; } catch (MsalUiRequiredException) { try { SecureString password = new SecureString(); foreach (var key in appSettings.Value.PbiPassword) { password.AppendChar(key); } authenticationResult = clientApp.AcquireTokenByUsernamePassword(appSettings.Value.Scope, appSettings.Value.PbiUsername, password).ExecuteAsync().Result; } catch (MsalException) { throw; } } } else if (appSettings.Value.AuthenticationMode.Equals("serviceprincipal", StringComparison.InvariantCultureIgnoreCase)) { // For app only authentication, we need the specific tenant id in the authority url var tenantSpecificUrl = appSettings.Value.AuthorityUri.Replace("organizations", appSettings.Value.TenantId); // Create a confidetial client to authorize the app with the AAD app IConfidentialClientApplication clientApp = ConfidentialClientApplicationBuilder .Create(appSettings.Value.ClientId) .WithClientSecret(appSettings.Value.ClientSecret) .WithAuthority(tenantSpecificUrl) .Build(); try { // Make a client call if Access token is not available in cache authenticationResult = clientApp.AcquireTokenForClient(appSettings.Value.Scope).ExecuteAsync().Result; } catch (MsalException) { throw; } } try { return(authenticationResult.AccessToken); } catch (Exception) { throw; } }
public void UnifiedCache_MsalStoresToAndReadRtFromAdalCache() { using (var mocks = new MockHttpAndServiceBundle()) { var httpManager = mocks.HttpManager; httpManager.AddInstanceDiscoveryMockHandler(); var app = PublicClientApplicationBuilder.Create(TestConstants.ClientId) .WithAuthority(new Uri(ClientApplicationBase.DefaultAuthority), true) .WithHttpManager(httpManager) .WithTelemetry(new TraceTelemetryConfig()) .WithUserTokenLegacyCachePersistenceForTest( new TestLegacyCachePersistance()) .BuildConcrete(); app.ServiceBundle.ConfigureMockWebUI( AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code")); HttpResponseMessage response = MockHelpers.CreateSuccessTokenResponseMessageWithUid( TestConstants.Uid, TestConstants.Utid, "*****@*****.**"); httpManager.AddResponseMockHandlerForPost(response); AuthenticationResult result = app.AcquireTokenInteractive(TestConstants.s_scope).ExecuteAsync(CancellationToken.None).Result; Assert.IsNotNull(result); // make sure Msal stored RT in Adal cache IDictionary <AdalTokenCacheKey, AdalResultWrapper> adalCacheDictionary = AdalCacheOperations.Deserialize(app.ServiceBundle.DefaultLogger, app.UserTokenCacheInternal.LegacyPersistence.LoadCache()); Assert.IsTrue(adalCacheDictionary.Count == 1); var requestContext = new RequestContext(app.ServiceBundle, Guid.NewGuid()); var authority = Microsoft.Identity.Client.Instance.Authority.CreateAuthorityForRequest( requestContext.ServiceBundle.Config.AuthorityInfo, null); AuthenticationRequestParameters reqParams = new AuthenticationRequestParameters( mocks.ServiceBundle, app.UserTokenCacheInternal, new Client.ApiConfig.Parameters.AcquireTokenCommonParameters(), requestContext, authority); var accounts = app.UserTokenCacheInternal.GetAccountsAsync(reqParams).Result; foreach (IAccount account in accounts) { app.UserTokenCacheInternal.RemoveMsalAccountWithNoLocks(account, requestContext); } Assert.AreEqual(0, httpManager.QueueSize); httpManager.AddMockHandler( new MockHttpMessageHandler() { ExpectedMethod = HttpMethod.Post, ExpectedPostData = new Dictionary <string, string>() { { "grant_type", "refresh_token" } }, ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage( TestConstants.UniqueId, TestConstants.DisplayableId, TestConstants.s_scope.ToArray()) }); // Using RT from Adal cache for silent call AuthenticationResult result1 = app .AcquireTokenSilent(TestConstants.s_scope, result.Account) .WithAuthority(TestConstants.AuthorityCommonTenant) .WithForceRefresh(false) .ExecuteAsync(CancellationToken.None) .Result; Assert.IsNotNull(result1); } }
public async Task WAM_AccountIds_GetMerged_Async() { // Arrange using (var httpManager = new MockHttpManager()) { var cache = new InMemoryTokenCache(); httpManager.AddInstanceDiscoveryMockHandler(); var mockBroker = Substitute.For <IBroker>(); mockBroker.IsBrokerInstalledAndInvokable().Returns(true); var msalTokenResponse1 = CreateMsalTokenResponseFromWam("wam1"); var msalTokenResponse2 = CreateMsalTokenResponseFromWam("wam2"); var msalTokenResponse3 = CreateMsalTokenResponseFromWam("wam3"); // 2 apps must share the token cache, like FOCI apps, for this test to be interesting var pca1 = PublicClientApplicationBuilder.Create(TestConstants.ClientId) .WithExperimentalFeatures(true) .WithTestBroker(mockBroker) .WithHttpManager(httpManager) .BuildConcrete(); var pca2 = PublicClientApplicationBuilder.Create(TestConstants.ClientId2) .WithExperimentalFeatures(true) .WithTestBroker(mockBroker) .WithHttpManager(httpManager) .BuildConcrete(); cache.Bind(pca1.UserTokenCache); cache.Bind(pca2.UserTokenCache); pca1.ServiceBundle.Config.BrokerCreatorFunc = (app, config, logger) => mockBroker; pca2.ServiceBundle.Config.BrokerCreatorFunc = (app, config, logger) => mockBroker; // Act mockBroker.AcquireTokenInteractiveAsync(null, null).ReturnsForAnyArgs(Task.FromResult(msalTokenResponse1)); await pca1.AcquireTokenInteractive(TestConstants.s_scope).ExecuteAsync().ConfigureAwait(false); // this should override wam1 id mockBroker.AcquireTokenInteractiveAsync(null, null).ReturnsForAnyArgs(Task.FromResult(msalTokenResponse2)); await pca1.AcquireTokenInteractive(TestConstants.s_scope).ExecuteAsync().ConfigureAwait(false); mockBroker.AcquireTokenInteractiveAsync(null, null).ReturnsForAnyArgs(Task.FromResult(msalTokenResponse3)); await pca2.AcquireTokenInteractive(TestConstants.s_scope).ExecuteAsync().ConfigureAwait(false); var accounts1 = await pca1.GetAccountsAsync().ConfigureAwait(false); var accounts2 = await pca2.GetAccountsAsync().ConfigureAwait(false); // Assert #if SUPPORTS_BROKER var wamAccountIds = (accounts1.Single() as Account).WamAccountIds; Assert.AreEqual(2, wamAccountIds.Count); Assert.AreEqual("wam2", wamAccountIds[TestConstants.ClientId]); Assert.AreEqual("wam3", wamAccountIds[TestConstants.ClientId2]); CoreAssert.AssertDictionariesAreEqual(wamAccountIds, (accounts2.Single() as Account).WamAccountIds, StringComparer.Ordinal); #else Assert.IsTrue(accounts1.All(a => (a as IAccountInternal).WamAccountIds == null)); Assert.IsTrue(accounts2.All(a => (a as IAccountInternal).WamAccountIds == null)); #endif } }
private async Task <AuthenticationResult> RunTestForUserAsync(LabResponse labResponse, bool directToAdfs = false) { IPublicClientApplication pca; if (directToAdfs) { pca = PublicClientApplicationBuilder .Create(Adfs2019LabConstants.PublicClientId) .WithRedirectUri(Adfs2019LabConstants.ClientRedirectUri) .WithAdfsAuthority(Adfs2019LabConstants.Authority) .Build(); } else { pca = PublicClientApplicationBuilder .Create(labResponse.App.AppId) .WithRedirectUri(SeleniumWebUI.FindFreeLocalhostRedirectUri()) .WithAuthority(labResponse.Lab.Authority + "common") .Build(); } var userCacheAccess = pca.UserTokenCache.RecordAccess(); Trace.WriteLine("Part 1 - Acquire a token interactively, no login hint"); AuthenticationResult result = await pca .AcquireTokenInteractive(s_scopes) .WithCustomWebUi(CreateSeleniumCustomWebUI(labResponse.User, Prompt.SelectAccount, false, directToAdfs)) .ExecuteAsync(new CancellationTokenSource(_interactiveAuthTimeout).Token) .ConfigureAwait(false); userCacheAccess.AssertAccessCounts(0, 1); IAccount account = await MsalAssert.AssertSingleAccountAsync(labResponse, pca, result).ConfigureAwait(false); userCacheAccess.AssertAccessCounts(1, 1); // the assert calls GetAccounts Assert.IsFalse(userCacheAccess.LastNotificationArgs.IsApplicationCache); Trace.WriteLine("Part 2 - Clear the cache"); await pca.RemoveAsync(account).ConfigureAwait(false); userCacheAccess.AssertAccessCounts(1, 2); Assert.IsFalse((await pca.GetAccountsAsync().ConfigureAwait(false)).Any()); userCacheAccess.AssertAccessCounts(2, 2); Assert.IsFalse(userCacheAccess.LastNotificationArgs.IsApplicationCache); Trace.WriteLine("Part 3 - Acquire a token interactively again, with login hint"); result = await pca .AcquireTokenInteractive(s_scopes) .WithCustomWebUi(CreateSeleniumCustomWebUI(labResponse.User, Prompt.ForceLogin, true, directToAdfs)) .WithPrompt(Prompt.ForceLogin) .WithLoginHint(labResponse.User.Upn) .ExecuteAsync(new CancellationTokenSource(_interactiveAuthTimeout).Token) .ConfigureAwait(false); userCacheAccess.AssertAccessCounts(2, 3); account = await MsalAssert.AssertSingleAccountAsync(labResponse, pca, result).ConfigureAwait(false); userCacheAccess.AssertAccessCounts(3, 3); Assert.IsFalse(userCacheAccess.LastNotificationArgs.IsApplicationCache); Trace.WriteLine("Part 4 - Acquire a token silently"); result = await pca .AcquireTokenSilent(s_scopes, account) .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); await MsalAssert.AssertSingleAccountAsync(labResponse, pca, result).ConfigureAwait(false); Assert.IsFalse(userCacheAccess.LastNotificationArgs.IsApplicationCache); return(result); }
public async Task AcquireTokenByObo_NormalOboThenLongRunningAcquire_WithTheSameKey_TestAsync() { var user1 = (await LabUserHelper.GetSpecificUserAsync("*****@*****.**").ConfigureAwait(false)).User; var pca = PublicClientApplicationBuilder .Create(PublicClientID) .WithAuthority(AadAuthorityAudience.AzureAdMultipleOrgs) .Build(); var userAuthResult = await pca .AcquireTokenByUsernamePassword(s_oboServiceScope, user1.Upn, new NetworkCredential("", user1.GetOrFetchPassword()).SecurePassword) .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); var cca = BuildCCA(userAuthResult.TenantId); UserAssertion userAssertion = new UserAssertion(userAuthResult.AccessToken); string oboCacheKey = userAssertion.AssertionHash; // AcquireNormal - AT from IdP via OBO flow (only new AT cached, no RT in cache) var result = await cca.AcquireTokenOnBehalfOf(s_scopes, userAssertion).ExecuteAsync().ConfigureAwait(false); Assert.AreEqual(TokenSource.IdentityProvider, result.AuthenticationResultMetadata.TokenSource); Assert.AreEqual(1, cca.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count); Assert.AreEqual(0, cca.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count); // AcquireLR - AT from cache result = await cca.AcquireTokenInLongRunningProcess(s_scopes, oboCacheKey).ExecuteAsync().ConfigureAwait(false); Assert.AreEqual(TokenSource.Cache, result.AuthenticationResultMetadata.TokenSource); // Expire AT TokenCacheHelper.ExpireAllAccessTokens(cca.UserTokenCacheInternal); // AcquireLR - throws because no RT var exception = await AssertException.TaskThrowsAsync <MsalClientException>( () => cca.AcquireTokenInLongRunningProcess(s_scopes.ToArray(), oboCacheKey) .ExecuteAsync()) .ConfigureAwait(false); Assert.AreEqual(MsalError.OboCacheKeyNotInCacheError, exception.ErrorCode); // Expire AT TokenCacheHelper.ExpireAllAccessTokens(cca.UserTokenCacheInternal); // InitiateLR - AT from IdP via OBO flow (new AT, RT cached) result = await cca.InitiateLongRunningProcessInWebApi(s_scopes, userAuthResult.AccessToken, ref oboCacheKey) .ExecuteAsync().ConfigureAwait(false); Assert.AreEqual(TokenSource.IdentityProvider, result.AuthenticationResultMetadata.TokenSource); Assert.AreEqual(1, cca.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count); Assert.AreEqual(1, cca.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count); // Expire AT TokenCacheHelper.ExpireAllAccessTokens(cca.UserTokenCacheInternal); // AcquireLR - AT from IdP via RT flow (new AT, RT cached) result = await cca.AcquireTokenInLongRunningProcess(s_scopes, oboCacheKey).ExecuteAsync().ConfigureAwait(false); Assert.AreEqual(TokenSource.IdentityProvider, result.AuthenticationResultMetadata.TokenSource); Assert.AreEqual(1, cca.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count); Assert.AreEqual(1, cca.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count); }
[WorkItem(695)] // Fix for https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/695 public void AcquireTokenSilentForceRefreshFalseMultipleTenantsTest() { using (var httpManager = new MockHttpManager()) { PublicClientApplication app = PublicClientApplicationBuilder.Create(TestConstants.ClientId) .WithAuthority(new Uri(ClientApplicationBase.DefaultAuthority), true) .WithHttpManager(httpManager) .WithTelemetry(new TraceTelemetryConfig()) .BuildConcrete(); // PopulateCache() creates two access tokens TokenCacheHelper.PopulateCache(app.UserTokenCacheInternal.Accessor); Task <AuthenticationResult> task = app .AcquireTokenSilent( TestConstants.s_scope.ToArray(), new Account(TestConstants.s_userIdentifier, TestConstants.DisplayableId, null)) .WithAuthority(TestConstants.AuthorityCommonTenant) .WithForceRefresh(false) .ExecuteAsync(CancellationToken.None); AuthenticationResult result = task.Result; Assert.IsNotNull(result); Assert.AreEqual(TestConstants.DisplayableId, result.Account.Username); Assert.AreEqual(TestConstants.s_scope.ToArray().AsSingleString(), result.Scopes.AsSingleString()); Assert.AreEqual(0, httpManager.QueueSize); Assert.AreEqual(2, app.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count()); Assert.AreEqual(1, app.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count()); httpManager.AddInstanceDiscoveryMockHandler(); httpManager.AddMockHandler( new MockHttpMessageHandler() { ExpectedMethod = HttpMethod.Post, ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage( TestConstants.UniqueId, TestConstants.DisplayableId, TestConstants.s_scope.ToArray()) }); // Same user, scopes, clientId, but different authority // Should result in new AccessToken, but same refresh token Task <AuthenticationResult> task2 = app .AcquireTokenSilent( TestConstants.s_scope.ToArray(), new Account(TestConstants.s_userIdentifier, TestConstants.DisplayableId, null)) .WithAuthority(TestConstants.AuthorityGuidTenant2) .WithForceRefresh(false) .ExecuteAsync(CancellationToken.None); AuthenticationResult result2 = task2.Result; Assert.IsNotNull(result2); Assert.AreEqual(TestConstants.DisplayableId, result2.Account.Username); Assert.AreEqual(TestConstants.s_scope.ToArray().AsSingleString(), result2.Scopes.AsSingleString()); Assert.AreEqual(3, app.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count()); Assert.AreEqual(1, app.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count()); httpManager.AddMockHandler( new MockHttpMessageHandler() { ExpectedMethod = HttpMethod.Post, ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage( TestConstants.UniqueId, TestConstants.DisplayableId, TestConstants.s_scope.ToArray()) }); // Same user, scopes, clientId, but different authority // Should result in new AccessToken, but same refresh token Task <AuthenticationResult> task3 = app .AcquireTokenSilent( TestConstants.s_scope.ToArray(), new Account(TestConstants.s_userIdentifier, TestConstants.DisplayableId, null)) .WithAuthority(TestConstants.AuthorityGuidTenant) .WithForceRefresh(false) .ExecuteAsync(CancellationToken.None); AuthenticationResult result3 = task3.Result; Assert.IsNotNull(result3); Assert.AreEqual(TestConstants.DisplayableId, result3.Account.Username); Assert.AreEqual(TestConstants.s_scope.ToArray().AsSingleString(), result3.Scopes.AsSingleString()); Assert.AreEqual(4, app.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count()); Assert.AreEqual(1, app.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count()); } }
private async Task <IConfidentialClientApplication> RunOnBehalfOfTestAsync( LabUser user, bool silentCallShouldSucceed, bool forceRefresh = false) { SecureString securePassword = new NetworkCredential("", user.GetOrFetchPassword()).SecurePassword; AuthenticationResult authResult; var pca = PublicClientApplicationBuilder .Create(PublicClientID) .WithAuthority(AadAuthorityAudience.AzureAdMultipleOrgs) .WithTestLogging() .Build(); s_inMemoryTokenCache.Bind(pca.UserTokenCache); try { authResult = await pca .AcquireTokenSilent(s_oboServiceScope, user.Upn) .ExecuteAsync() .ConfigureAwait(false); Assert.AreEqual(TokenSource.Cache, authResult.AuthenticationResultMetadata.TokenSource); } catch (MsalUiRequiredException) { Assert.IsFalse(silentCallShouldSucceed, "ATS should have found a token, but it didn't"); authResult = await pca .AcquireTokenByUsernamePassword(s_oboServiceScope, user.Upn, securePassword) .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); Assert.AreEqual(TokenSource.IdentityProvider, authResult.AuthenticationResultMetadata.TokenSource); } MsalAssert.AssertAuthResult(authResult, user); Assert.IsTrue(authResult.Scopes.Any(s => string.Equals(s, s_oboServiceScope.Single(), StringComparison.OrdinalIgnoreCase))); var cca = ConfidentialClientApplicationBuilder .Create(OboConfidentialClientID) .WithAuthority(new Uri("https://login.microsoftonline.com/" + authResult.TenantId), true) .WithTestLogging(out HttpSnifferClientFactory factory) .WithClientSecret(_confidentialClientSecret) .Build(); s_inMemoryTokenCache.Bind(cca.UserTokenCache); authResult = await cca.AcquireTokenOnBehalfOf(s_scopes, new UserAssertion(authResult.AccessToken)) .WithForceRefresh(forceRefresh) .WithCcsRoutingHint("597f86cd-13f3-44c0-bece-a1e77ba43228", "f645ad92-e38d-4d1a-b510-d1b09a74a8ca") .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); if (!forceRefresh) { Assert.AreEqual( silentCallShouldSucceed, authResult.AuthenticationResultMetadata.TokenSource == TokenSource.Cache); } else { Assert.AreEqual(TokenSource.IdentityProvider, authResult.AuthenticationResultMetadata.TokenSource); } MsalAssert.AssertAuthResult(authResult, user); Assert.IsNotNull(authResult.IdToken); // https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/1950 Assert.IsTrue(authResult.Scopes.Any(s => string.Equals(s, s_scopes.Single(), StringComparison.OrdinalIgnoreCase))); AssertExtraHTTPHeadersAreSent(factory); return(cca); }
public static InteractiveAuthenticationProvider GetCredentialProvider() { IPublicClientApplication publicClientApplication = PublicClientApplicationBuilder.Create(clientId).WithTenantId(tenantId).WithDefaultRedirectUri().Build(); return(new InteractiveAuthenticationProvider(publicClientApplication)); }
public async Task OboAndSilent_Async(bool serializeCache, bool usePartitionedSerializationCache) { // Setup: Get lab users, create PCA and get user tokens var user1 = (await LabUserHelper.GetSpecificUserAsync("*****@*****.**").ConfigureAwait(false)).User; var user2 = (await LabUserHelper.GetSpecificUserAsync("*****@*****.**").ConfigureAwait(false)).User; var partitionedInMemoryTokenCache = new InMemoryPartitionedTokenCache(); var nonPartitionedInMemoryTokenCache = new InMemoryTokenCache(); var oboTokens = new HashSet <string>(); var pca = PublicClientApplicationBuilder .Create(PublicClientID) .WithAuthority(AadAuthorityAudience.AzureAdMultipleOrgs) .Build(); var user1AuthResult = await pca .AcquireTokenByUsernamePassword(s_oboServiceScope, user1.Upn, new NetworkCredential("", user1.GetOrFetchPassword()).SecurePassword) .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); var user2AuthResult = await pca .AcquireTokenByUsernamePassword(s_oboServiceScope, user2.Upn, new NetworkCredential("", user2.GetOrFetchPassword()).SecurePassword) .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); Assert.AreEqual(user1AuthResult.TenantId, user2AuthResult.TenantId); var cca = CreateCCA(); // Asserts // Silent calls should throw await AssertException.TaskThrowsAsync <MsalUiRequiredException>(() => cca.AcquireTokenSilent(s_scopes, user1.Upn) .ExecuteAsync(CancellationToken.None) ).ConfigureAwait(false); await AssertException.TaskThrowsAsync <MsalUiRequiredException>(() => cca.AcquireTokenSilent(s_scopes, user2.Upn) .ExecuteAsync(CancellationToken.None) ).ConfigureAwait(false); // User1 - no AT, RT in cache - retrieves from IdP var authResult = await cca.AcquireTokenOnBehalfOf(s_scopes, new UserAssertion(user1AuthResult.AccessToken)) .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); Assert.AreEqual(TokenSource.IdentityProvider, authResult.AuthenticationResultMetadata.TokenSource); Assert.AreEqual(CacheRefreshReason.NoCachedAccessToken, authResult.AuthenticationResultMetadata.CacheRefreshReason); oboTokens.Add(authResult.AccessToken); // User1 - finds AT in cache authResult = await cca.AcquireTokenOnBehalfOf(s_scopes, new UserAssertion(user1AuthResult.AccessToken)) .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); Assert.AreEqual(TokenSource.Cache, authResult.AuthenticationResultMetadata.TokenSource); Assert.AreEqual(CacheRefreshReason.NotApplicable, authResult.AuthenticationResultMetadata.CacheRefreshReason); oboTokens.Add(authResult.AccessToken); // User2 - no AT, RT - retrieves from IdP authResult = await cca.AcquireTokenOnBehalfOf(s_scopes, new UserAssertion(user2AuthResult.AccessToken)) .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); Assert.AreEqual(TokenSource.IdentityProvider, authResult.AuthenticationResultMetadata.TokenSource); Assert.AreEqual(CacheRefreshReason.NoCachedAccessToken, authResult.AuthenticationResultMetadata.CacheRefreshReason); oboTokens.Add(authResult.AccessToken); // User2 - finds AT in cache authResult = await cca.AcquireTokenOnBehalfOf(s_scopes, new UserAssertion(user2AuthResult.AccessToken)) .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); Assert.AreEqual(TokenSource.Cache, authResult.AuthenticationResultMetadata.TokenSource); Assert.AreEqual(CacheRefreshReason.NotApplicable, authResult.AuthenticationResultMetadata.CacheRefreshReason); oboTokens.Add(authResult.AccessToken); Assert.AreEqual(2, oboTokens.Count); // Silent calls should throw await AssertException.TaskThrowsAsync <MsalUiRequiredException>(() => cca.AcquireTokenSilent(s_scopes, user1.Upn) .ExecuteAsync(CancellationToken.None) ).ConfigureAwait(false); await AssertException.TaskThrowsAsync <MsalUiRequiredException>(() => cca.AcquireTokenSilent(s_scopes, user2.Upn) .ExecuteAsync(CancellationToken.None) ).ConfigureAwait(false); IConfidentialClientApplication CreateCCA() { var app = ConfidentialClientApplicationBuilder .Create(OboConfidentialClientID) .WithAuthority(new Uri($"https://login.microsoftonline.com/{user1AuthResult.TenantId}"), true) .WithClientSecret(_confidentialClientSecret) .WithLegacyCacheCompatibility(false) .Build(); if (serializeCache) { if (usePartitionedSerializationCache) { partitionedInMemoryTokenCache.Bind(app.UserTokenCache); } else { nonPartitionedInMemoryTokenCache.Bind(app.UserTokenCache); } } return(app); } }
protected override async void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // Create your application here SetContentView(Resource.Layout.activity_main); var check = System.Threading.Thread.CurrentThread.Name; callGraphButton = (Button)FindViewById(Resource.Id.callGraph); signOutButton = (Button)FindViewById(Resource.Id.clearCache); /* callGraphButton.Click += (sender, e) => * { * // onCallGraphClicked(); * }; * * signOutButton.Click += (sender, e) => * { * // onSignOutClicked(); * };*/ //sampleApp = ""; /* Configure your sample app and save state for this activity */ sampleApp = PublicClientApplicationBuilder.Create(ClientId).WithRedirectUri(reDirect).Build(); var scopes = mScopes.Split(' '); accessToken = string.Empty; /* try * { * IEnumerable<IAccount> accounts = await sampleApp.GetAccountsAsync(); * * if (accounts.Count() > 0) * { * IAccount firstAccount = accounts.FirstOrDefault(); * silentAuthResult = await sampleApp.AcquireTokenSilent(scopes, firstAccount).ExecuteAsync(); * * await RefreshUserDataAsync(silentAuthResult.AccessToken).ConfigureAwait(false); * * Console.WriteLine("User already signed in."); * Console.WriteLine($"Access token: {silentAuthResult.AccessToken}"); * accessToken = silentAuthResult.AccessToken; * } * } * * catch (MsalUiRequiredException) * { * // This exception is thrown when an interactive sign-in is required. * Console.WriteLine("Silent token request failed, user needs to sign-in"); * }*/ if (string.IsNullOrEmpty(accessToken)) { // Prompt the user to sign-in var interactiveRequest = await sampleApp.AcquireTokenInteractive(scopes).WithParentActivityOrWindow(this).ExecuteAsync(); await RefreshUserDataAsync(interactiveRequest.AccessToken); // var authResult = await interactiveRequest.WithParentActivityOrWindow(this).ExecuteAsync(); Console.WriteLine("Access Token: {0}", arg0: interactiveRequest.AccessToken); var intent = new Intent(this, typeof(OptionsforKids)); StartActivity(intent); AuthUIParent = this; } //code to create buttons dynamically LinearLayout linearLayout = FindViewById <LinearLayout>(Resource.Id.grace); for (int i = 0; i < 15; i++) { //You create the instance of your view in this case your Button Button button = new Button(this); button.Text = "grace"; button.SetBackgroundColor(Android.Graphics.Color.Black); button.SetTextColor(Android.Graphics.Color.White); //define the button layout LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent); //in case you want to modify other properties of the LayoutParams you use the object layoutParams.BottomMargin = 5; //Assign the layoutParams to the Button. button.LayoutParameters = layoutParams; //If you want to do something with the buttons you create you add the handle here //button.Click += (sender, e) => DoSomething(id); //Add the button as a child of your ViewGroup var check2 = System.Threading.Thread.CurrentThread.Name; RunOnUiThread(() => { linearLayout.AddView(button); }); } }
public OneDrive2FileStorage() { _publicClientApp = PublicClientApplicationBuilder.Create(ClientID) .WithRedirectUri($"msal{ClientID}://auth") .Build(); }