private async Task SendEmailVerificationCodeAsync()
        {
            var authorizationUri = CreateAuthorizationUri(true, true);
            var uiEvent          = new UiEvent();

            using (ServiceBundle.TelemetryManager.CreateTelemetryHelper(
                       AuthenticationRequestParameters.RequestContext.TelemetryRequestId,
                       AuthenticationRequestParameters.ClientId,
                       uiEvent))
            {
                var requestContext = AuthenticationRequestParameters.RequestContext;
                var response       = await _httpManager.SendGetAsync(authorizationUri, new Dictionary <string, string>(), requestContext).ConfigureAwait(false);

                if (response != null &&
                    response.StatusCode == HttpStatusCode.OK &&
                    !string.IsNullOrEmpty(response.Body))
                {
                    _csrf       = GetField(response.Body, "csrf");
                    _transId    = GetField(response.Body, "transId");
                    _policy     = GetField(response.Body, "policy"); // B2C_1_password_reset
                    _pageViewId = GetField(response.Body, "pageViewId");
                    var verifyEmailUri = CreateResetPasswordUri(_transId, _policy);
                    var postData       = new Dictionary <string, string>
                    {
                        ["request_type"] = "VERIFICATION_REQUEST",
                        ["claim_id"]     = "email",
                        ["claim_value"]  = Email
                    };
                    var response2 = await _httpManager.SendPostAsync(verifyEmailUri, new Dictionary <string, string> {
                        ["X-CSRF-TOKEN"] = _csrf
                    }, postData, requestContext).ConfigureAwait(false);

                    if (response2 != null &&
                        response2.StatusCode == HttpStatusCode.OK)
                    {
                        AuthorizationResult = new AuthorizationResult(AuthorizationStatus.Success);
                    }
                    else
                    {
                        AuthorizationResult = new AuthorizationResult(AuthorizationStatus.ErrorHttp);
                    }
                }
                else
                {
                    AuthorizationResult = new AuthorizationResult(AuthorizationStatus.ErrorHttp);
                }
                uiEvent.UserCancelled = AuthorizationResult.Status == AuthorizationStatus.UserCancel;
                uiEvent.AccessDenied  = AuthorizationResult.Status == AuthorizationStatus.ProtocolError;
            }
        }
        internal async Task <T> ExecuteRequestAsync <T>(Uri endPoint, HttpMethod method, RequestContext requestContext, bool expectErrorsOn200OK = false)
        {
            bool addCorrelationId = requestContext != null && !string.IsNullOrEmpty(requestContext.Logger.CorrelationId.ToString());

            AddCommonHeaders(requestContext, addCorrelationId);

            HttpResponse response    = null;
            Uri          endpointUri = CreateFullEndpointUri(endPoint);
            var          httpEvent   = new HttpEvent(requestContext.CorrelationId.AsMatsCorrelationId())
            {
                HttpPath    = endpointUri,
                QueryParams = endpointUri.Query
            };

            using (_telemetryManager.CreateTelemetryHelper(httpEvent))
            {
                if (method == HttpMethod.Post)
                {
                    response = await _httpManager.SendPostAsync(endpointUri, _headers, _bodyParameters, requestContext.Logger)
                               .ConfigureAwait(false);
                }
                else
                {
                    response = await _httpManager.SendGetAsync(endpointUri, _headers, requestContext.Logger).ConfigureAwait(false);
                }

                DecorateHttpEvent(method, requestContext, response, httpEvent);

                if (response.StatusCode != HttpStatusCode.OK || expectErrorsOn200OK)
                {
                    try
                    {
                        httpEvent.OauthErrorCode = MsalError.UnknownError;
                        // In cases where the end-point is not found (404) response.body will be empty.
                        // CreateResponse handles throwing errors - in the case of HttpStatusCode <> and ErrorResponse will be created.
                        if (!string.IsNullOrWhiteSpace(response.Body))
                        {
                            var msalTokenResponse = JsonHelper.DeserializeFromJson <MsalTokenResponse>(response.Body);
                            if (msalTokenResponse != null)
                            {
                                httpEvent.OauthErrorCode = msalTokenResponse?.Error;
                            }

                            if (response.StatusCode == HttpStatusCode.OK &&
                                expectErrorsOn200OK &&
                                !string.IsNullOrEmpty(msalTokenResponse.Error))
                            {
                                ThrowServerException(response, requestContext);
                            }
                        }
                    }
                    catch (JsonException) // in the rare case we get an error response we cannot deserialize
                    {
                        // CreateErrorResponse does the same validation. Will be logging the error there.
                    }
                }
            }

            return(CreateResponse <T>(response, requestContext, addCorrelationId));
        }
        internal async Task <T> ExecuteRequestAsync <T>(Uri endPoint, HttpMethod method, RequestContext requestContext)
        {
            HttpResponse response    = null;
            Uri          endpointUri = CreateFullEndpointUri(endPoint);

            if (method == HttpMethod.Post)
            {
                response = await _httpManager.SendPostAsync(endpointUri, _headers, _bodyParameters, requestContext)
                           .ConfigureAwait(false);
            }
            else
            {
                response = await _httpManager.SendGetAsync(endpointUri, _headers, requestContext).ConfigureAwait(false);
            }

            return(CreateResponse <T>(response, requestContext));
        }
