private void LogRequestStarted(AuthenticationRequestParameters authenticationRequestParameters)
        {
            string messageWithPii = string.Format(
                CultureInfo.InvariantCulture,
                "=== Token Acquisition ({3}) started:\n\tAuthority: {0}\n\tScope: {1}\n\tClientId: {2}\n\t",
                authenticationRequestParameters.AuthorityInfo?.CanonicalAuthority,
                authenticationRequestParameters.Scope.AsSingleString(),
                authenticationRequestParameters.AppConfig.ClientId,
                GetType().Name);

            string messageWithoutPii = string.Format(
                CultureInfo.InvariantCulture,
                "=== Token Acquisition ({0}) started:\n\t",
                GetType().Name);

            if (authenticationRequestParameters.AuthorityInfo != null &&
                KnownMetadataProvider.IsKnownEnvironment(authenticationRequestParameters.AuthorityInfo?.Host))
            {
                messageWithoutPii += string.Format(
                    CultureInfo.CurrentCulture,
                    "\n\tAuthority Host: {0}",
                    authenticationRequestParameters.AuthorityInfo?.Host);
            }

            authenticationRequestParameters.RequestContext.Logger.InfoPii(messageWithPii, messageWithoutPii);

            if (authenticationRequestParameters.IsConfidentialClient && !CacheManager.TokenCacheInternal.IsTokenCacheSerialized())
            {
                authenticationRequestParameters.RequestContext.Logger.Error("The default token cache provided by MSAL is not designed to be performant when used in confidential client applications. Please use token cache serialization. See https://aka.ms/msal-net-cca-token-cache-serialization.");
            }
        }
        private void LogRequestStarted(AuthenticationRequestParameters authenticationRequestParameters)
        {
            string messageWithPii = string.Format(
                CultureInfo.InvariantCulture,
                "=== Token Acquisition ({4}) started:\n\tAuthority: {0}\n\tScope: {1}\n\tClientId: {2}\n\tCache Provided: {3}",
                authenticationRequestParameters.AuthorityInfo?.CanonicalAuthority,
                authenticationRequestParameters.Scope.AsSingleString(),
                authenticationRequestParameters.ClientId,
                CacheManager.HasCache,
                GetType().Name);

            string messageWithoutPii = string.Format(
                CultureInfo.InvariantCulture,
                "=== Token Acquisition ({1}) started:\n\tCache Provided: {0}",
                CacheManager.HasCache,
                GetType().Name);

            if (authenticationRequestParameters.AuthorityInfo != null &&
                KnownMetadataProvider.IsKnownEnvironment(authenticationRequestParameters.AuthorityInfo?.Host))
            {
                messageWithoutPii += string.Format(
                    CultureInfo.CurrentCulture,
                    "\n\tAuthority Host: {0}",
                    authenticationRequestParameters.AuthorityInfo?.Host);
            }

            authenticationRequestParameters.RequestContext.Logger.InfoPii(messageWithPii, messageWithoutPii);
        }
Exemple #3
0
        public static MockHttpMessageHandler AddInstanceDiscoveryMockHandler(
            this MockHttpManager httpManager,
            string authority               = TestConstants.AuthorityCommonTenant,
            Uri customDiscoveryEndpoint    = null,
            string instanceMetadataContent = null)
        {
            Uri authorityURI = new Uri(authority);

            string discoveryEndpoint;

            if (customDiscoveryEndpoint == null)
            {
                string discoveryHost = KnownMetadataProvider.IsKnownEnvironment(authorityURI.Host)
                                           ? authorityURI.Host
                                           : AadAuthority.DefaultTrustedHost;

                discoveryEndpoint = UriBuilderExtensions.GetHttpsUriWithOptionalPort($"https://{discoveryHost}/common/discovery/instance", authorityURI.Port);
            }
            else
            {
                discoveryEndpoint = customDiscoveryEndpoint.AbsoluteUri;
            }

            return(httpManager.AddMockHandler(
                       MockHelpers.CreateInstanceDiscoveryMockHandler(
                           discoveryEndpoint,
                           instanceMetadataContent ?? TestConstants.DiscoveryJsonResponse)));
        }
