This class adds additional query parameters or headers to the requests sent to STS. This can help us in collecting statistics and potentially on diagnostics.
예제 #1
0
        private Dictionary <string, string> CreateAuthorizationRequestParameters(Uri redirectUriOverride = null)
        {
            var extraScopesToConsent = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            if (!_interactiveParameters.ExtraScopesToConsent.IsNullOrEmpty())
            {
                extraScopesToConsent = ScopeHelper.CreateScopeSet(_interactiveParameters.ExtraScopesToConsent);
            }

            if (extraScopesToConsent.Contains(_requestParams.AppConfig.ClientId))
            {
                throw new ArgumentException("API does not accept client id as a user-provided scope");
            }

            var unionScope = ScopeHelper.GetMsalScopes(
                new HashSet <string>(_requestParams.Scope.Concat(extraScopesToConsent)));

            var authorizationRequestParameters = new Dictionary <string, string>
            {
                [OAuth2Parameter.Scope]        = unionScope.AsSingleString(),
                [OAuth2Parameter.ResponseType] = OAuth2ResponseType.Code,

                [OAuth2Parameter.ClientId]    = _requestParams.AppConfig.ClientId,
                [OAuth2Parameter.RedirectUri] = redirectUriOverride?.OriginalString ?? _requestParams.RedirectUri.OriginalString
            };

            if (!string.IsNullOrWhiteSpace(_requestParams.ClaimsAndClientCapabilities))
            {
                authorizationRequestParameters[OAuth2Parameter.Claims] = _requestParams.ClaimsAndClientCapabilities;
            }

            if (!string.IsNullOrWhiteSpace(_interactiveParameters.LoginHint))
            {
                authorizationRequestParameters[OAuth2Parameter.LoginHint] = _interactiveParameters.LoginHint;
            }

            if (_requestParams.RequestContext.CorrelationId != Guid.Empty)
            {
                authorizationRequestParameters[OAuth2Parameter.CorrelationId] =
                    _requestParams.RequestContext.CorrelationId.ToString();
            }

            foreach (KeyValuePair <string, string> kvp in MsalIdHelper.GetMsalIdParameters(_requestParams.RequestContext.Logger))
            {
                authorizationRequestParameters[kvp.Key] = kvp.Value;
            }

            if (_interactiveParameters.Prompt == Prompt.NotSpecified)
            {
                authorizationRequestParameters[OAuth2Parameter.Prompt] = Prompt.SelectAccount.PromptValue;
            }
            else if (_interactiveParameters.Prompt.PromptValue != Prompt.NoPrompt.PromptValue)
            {
                authorizationRequestParameters[OAuth2Parameter.Prompt] = _interactiveParameters.Prompt.PromptValue;
            }

            return(authorizationRequestParameters);
        }