Example #4
0
        internal async Task <T> ExecuteRequestAsync <T>(Uri endPoint, HttpMethod method, RequestContext requestContext)
        {
            bool addCorrelationId =
                requestContext != null && !string.IsNullOrEmpty(requestContext.Logger.CorrelationId.ToString());

            if (addCorrelationId)
            {
                _headers.Add(OAuth2Header.CorrelationId, requestContext.Logger.CorrelationId.ToString());
                _headers.Add(OAuth2Header.RequestCorrelationIdInResponse, "true");
            }

            HttpResponse response    = null;
            var          endpointUri = CreateFullEndpointUri(endPoint);
            var          httpEvent   = new HttpEvent()
            {
                HttpPath    = endpointUri,
                QueryParams = endpointUri.Query
            };

            using (_telemetryManager.CreateTelemetryHelper(requestContext.TelemetryRequestId, requestContext.ClientId, httpEvent))
            {
                if (method == HttpMethod.Post)
                {
                    response = await _httpManager.SendPostAsync(endpointUri, _headers, _bodyParameters, requestContext)
                               .ConfigureAwait(false);
                }
                else
                {
                    response = await _httpManager.SendGetAsync(endpointUri, _headers, requestContext).ConfigureAwait(false);
                }

                httpEvent.HttpResponseStatus = (int)response.StatusCode;
                httpEvent.UserAgent          = response.UserAgent;
                httpEvent.HttpMethod         = method.Method;

                IDictionary <string, string> headersAsDictionary = response.HeadersAsDictionary;
                if (headersAsDictionary.ContainsKey("x-ms-request-id") &&
                    headersAsDictionary["x-ms-request-id"] != null)
                {
                    httpEvent.RequestIdHeader = headersAsDictionary["x-ms-request-id"];
                }

                if (headersAsDictionary.ContainsKey("x-ms-clitelem") &&
                    headersAsDictionary["x-ms-clitelem"] != null)
                {
                    XmsCliTelemInfo xmsCliTeleminfo = new XmsCliTelemInfoParser().ParseXMsTelemHeader(headersAsDictionary["x-ms-clitelem"], requestContext);
                    if (xmsCliTeleminfo != null)
                    {
                        httpEvent.TokenAge           = xmsCliTeleminfo.TokenAge;
                        httpEvent.SpeInfo            = xmsCliTeleminfo.SpeInfo;
                        httpEvent.ServerErrorCode    = xmsCliTeleminfo.ServerErrorCode;
                        httpEvent.ServerSubErrorCode = xmsCliTeleminfo.ServerSubErrorCode;
                    }
                }

                if (response.StatusCode != HttpStatusCode.OK)
                {
                    try
                    {
                        httpEvent.OauthErrorCode = JsonHelper.DeserializeFromJson <MsalTokenResponse>(response.Body).Error;
                    }
                    catch (SerializationException) // in the rare case we get an error response we cannot deserialize
                    {
                        throw MsalExceptionFactory.GetServiceException(
                                  CoreErrorCodes.NonParsableOAuthError,
                                  CoreErrorMessages.NonParsableOAuthError,
                                  response);
                    }
                }
            }

            return(CreateResponse <T>(response, requestContext, addCorrelationId));
        }