Exemple #4
0
        private void RunAcquireTokenSilentCacheOnlyTest(string authority, bool expectNetworkDiscovery)
        {
            var receiver = new MyReceiver();

            using (MockHttpAndServiceBundle testHarness = base.CreateTestHarness())
            {
                PublicClientApplication app = PublicClientApplicationBuilder.Create(TestConstants.ClientId)
                                              .WithAuthority(authority, true)
                                              .WithHttpManager(testHarness.HttpManager)
                                              .WithTelemetry(receiver.HandleTelemetryEvents)
                                              .BuildConcrete();

                var tokenCacheHelper = new TokenCacheHelper();
                tokenCacheHelper.PopulateCache(app.UserTokenCacheInternal.Accessor);

                app.UserTokenCacheInternal.Accessor.DeleteAccessToken(new MsalAccessTokenCacheKey(
                                                                          TestConstants.ProductionPrefNetworkEnvironment,
                                                                          TestConstants.Utid,
                                                                          TestConstants.s_userIdentifier,
                                                                          TestConstants.ClientId,
                                                                          TestConstants.ScopeForAnotherResourceStr,
                                                                          TestConstants.Bearer));

                if (expectNetworkDiscovery)
                {
                    string host          = new Uri(authority).Host;
                    string discoveryHost = KnownMetadataProvider.IsKnownEnvironment(host)
                                               ? host
                                               : AadAuthority.DefaultTrustedHost;

                    string discoveryEndpoint = $"https://{discoveryHost}/common/discovery/instance";

                    var jsonResponse = TestConstants.DiscoveryJsonResponse.Replace("login.microsoft.com", host);
                    testHarness.HttpManager.AddMockHandler(
                        MockHelpers.CreateInstanceDiscoveryMockHandler(discoveryEndpoint, jsonResponse));
                }

                Task <AuthenticationResult> task = app
                                                   .AcquireTokenSilent(
                    TestConstants.s_scope.ToArray(),
                    new Account(TestConstants.s_userIdentifier, TestConstants.DisplayableId, null))
                                                   .WithAuthority(app.Authority, false)
                                                   .WithForceRefresh(false)
                                                   .ExecuteAsync(CancellationToken.None);

                AuthenticationResult result = task.Result;
                Assert.IsNotNull(result);
                Assert.AreEqual(TestConstants.DisplayableId, result.Account.Username);
                Assert.AreEqual(TestConstants.s_scope.AsSingleString(), result.Scopes.AsSingleString());

                Assert.AreEqual(2, app.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count());
                Assert.AreEqual(1, app.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count());
                Assert.IsNotNull(receiver.EventsReceived.Find(anEvent =>  // Expect finding such an event
                                                              anEvent[EventBase.EventNameKey].EndsWith("api_event") && anEvent[ApiEvent.WasSuccessfulKey] == "true" &&
                                                              anEvent[MsalTelemetryBlobEventNames.ApiIdConstStrKey] == "1007"));
            }
        }
Exemple #5
0
        public void KnownMetadataProvider_IsKnown()
        {
            Assert.IsFalse(KnownMetadataProvider.IsKnownEnvironment(null));
            Assert.IsFalse(KnownMetadataProvider.IsKnownEnvironment(""));
            Assert.IsFalse(KnownMetadataProvider.IsKnownEnvironment("bogus"));

            Assert.IsTrue(KnownMetadataProvider.IsKnownEnvironment("login.microsoftonline.de"));
            Assert.IsTrue(KnownMetadataProvider.IsKnownEnvironment("LOGIN.microsoftonline.de"));
        }
