예제 #1
0
        public async Task PKeyAuthNonInteractiveTestAsync()
        {
            //Arrange
            var labResponse = await LabUserHelper.GetSpecificUserAsync(_deviceAuthuser).ConfigureAwait(false);

            var factory          = new HttpSnifferClientFactory();
            var msalPublicClient = PublicClientApplicationBuilder
                                   .Create(labResponse.App.AppId)
                                   .WithAuthority("https://login.microsoftonline.com/organizations/")
                                   .WithHttpClientFactory(factory)
                                   .Build();

            //Act
            var authResult = msalPublicClient.AcquireTokenByUsernamePassword(
                new[] { "user.read" },
                labResponse.User.Upn,
                new NetworkCredential("", labResponse.User.GetOrFetchPassword()).SecurePassword)
                             .WithClaims(JObject.Parse(_claims).ToString())
                             .ExecuteAsync(CancellationToken.None).Result;

            //Assert
            Assert.IsNotNull(authResult);
            Assert.IsNotNull(authResult.AccessToken);
            Assert.IsNotNull(authResult.IdToken);
            Assert.IsTrue(string.Equals(_deviceAuthuser, authResult.Account.Username, StringComparison.InvariantCultureIgnoreCase));

            var(req, res) = factory.RequestsAndResponses
                            .Where(x => x.Item1.RequestUri.AbsoluteUri == labResponse.Lab.Authority + "organizations/oauth2/v2.0/token" &&
                                   x.Item2.StatusCode == HttpStatusCode.OK).ElementAt(1);

            var AuthHeader = req.Headers.Single(h => h.Key == "Authorization").Value.FirstOrDefault();

            Assert.IsTrue(!string.IsNullOrEmpty(AuthHeader));
            Assert.IsTrue(AuthHeader.Contains("PKeyAuth"));
        }
예제 #2
0
        public async Task PKeyAuthNonInteractiveTestAsync()
        {
            //Arrange
            var labResponse = await LabUserHelper.GetSpecificUserAsync(_deviceAuthuser).ConfigureAwait(false);

            var factory          = new HttpSnifferClientFactory();
            var msalPublicClient = PublicClientApplicationBuilder
                                   .Create(labResponse.App.AppId)
                                   .WithAuthority("https://login.microsoftonline.com/organizations/")
                                   .WithHttpClientFactory(factory)
                                   .Build();

            //Act
            var authResult = msalPublicClient.AcquireTokenByUsernamePassword(
                new[] { "user.read" },
                labResponse.User.Upn,
                new NetworkCredential("", labResponse.User.GetOrFetchPassword()).SecurePassword)
                             .WithClaims(JObject.Parse(_claims).ToString())
                             .ExecuteAsync(CancellationToken.None).Result;

            //Assert
            Assert.IsNotNull(authResult);
            Assert.IsNotNull(authResult.AccessToken);
            Assert.IsNotNull(authResult.IdToken);
            Assert.IsTrue(string.Equals(_deviceAuthuser, authResult.Account.Username, StringComparison.InvariantCultureIgnoreCase));

            //Assert that the PKeyAuth header is used and the token response is successful
            var(req, res) = factory.RequestsAndResponses
                            .Where(x => x.Item1.Headers.Authorization != null &&
                                   x.Item1.Headers.Authorization.Scheme.Contains(PKeyAuthConstants.PKeyAuthName) &&
                                   x.Item2.StatusCode == HttpStatusCode.OK).FirstOrDefault();

            Assert.IsNotNull(req);
            Assert.IsNotNull(res);
        }
예제 #3
0
        public async Task AcquireTokenByObo_LongRunning_WithDifferentScopes_TestAsync()
        {
            string[] scopes2 = { "api://eec635da-5760-452d-940a-448220db047c/access_as_user" };
            var      user1   = (await LabUserHelper.GetSpecificUserAsync("*****@*****.**").ConfigureAwait(false)).User;
            var      pca     = PublicClientApplicationBuilder
                               .Create(PublicClientID)
                               .WithAuthority(AadAuthorityAudience.AzureAdMultipleOrgs)
                               .WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient")
                               .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);

            string        oboCacheKey   = "obo-cache-key";
            UserAssertion userAssertion = new UserAssertion(userAuthResult.AccessToken);

            var result = await cca.InitiateLongRunningProcessInWebApi(s_scopes, userAuthResult.AccessToken, ref oboCacheKey)
                         .ExecuteAsync().ConfigureAwait(false);

            // Cache has 1 partition (user-provided key) with 1 token
            Assert.AreEqual(TokenSource.IdentityProvider, result.AuthenticationResultMetadata.TokenSource);
            Assert.AreEqual(1, cca.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count);
            Assert.AreEqual(1, cca.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count);

            // No matching AT, uses RT to retrieve new AT.
            result = await cca.AcquireTokenInLongRunningProcess(scopes2, oboCacheKey).ExecuteAsync().ConfigureAwait(false);

            Assert.AreEqual(TokenSource.IdentityProvider, result.AuthenticationResultMetadata.TokenSource);
            Assert.AreEqual(CacheRefreshReason.NoCachedAccessToken, result.AuthenticationResultMetadata.CacheRefreshReason);
        }
예제 #4
0
        public async Task AcquireTokenByObo_NormalOboThenLongRunningInitiate_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);

            // InitiateLR - AT from cache
            result = await cca.InitiateLongRunningProcessInWebApi(s_scopes, userAuthResult.AccessToken, ref oboCacheKey)
                     .ExecuteAsync().ConfigureAwait(false);

            Assert.AreEqual(TokenSource.Cache, result.AuthenticationResultMetadata.TokenSource);

            // Expire AT
            TokenCacheHelper.ExpireAllAccessTokens(cca.UserTokenCacheInternal);

            // InitiateLR - AT 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);
        }