Example #5
0
        internal async Task <T> ExecuteRequestAsync <T>(
            Uri endPoint,
            HttpMethod method,
            RequestContext requestContext,
            bool expectErrorsOn200OK = false,
            bool addCommonHeaders    = true,
            Func <OnBeforeTokenRequestData, Task> onBeforePostRequestData = null)
        {
            //Requests that are replayed by PKeyAuth do not need to have headers added because they already exist
            if (addCommonHeaders)
            {
                AddCommonHeaders(requestContext);
            }

            HttpResponse response    = null;
            Uri          endpointUri = AddExtraQueryParams(endPoint);

            using (requestContext.Logger.LogBlockDuration($"[Oauth2Client] Sending {method} request "))
            {
                if (method == HttpMethod.Post)
                {
                    if (onBeforePostRequestData != null)
                    {
                        var requestData = new OnBeforeTokenRequestData(_bodyParameters, _headers, endpointUri, requestContext.UserCancellationToken);
                        await onBeforePostRequestData(requestData).ConfigureAwait(false);
                    }

                    response = await _httpManager.SendPostAsync(
                        endpointUri,
                        _headers,
                        _bodyParameters,
                        requestContext.Logger,
                        requestContext.UserCancellationToken)
                               .ConfigureAwait(false);
                }
                else
                {
                    response = await _httpManager.SendGetAsync(
                        endpointUri,
                        _headers,
                        requestContext.Logger,
                        cancellationToken : requestContext.UserCancellationToken)
                               .ConfigureAwait(false);
                }
            }

            if (requestContext.ApiEvent != null)
            {
                requestContext.ApiEvent.DurationInHttpInMs += _httpManager.LastRequestDurationInMs;
            }

            if (response.StatusCode != HttpStatusCode.OK || expectErrorsOn200OK)
            {
                requestContext.Logger.Verbose("[Oauth2Client] Processing error response ");

                try
                {
                    // In cases where the end-point is not found (404) response.body will be empty.
                    // CreateResponse handles throwing errors - in the case of HttpStatusCode <> and ErrorResponse will be created.
                    if (!string.IsNullOrWhiteSpace(response.Body))
                    {
                        var msalTokenResponse = JsonHelper.DeserializeFromJson <MsalTokenResponse>(response.Body);

                        if (response.StatusCode == HttpStatusCode.OK &&
                            expectErrorsOn200OK &&
                            !string.IsNullOrEmpty(msalTokenResponse?.Error))
                        {
                            ThrowServerException(response, requestContext);
                        }
                    }
                }
                catch (JsonException) // in the rare case we get an error response we cannot deserialize
                {
                    // CreateErrorResponse does the same validation. Will be logging the error there.
                }
            }

            return(CreateResponse <T>(response, requestContext));
        }
