Exemple #1
0
        public async Task POP_ShrValidation_Async()
        {
            using (var httpManager = new MockHttpManager())
            {
                ConfidentialClientApplication app =
                    ConfidentialClientApplicationBuilder.Create(TestConstants.ClientId)
                    .WithClientSecret(TestConstants.ClientSecret)
                    .WithHttpManager(httpManager)
                    .WithExperimentalFeatures(true)
                    .BuildConcrete();

                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, new Uri(ProtectedUrl));
                var popConfig = new PoPAuthenticationConfiguration(request);
                var provider  = PoPProviderFactory.GetOrCreateProvider();

                httpManager.AddInstanceDiscoveryMockHandler();
                httpManager.AddMockHandlerSuccessfulClientCredentialTokenResponseMessage(tokenType: "pop");

                // Act
                var result = await app.AcquireTokenForClient(TestConstants.s_scope.ToArray())
                             .WithAuthority(TestConstants.AuthorityUtidTenant)
                             .WithProofOfPossession(popConfig)
                             .ExecuteAsync()
                             .ConfigureAwait(false);

                // access token parsing can be done with MSAL's id token parsing logic
                var claims = IdToken.Parse(result.AccessToken).ClaimsPrincipal;

                Assert.IsTrue(!string.IsNullOrEmpty(claims.FindAll("nonce").Single().Value));
                AssertSingedHttpRequestClaims(provider, claims);
            }
        }
Exemple #2
0
        public async Task POP_WithMissingNonceForPCA_Async()
        {
            using (var httpManager = new MockHttpManager())
            {
                PublicClientApplication app =
                    PublicClientApplicationBuilder.Create(TestConstants.ClientId)
                    .WithBrokerPreview()
                    .WithExperimentalFeatures()
                    .WithHttpManager(httpManager)
                    .BuildConcrete();

                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, new Uri(ProtectedUrl));
                var popConfig = new PoPAuthenticationConfiguration(request);
                var provider  = PoPProviderFactory.GetOrCreateProvider();

                await AssertException.TaskThrowsAsync <ArgumentNullException>(() =>
                                                                              app.AcquireTokenInteractive(TestConstants.s_scope.ToArray())
                                                                              .WithAuthority(TestConstants.AuthorityUtidTenant)
                                                                              .WithProofOfPossession(null, HttpMethod.Get, new Uri(app.Authority))
                                                                              .ExecuteAsync())
                .ConfigureAwait(false);

                await AssertException.TaskThrowsAsync <ArgumentNullException>(() =>
                                                                              app.AcquireTokenSilent(TestConstants.s_scope.ToArray(), "loginHint")
                                                                              .WithAuthority(TestConstants.AuthorityUtidTenant)
                                                                              .WithProofOfPossession(null, HttpMethod.Get, new Uri(app.Authority))
                                                                              .ExecuteAsync())
                .ConfigureAwait(false);
            }
        }
Exemple #3
0
        public async Task POP_NoHttpRequest_Async()
        {
            using (var httpManager = new MockHttpManager())
            {
                ConfidentialClientApplication app =
                    ConfidentialClientApplicationBuilder.Create(TestConstants.ClientId)
                    .WithClientSecret(TestConstants.ClientSecret)
                    .WithHttpManager(httpManager)
                    .WithExperimentalFeatures(true)
                    .BuildConcrete();

                // no HTTP method binding, but custom nonce
                var popConfig = new PoPAuthenticationConfiguration()
                {
                    Nonce = CustomNonce
                };
                var provider = PoPProviderFactory.GetOrCreateProvider();

                httpManager.AddInstanceDiscoveryMockHandler();
                httpManager.AddMockHandlerSuccessfulClientCredentialTokenResponseMessage(tokenType: "pop");

                // Act
                var result = await app.AcquireTokenForClient(TestConstants.s_scope.ToArray())
                             .WithAuthority(TestConstants.AuthorityUtidTenant)
                             .WithProofOfPossession(popConfig)
                             .ExecuteAsync()
                             .ConfigureAwait(false);

                // access token parsing can be done with MSAL's id token parsing logic
                var claims = IdToken.Parse(result.AccessToken).ClaimsPrincipal;

                Assert.AreEqual(CustomNonce, claims.FindAll("nonce").Single().Value);
                AssertTsAndJwkClaims(provider, claims);

                Assert.IsFalse(claims.FindAll("m").Any());
                Assert.IsFalse(claims.FindAll("u").Any());
                Assert.IsFalse(claims.FindAll("p").Any());
            }
        }