예제 #2
0
        private void Log(LogLevel msalLogLevel, string messageWithPii, string messageScrubbed)
        {
            if (msalLogLevel > Logger.Level)
            {
                return;
            }

            //format log message;
            string correlationId = CorrelationId.Equals(Guid.Empty)
                ? string.Empty
                : " - " + CorrelationId;

            var    msalIdParameters = MsalIdHelper.GetMsalIdParameters();
            string os = "N/A";

            if (msalIdParameters.TryGetValue(MsalIdParameter.OS, out string osValue))
            {
                os = osValue;
            }

            bool messageWithPiiExists = !string.IsNullOrWhiteSpace(messageWithPii);
            // If we have a message with PII, and PII logging is enabled, use the PII message, else use the scrubbed message.
            bool   isLoggingPii = messageWithPiiExists && Logger.PiiLoggingEnabled;
            string messageToLog = isLoggingPii ? messageWithPii : messageScrubbed;

            string log = string.Format(CultureInfo.InvariantCulture, "{0} MSAL {1} {2} {3} [{4}{5}]{6} {7}",
                                       isLoggingPii ? "(True)" : "(False)",
                                       MsalIdHelper.GetMsalVersion(),
                                       msalIdParameters[MsalIdParameter.Product],
                                       os, DateTime.UtcNow, correlationId, Component, messageToLog);

            if (Logger.DefaultLoggingEnabled)
            {
                switch (Logger.Level)
                {
                case LogLevel.Error:
                    _platformLogger.Error(log);
                    break;

                case LogLevel.Warning:
                    _platformLogger.Warning(log);
                    break;

                case LogLevel.Info:
                    _platformLogger.Information(log);
                    break;

                case LogLevel.Verbose:
                    _platformLogger.Verbose(log);
                    break;
                }
            }

            ExecuteCallback(msalLogLevel, log, isLoggingPii);
        }
        public async Task <T> GetResponseAsync <T>(string endpointType)
        {
            T             typedResponse = default(T);
            ClientMetrics clientMetrics = new ClientMetrics();

            try
            {
                clientMetrics.BeginClientMetricsRecord(this.CallState);

                Dictionary <string, string> clientMetricsHeaders = clientMetrics.GetPreviousRequestRecord(this.CallState);
                foreach (KeyValuePair <string, string> kvp in clientMetricsHeaders)
                {
                    this.Client.Headers[kvp.Key] = kvp.Value;
                }

                IDictionary <string, string> adalIdHeaders = MsalIdHelper.GetMsalIdParameters();
                foreach (KeyValuePair <string, string> kvp in adalIdHeaders)
                {
                    this.Client.Headers[kvp.Key] = kvp.Value;
                }

                IHttpWebResponse response;
                using (response = await this.Client.GetResponseAsync().ConfigureAwait(false))
                {
                    typedResponse = DeserializeResponse <T>(response.ResponseStream);
                    clientMetrics.SetLastError(null);
                }
            }
            catch (HttpRequestWrapperException ex)
            {
                PlatformPlugin.Logger.Error(this.CallState, ex);
                MsalServiceException serviceEx;
                if (ex.WebResponse != null)
                {
                    TokenResponse tokenResponse = TokenResponse.CreateFromErrorResponse(ex.WebResponse);
                    string[]      errorCodes    = tokenResponse.ErrorCodes ?? new[] { ex.WebResponse.StatusCode.ToString() };
                    serviceEx = new MsalServiceException(tokenResponse.Error, tokenResponse.ErrorDescription,
                                                         errorCodes, ex);
                }
                else
                {
                    serviceEx = new MsalServiceException(MsalError.Unknown, ex);
                }

                clientMetrics.SetLastError(serviceEx.ServiceErrorCodes);
                PlatformPlugin.Logger.Error(CallState, serviceEx);
                throw serviceEx;
            }
            finally
            {
                clientMetrics.EndClientMetricsRecord(endpointType, this.CallState);
            }

            return(typedResponse);
        }
        private Dictionary <string, string> CreateAuthorizationRequestParameters(Uri redirectUriOverride = null)
        {
            var extraScopesToConsent = new SortedSet <string>();

            if (!_interactiveParameters.ExtraScopesToConsent.IsNullOrEmpty())
            {
                extraScopesToConsent = ScopeHelper.CreateSortedSetFromEnumerable(_interactiveParameters.ExtraScopesToConsent);
            }

            if (extraScopesToConsent.Contains(_requestParams.ClientId))
            {
                throw new ArgumentException("API does not accept client id as a user-provided scope");
            }

            SortedSet <string> unionScope = GetDecoratedScope(
                new SortedSet <string>(_requestParams.Scope.Union(extraScopesToConsent)));

            var authorizationRequestParameters = new Dictionary <string, string>
            {
                [OAuth2Parameter.Scope]        = unionScope.AsSingleString(),
                [OAuth2Parameter.ResponseType] = OAuth2ResponseType.Code,

                [OAuth2Parameter.ClientId]    = _requestParams.ClientId,
                [OAuth2Parameter.RedirectUri] = redirectUriOverride?.OriginalString ?? _requestParams.RedirectUri.OriginalString
            };

            if (!string.IsNullOrWhiteSpace(_requestParams.ClaimsAndClientCapabilities))
            {
                authorizationRequestParameters[OAuth2Parameter.Claims] = _requestParams.ClaimsAndClientCapabilities;
            }

            if (!string.IsNullOrWhiteSpace(_interactiveParameters.LoginHint))
            {
                authorizationRequestParameters[OAuth2Parameter.LoginHint] = _interactiveParameters.LoginHint;
            }

            if (_requestParams.RequestContext?.Logger?.CorrelationId != Guid.Empty)
            {
                authorizationRequestParameters[OAuth2Parameter.CorrelationId] =
                    _requestParams.RequestContext.Logger.CorrelationId.ToString();
            }

            foreach (KeyValuePair <string, string> kvp in MsalIdHelper.GetMsalIdParameters(_requestParams.RequestContext.Logger))
            {
                authorizationRequestParameters[kvp.Key] = kvp.Value;
            }

            if (_interactiveParameters.Prompt.PromptValue != Prompt.NoPrompt.PromptValue)
            {
                authorizationRequestParameters[OAuth2Parameter.Prompt] = _interactiveParameters.Prompt.PromptValue;
            }

            return(authorizationRequestParameters);
        }
        private Dictionary <string, string> CreateAuthorizationRequestParameters(Uri redirectUriOverride = null)
        {
            var extraScopesToConsent = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            if (!_interactiveParameters.ExtraScopesToConsent.IsNullOrEmpty())
            {
                extraScopesToConsent = ScopeHelper.CreateScopeSet(_interactiveParameters.ExtraScopesToConsent);
            }

            if (extraScopesToConsent.Contains(_requestParams.AppConfig.ClientId))
            {
                throw new ArgumentException("API does not accept client id as a user-provided scope");
            }

            var unionScope = ScopeHelper.GetMsalScopes(
                new HashSet <string>(_requestParams.Scope.Concat(extraScopesToConsent)));

            var authorizationRequestParameters = new Dictionary <string, string>
            {
                [OAuth2Parameter.Scope]        = unionScope.AsSingleString(),
                [OAuth2Parameter.ResponseType] = OAuth2ResponseType.Code,

                [OAuth2Parameter.ClientId]    = _requestParams.AppConfig.ClientId,
                [OAuth2Parameter.RedirectUri] = redirectUriOverride?.OriginalString ?? _requestParams.RedirectUri.OriginalString
            };

            if (!string.IsNullOrWhiteSpace(_requestParams.ClaimsAndClientCapabilities))
            {
                authorizationRequestParameters[OAuth2Parameter.Claims] = _requestParams.ClaimsAndClientCapabilities;
            }

            if (!string.IsNullOrWhiteSpace(_interactiveParameters.LoginHint))
            {
                authorizationRequestParameters[OAuth2Parameter.LoginHint] = _interactiveParameters.LoginHint;

                //The CCS header is used by the CCS service to help route requests to resources in Azure during requests to speed up authentication.
                //It consists of either the ObjectId.TenantId or the upn of the account signign in.
                //See https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/2525
                string OidCcsHeader = CoreHelpers.GetCcsUpnHeader(_interactiveParameters.LoginHint);
                authorizationRequestParameters[Constants.CcsRoutingHintHeader] = OidCcsHeader;
            }

            if (_requestParams.RequestContext.CorrelationId != Guid.Empty)
            {
                authorizationRequestParameters[OAuth2Parameter.CorrelationId] =
                    _requestParams.RequestContext.CorrelationId.ToString();
            }

            foreach (KeyValuePair <string, string> kvp in MsalIdHelper.GetMsalIdParameters(_requestParams.RequestContext.Logger))
            {
                authorizationRequestParameters[kvp.Key] = kvp.Value;
            }

            if (_interactiveParameters.Prompt == Prompt.NotSpecified)
            {
                authorizationRequestParameters[OAuth2Parameter.Prompt] = Prompt.SelectAccount.PromptValue;
            }
            else if (_interactiveParameters.Prompt.PromptValue != Prompt.NoPrompt.PromptValue)
            {
                authorizationRequestParameters[OAuth2Parameter.Prompt] = _interactiveParameters.Prompt.PromptValue;
            }

            return(authorizationRequestParameters);
        }
        private static Assembly LoadPlatformSpecificAssembly()
        {
            // For security reasons, it is important to have PublicKeyToken mentioned referencing the assembly.
            const string PlatformSpecificAssemblyNameTemplate =
                "Microsoft.Identity.Client.Platform, Version={0}, Culture=neutral, PublicKeyToken=0a613f4dd989e8ae";

            string platformSpecificAssemblyName = string.Format(CultureInfo.InvariantCulture,
                                                                PlatformSpecificAssemblyNameTemplate, MsalIdHelper.GetMsalVersion());

            try
            {
                return(Assembly.Load(new AssemblyName(platformSpecificAssemblyName)));
            }
            catch (FileNotFoundException ex)
            {
                PlatformPlugin.Logger.Error(null, ex);
                throw new MsalException(MsalError.AssemblyNotFound,
                                        string.Format(CultureInfo.InvariantCulture, MsalErrorMessage.AssemblyNotFoundTemplate,
                                                      platformSpecificAssemblyName), ex);
            }
            catch (Exception ex) // FileLoadException is missing from PCL
            {
                PlatformPlugin.Logger.Error(null, ex);
                throw new MsalException(MsalError.AssemblyLoadFailed,
                                        string.Format(CultureInfo.InvariantCulture, MsalErrorMessage.AssemblyLoadFailedTemplate,
                                                      platformSpecificAssemblyName), ex);
            }
        }