Example #6
0
        internal async Task <T> ExecuteRequestAsync <T>(Uri endPoint, HttpMethod method, RequestContext requestContext)
        {
            bool addCorrelationId = requestContext != null && !string.IsNullOrEmpty(requestContext.Logger.CorrelationId.ToString());

            if (addCorrelationId)
            {
                _headers.Add(OAuth2Header.CorrelationId, requestContext.Logger.CorrelationId.ToString());
                _headers.Add(OAuth2Header.RequestCorrelationIdInResponse, "true");
            }

            if (!string.IsNullOrWhiteSpace(requestContext.Logger.ClientName))
            {
                _headers.Add(OAuth2Header.AppName, requestContext.Logger.ClientName);
            }

            if (!string.IsNullOrWhiteSpace(requestContext.Logger.ClientVersion))
            {
                _headers.Add(OAuth2Header.AppVer, requestContext.Logger.ClientVersion);
            }

            HttpResponse response    = null;
            Uri          endpointUri = CreateFullEndpointUri(endPoint);
            var          httpEvent   = new HttpEvent(requestContext.TelemetryCorrelationId)
            {
                HttpPath    = endpointUri,
                QueryParams = endpointUri.Query
            };

            using (_telemetryManager.CreateTelemetryHelper(httpEvent))
            {
                if (method == HttpMethod.Post)
                {
                    response = await _httpManager.SendPostAsync(endpointUri, _headers, _bodyParameters, requestContext.Logger)
                               .ConfigureAwait(false);
                }
                else
                {
                    response = await _httpManager.SendGetAsync(endpointUri, _headers, requestContext.Logger).ConfigureAwait(false);
                }

                httpEvent.HttpResponseStatus = (int)response.StatusCode;
                httpEvent.UserAgent          = response.UserAgent;
                httpEvent.HttpMethod         = method.Method;

                IDictionary <string, string> headersAsDictionary = response.HeadersAsDictionary;
                if (headersAsDictionary.ContainsKey("x-ms-request-id") &&
                    headersAsDictionary["x-ms-request-id"] != null)
                {
                    httpEvent.RequestIdHeader = headersAsDictionary["x-ms-request-id"];
                }

                if (headersAsDictionary.ContainsKey("x-ms-clitelem") &&
                    headersAsDictionary["x-ms-clitelem"] != null)
                {
                    XmsCliTelemInfo xmsCliTeleminfo = new XmsCliTelemInfoParser().ParseXMsTelemHeader(
                        headersAsDictionary["x-ms-clitelem"],
                        requestContext.Logger);

                    if (xmsCliTeleminfo != null)
                    {
                        httpEvent.TokenAge           = xmsCliTeleminfo.TokenAge;
                        httpEvent.SpeInfo            = xmsCliTeleminfo.SpeInfo;
                        httpEvent.ServerErrorCode    = xmsCliTeleminfo.ServerErrorCode;
                        httpEvent.ServerSubErrorCode = xmsCliTeleminfo.ServerSubErrorCode;
                    }
                }

                if (response.StatusCode != HttpStatusCode.OK)
                {
                    try
                    {
                        httpEvent.OauthErrorCode = MsalError.UnknownError;
                        // In cases where the end-point is not found (404) response.body will be empty.
                        // CreateResponse handles throwing errors - in the case of HttpStatusCode <> and ErrorResponse will be created.
                        if (!string.IsNullOrWhiteSpace(response.Body))
                        {
                            var msalTokenResponse = JsonHelper.DeserializeFromJson <MsalTokenResponse>(response.Body);
                            if (msalTokenResponse != null)
                            {
                                httpEvent.OauthErrorCode = msalTokenResponse.Error;
                            }
                        }
                    }
                    catch (SerializationException) // in the rare case we get an error response we cannot deserialize
                    {
                        // CreateErrorResponse does the same validation. Will be logging the error there.
                    }
                }
            }

            return(CreateResponse <T>(response, requestContext, addCorrelationId));
        }
        internal async Task <T> ExecuteRequestAsync <T>(Uri endPoint, HttpMethod method, RequestContext requestContext, bool expectErrorsOn200OK = false, bool addCommonHeaders = true)
        {
            //Requests that are replayed by PKeyAuth do not need to have headers added because they already exist
            if (addCommonHeaders)
            {
                AddCommonHeaders(requestContext);
            }

            HttpResponse response    = null;
            Uri          endpointUri = AddExtraQueryParams(endPoint);
            var          httpEvent   = new HttpEvent(requestContext.CorrelationId.AsMatsCorrelationId())
            {
                HttpPath    = endpointUri,
                QueryParams = endpointUri.Query
            };

            using (requestContext.CreateTelemetryHelper(httpEvent))
            {
                if (method == HttpMethod.Post)
                {
                    response = await _httpManager.SendPostAsync(endpointUri, _headers, _bodyParameters, requestContext.Logger)
                               .ConfigureAwait(false);
                }
                else
                {
                    response = await _httpManager.SendGetAsync(
                        endpointUri,
                        _headers,
                        requestContext.Logger,
                        cancellationToken : requestContext.UserCancellationToken).ConfigureAwait(false);
                }

                if (requestContext.ApiEvent != null)
                {
                    requestContext.ApiEvent.DurationInHttpInMs += _httpManager.LastRequestDurationInMs;
                }

                DecorateHttpEvent(method, requestContext, response, httpEvent);

                if (response.StatusCode != HttpStatusCode.OK || expectErrorsOn200OK)
                {
                    try
                    {
                        httpEvent.OauthErrorCode = MsalError.UnknownError;
                        // In cases where the end-point is not found (404) response.body will be empty.
                        // CreateResponse handles throwing errors - in the case of HttpStatusCode <> and ErrorResponse will be created.
                        if (!string.IsNullOrWhiteSpace(response.Body))
                        {
                            var msalTokenResponse = JsonHelper.DeserializeFromJson <MsalTokenResponse>(response.Body);
                            if (msalTokenResponse != null)
                            {
                                httpEvent.OauthErrorCode = msalTokenResponse?.Error;
                            }

                            if (response.StatusCode == HttpStatusCode.OK &&
                                expectErrorsOn200OK &&
                                !string.IsNullOrEmpty(msalTokenResponse?.Error))
                            {
                                ThrowServerException(response, requestContext);
                            }
                        }
                    }
                    catch (JsonException) // in the rare case we get an error response we cannot deserialize
                    {
                        // CreateErrorResponse does the same validation. Will be logging the error there.
                    }
                }
            }

            return(CreateResponse <T>(response, requestContext));
        }