예제 #5
0
        public async Task OboAndClient_WithRegional_TestAsync()
        {
            // Setup: Get lab user, create PCA and get user tokens
            var user = (await LabUserHelper.GetSpecificUserAsync("*****@*****.**").ConfigureAwait(false)).User;

            var pca = PublicClientApplicationBuilder
                      .Create(PublicClientID)
                      .WithAuthority(AadAuthorityAudience.AzureAdMultipleOrgs)
                      .Build();

            var userResult = await pca
                             .AcquireTokenByUsernamePassword(s_oboServiceScope, user.Upn, new NetworkCredential("", user.GetOrFetchPassword()).SecurePassword)
                             .ExecuteAsync(CancellationToken.None)
                             .ConfigureAwait(false);

            // Act and Assert different scenarios
            var cca = BuildCCA(userResult.TenantId, true);

            // OBO uses global - IdP
            var oboResult = await cca.AcquireTokenOnBehalfOf(s_scopes, new UserAssertion(userResult.AccessToken))
                            .ExecuteAsync(CancellationToken.None)
                            .ConfigureAwait(false);

            Assert.AreEqual(TokenSource.IdentityProvider, oboResult.AuthenticationResultMetadata.TokenSource);
            Assert.IsFalse(oboResult.AuthenticationResultMetadata.TokenEndpoint.Contains(TestConstants.Region));

            // Client uses regional - IdP
            var clientResult = await cca.AcquireTokenForClient(new string[] { "https://graph.microsoft.com/.default" })
                               .ExecuteAsync(CancellationToken.None)
                               .ConfigureAwait(false);

            Assert.AreEqual(TokenSource.IdentityProvider, clientResult.AuthenticationResultMetadata.TokenSource);
            Assert.IsTrue(clientResult.AuthenticationResultMetadata.TokenEndpoint.Contains(TestConstants.Region));

            // OBO from cache
            oboResult = await cca.AcquireTokenOnBehalfOf(s_scopes, new UserAssertion(userResult.AccessToken))
                        .ExecuteAsync(CancellationToken.None)
                        .ConfigureAwait(false);

            Assert.AreEqual(TokenSource.Cache, oboResult.AuthenticationResultMetadata.TokenSource);

            // Client from cache
            clientResult = await cca.AcquireTokenForClient(new string[] { "https://graph.microsoft.com/.default" })
                           .ExecuteAsync(CancellationToken.None)
                           .ConfigureAwait(false);

            Assert.AreEqual(TokenSource.Cache, clientResult.AuthenticationResultMetadata.TokenSource);
        }
예제 #6
0
        public async Task AcquireTokenByObo_LongRunningAndNormalObo_WithDifferentKeys_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);

            string        oboCacheKey   = "obo-cache-key";
            UserAssertion userAssertion = new UserAssertion(userAuthResult.AccessToken);

            var result = await cca.InitiateLongRunningProcessInWebApi(s_scopes, userAuthResult.AccessToken, ref oboCacheKey)
                         .ExecuteAsync().ConfigureAwait(false);

            // Cache has 1 partition (user-provided key) with 1 token
            Assert.AreEqual(TokenSource.IdentityProvider, result.AuthenticationResultMetadata.TokenSource);
            Assert.AreEqual(1, cca.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count);
            Assert.AreEqual(1, cca.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count);

            result = await cca.AcquireTokenOnBehalfOf(s_scopes, userAssertion).ExecuteAsync().ConfigureAwait(false);

            // Cache has 2 partitions (user-provided key, assertion) with 1 token each
            Assert.AreEqual(TokenSource.IdentityProvider, result.AuthenticationResultMetadata.TokenSource);
            Assert.AreEqual(2, cca.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count);
            Assert.AreEqual(1, cca.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count);

            // Returns long-running token
            result = await cca.AcquireTokenInLongRunningProcess(s_scopes, oboCacheKey).ExecuteAsync().ConfigureAwait(false);

            Assert.AreEqual(TokenSource.Cache, result.AuthenticationResultMetadata.TokenSource);

            // Returns normal token
            result = await cca.AcquireTokenOnBehalfOf(s_scopes, userAssertion).ExecuteAsync().ConfigureAwait(false);

            Assert.AreEqual(TokenSource.Cache, result.AuthenticationResultMetadata.TokenSource);
        }
예제 #7
0
        private static async Task<AuthenticationResult> AcquireTokenForLabUserAsync()
        {
            var labResponse = await LabUserHelper.GetSpecificUserAsync(TestConstants.OBOUser).ConfigureAwait(false);
            var msalPublicClient = PublicClientApplicationBuilder
               .Create(TestConstants.OBOClientSideClientId)
               .WithAuthority(labResponse.Lab.Authority, TestConstants.Organizations)
               .Build();

            AuthenticationResult authResult = await msalPublicClient
                .AcquireTokenByUsernamePassword(
                TestConstants.OBOApiScope,
                TestConstants.OBOUser,
                new NetworkCredential(
                    TestConstants.OBOUser,
                    labResponse.User.GetOrFetchPassword()).SecurePassword)
                .ExecuteAsync(CancellationToken.None)
                .ConfigureAwait(false);

            return authResult;
        }
 public async Task WebAPIAccessingGraphOnBehalfOfUserTestAsync()
 {
     await RunOnBehalfOfTestAsync(await LabUserHelper.GetSpecificUserAsync("*****@*****.**").ConfigureAwait(false)).ConfigureAwait(false);
 }
예제 #9
0
        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);
            }
        }