Exemple #6
0
        public static void AddInstanceDiscoveryMockHandler(this MockHttpManager httpManager, string authority)
        {
            string host          = new Uri(authority).Host;
            string discoveryHost = KnownMetadataProvider.IsKnownEnvironment(host)
                                       ? host
                                       : AadAuthority.DefaultTrustedHost;

            string discoveryEndpoint = $"https://{discoveryHost}/common/discovery/instance";

            httpManager.AddMockHandler(
                MockHelpers.CreateInstanceDiscoveryMockHandler(discoveryEndpoint));
        }
        public static void AddInstanceDiscoveryMockHandler(this MockHttpManager httpManager, string authority)
        {
            Uri    authorityURI  = new Uri(authority);
            string discoveryHost = KnownMetadataProvider.IsKnownEnvironment(authorityURI.Host)
                                       ? authorityURI.Host
                                       : AadAuthority.DefaultTrustedHost;

            string discoveryEndpoint = UriBuilderExtensions.GetHttpsUriWithOptionalPort($"https://{discoveryHost}/common/discovery/instance", authorityURI.Port);

            httpManager.AddMockHandler(
                MockHelpers.CreateInstanceDiscoveryMockHandler(discoveryEndpoint));
        }
        /// <summary>
        /// AAD performs authority validation by calling the instance metadata endpoint. This is a bit unfortunate,
        /// because instance metadata is used for aliasing, and authority validation is orthogonal to that.
        /// MSAL must figure out aliasing even if ValidateAuthority is set to false.
        /// </summary>
        public async Task ValidateAuthorityAsync(
            AuthorityInfo authorityInfo,
            RequestContext requestContext)
        {
            var authorityUri = new Uri(authorityInfo.CanonicalAuthority);

            if (authorityInfo.ValidateAuthority && !KnownMetadataProvider.IsKnownEnvironment(authorityUri.Host))
            {
                // MSAL will throw if the instance discovery URI does not respond with a valid json
                await _serviceBundle.InstanceDiscoveryManager.GetMetadataEntryAsync(
                    authorityInfo.CanonicalAuthority,
                    requestContext).ConfigureAwait(false);
            }
        }
        /// <inheritdoc />
        public async Task <string> ValidateAuthorityAndGetOpenIdDiscoveryEndpointAsync(
            AuthorityInfo authorityInfo,
            string userPrincipalName,
            RequestContext requestContext)
        {
            var authorityUri = new Uri(authorityInfo.CanonicalAuthority);

            if (authorityInfo.ValidateAuthority && !KnownMetadataProvider.IsKnownEnvironment(authorityUri.Host))
            {
                // MSAL will throw if the instance discovery URI does not respond with a valid json
                await _serviceBundle.InstanceDiscoveryManager.GetMetadataEntryAsync(
                    authorityInfo.CanonicalAuthority,
                    requestContext).ConfigureAwait(false);
            }

            return(authorityInfo.CanonicalAuthority + Constants.OpenIdConfigurationEndpoint);
        }