Exemple #4
0
        internal ServiceBundle(
            ApplicationConfiguration config,
            bool shouldClearCaches = false)
        {
            Config = config;

            ApplicationLogger = new MsalLogger(
                Guid.Empty,
                config.ClientName,
                config.ClientVersion,
                config.LogLevel,
                config.EnablePiiLogging,
                config.IsDefaultPlatformLoggingEnabled,
                config.LoggingCallback);

            PlatformProxy = config.PlatformProxy ?? PlatformProxyFactory.CreatePlatformProxy(ApplicationLogger);
            HttpManager   = config.HttpManager ?? new HttpManager(
                config.HttpClientFactory ??
                PlatformProxy.CreateDefaultHttpClientFactory());

            HttpTelemetryManager = new HttpTelemetryManager();

            InstanceDiscoveryManager = new InstanceDiscoveryManager(
                HttpManager,
                shouldClearCaches,
                config.CustomInstanceDiscoveryMetadata,
                config.CustomInstanceDiscoveryMetadataUri);

            WsTrustWebRequestManager = new WsTrustWebRequestManager(HttpManager);
            ThrottlingManager        = SingletonThrottlingManager.GetInstance();
            DeviceAuthManager        = config.DeviceAuthManagerForTest ?? PlatformProxy.CreateDeviceAuthManager();

            if (shouldClearCaches) // for test
            {
                AuthorityManager.ClearValidationCache();
                PoPProviderFactory.Reset();
            }
        }