Example #8
0
        internal protected override async Task AcquireAuthorizationAsync()
        {
            var authorizationUri = CreateAuthorizationUri(true, true);

            var uiEvent = new UiEvent();

            using (ServiceBundle.TelemetryManager.CreateTelemetryHelper(
                       AuthenticationRequestParameters.RequestContext.TelemetryRequestId,
                       AuthenticationRequestParameters.ClientId,
                       uiEvent))
            {
                var requestContext = AuthenticationRequestParameters.RequestContext;
                var response       = await _httpManager.SendGetAsync(authorizationUri, new Dictionary <string, string>(), requestContext).ConfigureAwait(false);

                if (response != null &&
                    response.StatusCode == HttpStatusCode.OK &&
                    !string.IsNullOrEmpty(response.Body))
                {
                    var csrf       = GetField(response.Body, "csrf");
                    var transId    = GetField(response.Body, "transId");
                    var policy     = GetField(response.Body, "policy");
                    var pageViewId = GetField(response.Body, "pageViewId");
                    var api        = GetField(response.Body, "api");
                    var logonUri   = CreateLogonUri(transId, policy);
                    var postData   = new Dictionary <string, string>
                    {
                        ["request_type"]    = "RESPONSE",
                        ["logonIdentifier"] = Username,
                        ["password"]        = Password
                    };
                    var response2 = await _httpManager.SendPostAsync(logonUri, new Dictionary <string, string> {
                        ["X-CSRF-TOKEN"] = csrf
                    }, postData, requestContext).ConfigureAwait(false);

                    if (response2 != null &&
                        response2.StatusCode == HttpStatusCode.OK)
                    {
                        var confirmedUri = CreateConfirmedUri(csrf, transId, policy, pageViewId, api);
                        var response3    = await _httpManager.SendGetAsync(confirmedUri, new Dictionary <string, string> {
                            ["x-ms-cpim-pageviewid"] = pageViewId
                        }, requestContext).ConfigureAwait(false);

                        if (response3 != null &&
                            (response3.StatusCode == HttpStatusCode.Found ||
                             response3.StatusCode == HttpStatusCode.OK))
                        {
                            AuthorizationResult = new AuthorizationResult(AuthorizationStatus.Success, response3.Headers?.Location);
                        }
                        else
                        {
                            AuthorizationResult = new AuthorizationResult(AuthorizationStatus.ErrorHttp);
                        }
                    }
                    else
                    {
                        AuthorizationResult = new AuthorizationResult(AuthorizationStatus.ErrorHttp);
                    }
                }
                else
                {
                    AuthorizationResult = new AuthorizationResult(AuthorizationStatus.ErrorHttp);
                }
                uiEvent.UserCancelled = AuthorizationResult.Status == AuthorizationStatus.UserCancel;
                uiEvent.AccessDenied  = AuthorizationResult.Status == AuthorizationStatus.ProtocolError;
            }
        }