Exemple #10
0
        /// <summary>
        /// AAD performs authority validation by calling the instance metadata endpoint. This is a bit unfortunate,
        /// because instance metadata is used for aliasing, and authority validation is orthogonal to that.
        /// MSAL must figure out aliasing even if ValidateAuthority is set to false.
        /// </summary>
        public async Task ValidateAuthorityAsync(
            AuthorityInfo authorityInfo)
        {
            var  authorityUri = new Uri(authorityInfo.CanonicalAuthority);
            bool isKnownEnv   = KnownMetadataProvider.IsKnownEnvironment(authorityUri.Host);

            _requestContext.Logger.Info($"Authority validation enabled? {authorityInfo.ValidateAuthority}. ");
            _requestContext.Logger.Info($"Authority validation - is known env? {isKnownEnv}. ");

            if (authorityInfo.ValidateAuthority && !isKnownEnv)
            {
                _requestContext.Logger.Info($"Authority validation is being performed. ");

                // MSAL will throw if the instance discovery URI does not respond with a valid json
                await _requestContext.ServiceBundle.InstanceDiscoveryManager.GetMetadataEntryAsync(
                    authorityInfo,
                    _requestContext).ConfigureAwait(false);
            }
        }
        private void RunAcquireTokenSilentCacheOnlyTest(string authority, bool expectNetworkDiscovery)
        {
            using (MockHttpAndServiceBundle testHarness = base.CreateTestHarness())
            {
                PublicClientApplication app = PublicClientApplicationBuilder.Create(TestConstants.ClientId)
                                              .WithAuthority(authority, true)
                                              .WithHttpManager(testHarness.HttpManager)
                                              .BuildConcrete();

                TokenCacheHelper.PopulateCache(app.UserTokenCacheInternal.Accessor);

                if (expectNetworkDiscovery)
                {
                    string host          = new Uri(authority).Host;
                    string discoveryHost = KnownMetadataProvider.IsKnownEnvironment(host)
                                               ? host
                                               : AadAuthority.DefaultTrustedHost;

                    string discoveryEndpoint = $"https://{discoveryHost}/common/discovery/instance";

                    var jsonResponse = TestConstants.DiscoveryJsonResponse.Replace("login.microsoft.com", host);
                    testHarness.HttpManager.AddMockHandler(
                        MockHelpers.CreateInstanceDiscoveryMockHandler(discoveryEndpoint, jsonResponse));
                }

                Task <AuthenticationResult> task = app
                                                   .AcquireTokenSilent(
                    TestConstants.s_scope.ToArray(),
                    new Account(TestConstants.s_userIdentifier, TestConstants.DisplayableId, null))
                                                   .WithForceRefresh(false)
                                                   .ExecuteAsync(CancellationToken.None);

                AuthenticationResult result = task.Result;
                Assert.IsNotNull(result);
                Assert.AreEqual(TestConstants.DisplayableId, result.Account.Username);
                Assert.AreEqual(TestConstants.s_scope.AsSingleString(), result.Scopes.AsSingleString());

                Assert.AreEqual(2, app.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count());
                Assert.AreEqual(1, app.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count());
            }
        }
        private void LogRequestStarted(AuthenticationRequestParameters authenticationRequestParameters)
        {
            if (authenticationRequestParameters.RequestContext.Logger.IsLoggingEnabled(LogLevel.Info))
            {
                string scopes         = authenticationRequestParameters.Scope.AsSingleString();
                string messageWithPii = string.Format(
                    CultureInfo.InvariantCulture,
                    "=== Token Acquisition ({3}) started:\n\tAuthority: {0}\n\tScope: {1}\n\tClientId: {2}\n\t",
                    authenticationRequestParameters.AuthorityInfo?.CanonicalAuthority,
                    scopes,
                    authenticationRequestParameters.AppConfig.ClientId,
                    GetType().Name);

                string messageWithoutPii = string.Format(
                    CultureInfo.InvariantCulture,
                    "=== Token Acquisition ({0}) started:\n\t Scopes: {1}",
                    GetType().Name,
                    scopes);

                if (authenticationRequestParameters.AuthorityInfo != null &&
                    KnownMetadataProvider.IsKnownEnvironment(authenticationRequestParameters.AuthorityInfo?.Host))
                {
                    messageWithoutPii += string.Format(
                        CultureInfo.CurrentCulture,
                        "\n\tAuthority Host: {0}",
                        authenticationRequestParameters.AuthorityInfo?.Host);
                }

                authenticationRequestParameters.RequestContext.Logger.InfoPii(messageWithPii, messageWithoutPii);
            }

            if (authenticationRequestParameters.IsConfidentialClient &&
                !authenticationRequestParameters.IsClientCredentialRequest &&
                !CacheManager.TokenCacheInternal.IsAppSubscribedToSerializationEvents())
            {
                authenticationRequestParameters.RequestContext.Logger.Warning(
                    "Only in-memory caching is used. The cache is not persisted and will be lost if the machine is restarted. It also does not scale for a web app or web API, where the number of users can grow large. In production, web apps and web APIs should use distributed caching like Redis. See https://aka.ms/msal-net-cca-token-cache-serialization");
            }
        }