Exemple #5
0
 public override IPoPCryptoProvider GetDefaultPoPCryptoProvider()
 {
     return(PoPProviderFactory.GetOrCreateProvider());
 }
        public async Task ValidateKeyExpirationAsync()
        {
            using (var harness = CreateTestHarness())
            {
                harness.HttpManager.AddInstanceDiscoveryMockHandler();
                PoPAuthenticationConfiguration popConfig = new PoPAuthenticationConfiguration(new Uri("https://www.contoso.com/path1/path2?queryParam1=a&queryParam2=b"));
                popConfig.HttpMethod        = HttpMethod.Get;
                popConfig.PopCryptoProvider = new InMemoryCryptoProvider();

                var app = ConfidentialClientApplicationBuilder.Create(TestConstants.ClientId)
                          .WithHttpManager(harness.HttpManager)
                          .WithExperimentalFeatures()
                          .WithClientSecret("some-secret")
                          .BuildConcrete();

                harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(
                    TestConstants.AuthorityCommonTenant,
                    null,
                    null,
                    false,
                    MockHelpers.CreateSuccessResponseMessage(MockHelpers.GetPopTokenResponse()));

                Guid      correlationId = Guid.NewGuid();
                TestClock testClock     = new TestClock();
                testClock.TestTime = DateTime.UtcNow;
                var provider = PoPProviderFactory.GetOrCreateProvider(testClock);

                await app.AcquireTokenForClient(TestConstants.s_scope)
                .WithProofOfPossession(popConfig)
                .ExecuteAsync(CancellationToken.None)
                .ConfigureAwait(false);

                var JWK = provider.CannonicalPublicKeyJwk;
                //Advance time 7 hours. Should still be the same key
                testClock.TestTime = testClock.TestTime + TimeSpan.FromSeconds(60 * 60 * 7);

                harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(
                    TestConstants.AuthorityCommonTenant,
                    null,
                    null,
                    false,
                    MockHelpers.CreateSuccessResponseMessage(MockHelpers.GetPopTokenResponse()));

                provider = PoPProviderFactory.GetOrCreateProvider(testClock);
                await app.AcquireTokenForClient(TestConstants.s_scope)
                .WithProofOfPossession(popConfig)
                .ExecuteAsync(CancellationToken.None)
                .ConfigureAwait(false);

                Assert.IsTrue(JWK == provider.CannonicalPublicKeyJwk);
                //Advance time 2 hours. Should be a different key
                testClock.TestTime = testClock.TestTime + TimeSpan.FromSeconds(60 * 60 * 2);

                harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(
                    TestConstants.AuthorityCommonTenant,
                    null,
                    null,
                    false,
                    MockHelpers.CreateSuccessResponseMessage(MockHelpers.GetPopTokenResponse()));

                provider = PoPProviderFactory.GetOrCreateProvider(testClock);
                await app.AcquireTokenForClient(TestConstants.s_scope)
                .WithProofOfPossession(popConfig)
                .ExecuteAsync(CancellationToken.None)
                .ConfigureAwait(false);

                Assert.IsTrue(JWK != provider.CannonicalPublicKeyJwk);
            }
        }
        public async Task ValidateKeyExpirationAsync()
        {
            using (var harness = CreateTestHarness())
            {
                harness.HttpManager.AddInstanceDiscoveryMockHandler();
                HttpRequestMessage request1 = new HttpRequestMessage(HttpMethod.Get, new Uri("https://www.contoso.com/path1/path2?queryParam1=a&queryParam2=b"));

                var app = PublicClientApplicationBuilder.Create(TestConstants.ClientId)
                          .WithHttpManager(harness.HttpManager)
                          .WithExperimentalFeatures()
                          .BuildConcrete();


                MsalMockHelpers.ConfigureMockWebUI(
                    app.ServiceBundle.PlatformProxy,
                    AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code"));

                harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(
                    TestConstants.AuthorityCommonTenant,
                    null,
                    null,
                    false,
                    MockHelpers.CreateSuccessResponseMessage(MockHelpers.GetPopTokenResponse()));

                Guid      correlationId = Guid.NewGuid();
                TestClock testClock     = new TestClock();
                testClock.TestTime = DateTime.UtcNow;
                var provider = PoPProviderFactory.GetOrCreateProvider(testClock);

                await app.AcquireTokenInteractive(TestConstants.s_scope)
                .WithProofOfPosession(request1, provider)
                .ExecuteAsync(CancellationToken.None)
                .ConfigureAwait(false);

                var JWK = provider.CannonicalPublicKeyJwk;
                //Advance time 7 hours. Should still be the same key
                testClock.TestTime = testClock.TestTime + TimeSpan.FromSeconds(60 * 60 * 7);

                harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(
                    TestConstants.AuthorityCommonTenant,
                    null,
                    null,
                    false,
                    MockHelpers.CreateSuccessResponseMessage(MockHelpers.GetPopTokenResponse()));

                provider = PoPProviderFactory.GetOrCreateProvider(testClock);
                await app.AcquireTokenInteractive(TestConstants.s_scope)
                .WithProofOfPosession(request1, provider)
                .ExecuteAsync(CancellationToken.None)
                .ConfigureAwait(false);

                Assert.IsTrue(JWK == provider.CannonicalPublicKeyJwk);
                //Advance time 2 hours. Should be a different key
                testClock.TestTime = testClock.TestTime + TimeSpan.FromSeconds(60 * 60 * 2);

                harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(
                    TestConstants.AuthorityCommonTenant,
                    null,
                    null,
                    false,
                    MockHelpers.CreateSuccessResponseMessage(MockHelpers.GetPopTokenResponse()));

                provider = PoPProviderFactory.GetOrCreateProvider(testClock);
                await app.AcquireTokenInteractive(TestConstants.s_scope)
                .WithProofOfPosession(request1, provider)
                .ExecuteAsync(CancellationToken.None)
                .ConfigureAwait(false);

                Assert.IsTrue(JWK != provider.CannonicalPublicKeyJwk);
            }
        }
Exemple #8
0
 public override void TestCleanup()
 {
     PoPProviderFactory.Reset();
     base.TestCleanup();
 }
Exemple #9
0
        public async Task CacheKey_Includes_POPKid_Async()
        {
            using (var httpManager = new MockHttpManager())
            {
                ConfidentialClientApplication app =
                    ConfidentialClientApplicationBuilder.Create(TestConstants.ClientId)
                    .WithClientSecret(TestConstants.ClientSecret)
                    .WithHttpManager(httpManager)
                    .WithExperimentalFeatures(true)
                    .BuildConcrete();
                var testTimeService = new TestTimeService();
                PoPProviderFactory.TimeService = testTimeService;

                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, new Uri(ProtectedUrl));
                var popConfig   = new PoPAuthenticationConfiguration(request);
                var cacheAccess = app.AppTokenCache.RecordAccess();

                httpManager.AddInstanceDiscoveryMockHandler();
                httpManager.AddMockHandlerSuccessfulClientCredentialTokenResponseMessage(tokenType: "pop");

                // Act
                Trace.WriteLine("1. AcquireTokenForClient ");
                var result = await app.AcquireTokenForClient(TestConstants.s_scope.ToArray())
                             .WithAuthority(TestConstants.AuthorityUtidTenant)
                             .WithProofOfPossession(popConfig)
                             .ExecuteAsync()
                             .ConfigureAwait(false);

                // Assert
                Assert.AreEqual(TokenSource.IdentityProvider, result.AuthenticationResultMetadata.TokenSource);
                string expectedKid    = GetKidFromJwk(PoPProviderFactory.GetOrCreateProvider().CannonicalPublicKeyJwk);
                string actualCacheKey = cacheAccess.LastBeforeAccessNotificationArgs.SuggestedCacheKey;
                Assert.AreEqual(
                    string.Format(
                        CultureInfo.InvariantCulture,
                        "{0}{1}_{2}_AppTokenCache",
                        expectedKid,
                        TestConstants.ClientId,
                        TestConstants.Utid),
                    actualCacheKey);

                // Arrange - force a new key by moving to the future
                (PoPProviderFactory.TimeService as TestTimeService).MoveToFuture(
                    PoPProviderFactory.KeyRotationInterval.Add(TimeSpan.FromMinutes(10)));

                httpManager.AddMockHandlerSuccessfulClientCredentialTokenResponseMessage(tokenType: "pop");

                // Act
                Trace.WriteLine("1. AcquireTokenForClient again, after time passes - expect POP key rotation");
                result = await app.AcquireTokenForClient(TestConstants.s_scope.ToArray())
                         .WithAuthority(TestConstants.AuthorityUtidTenant)
                         .WithProofOfPossession(popConfig)
                         .ExecuteAsync()
                         .ConfigureAwait(false);

                // Assert
                Assert.AreEqual(TokenSource.IdentityProvider, result.AuthenticationResultMetadata.TokenSource);
                string expectedKid2    = GetKidFromJwk(PoPProviderFactory.GetOrCreateProvider().CannonicalPublicKeyJwk);
                string actualCacheKey2 = cacheAccess.LastBeforeAccessNotificationArgs.SuggestedCacheKey;
                Assert.AreEqual(
                    string.Format(
                        CultureInfo.InvariantCulture,
                        "{0}{1}_{2}_AppTokenCache",
                        expectedKid2,
                        TestConstants.ClientId,
                        TestConstants.Utid),
                    actualCacheKey2);

                Assert.AreNotEqual(actualCacheKey, actualCacheKey2);
            }
        }