示例#1
0
        private string CreateDeviceCodeRequestUriString()
        {
            var deviceCodeRequestParameters = new DictionaryRequestParameters(this.resource, this.clientKey);

            if (this.callState != null && this.callState.CorrelationId != Guid.Empty)
            {
                deviceCodeRequestParameters[OAuthParameter.CorrelationId] = this.callState.CorrelationId.ToString();
            }

            if (PlatformPlugin.HttpClientFactory.AddAdditionalHeaders)
            {
                IDictionary <string, string> adalIdParameters = AdalIdHelper.GetAdalIdParameters();
                foreach (KeyValuePair <string, string> kvp in adalIdParameters)
                {
                    deviceCodeRequestParameters[kvp.Key] = kvp.Value;
                }
            }

            if (!string.IsNullOrWhiteSpace(extraQueryParameters))
            {
                // Checks for extraQueryParameters duplicating standard parameters
                Dictionary <string, string> kvps = EncodingHelper.ParseKeyValueList(extraQueryParameters, '&', false, this.callState);
                foreach (KeyValuePair <string, string> kvp in kvps)
                {
                    if (deviceCodeRequestParameters.ContainsKey(kvp.Key))
                    {
                        throw new AdalException(AdalError.DuplicateQueryParameter, string.Format(CultureInfo.CurrentCulture, AdalErrorMessage.DuplicateQueryParameterTemplate, kvp.Key));
                    }
                }

                deviceCodeRequestParameters.ExtraQueryParameter = extraQueryParameters;
            }

            return(new Uri(new Uri(this.authenticator.DeviceCodeUri), "?" + deviceCodeRequestParameters).AbsoluteUri);
        }
        /// <summary>
        /// Creates authentication parameters from the WWW-Authenticate header in response received from resource. This method expects the header to contain authentication parameters.
        /// </summary>
        /// <param name="authenticateHeader">Content of header WWW-Authenticate header</param>
        /// <returns>AuthenticationParameters object containing authentication parameters</returns>
        public static AuthenticationParameters CreateFromResponseAuthenticateHeader(string authenticateHeader)
        {
            if (string.IsNullOrWhiteSpace(authenticateHeader))
            {
                throw new ArgumentNullException("authenticateHeader");
            }

            authenticateHeader = authenticateHeader.Trim();

            // This also checks for cases like "BearerXXXX authorization_uri=...." and "Bearer" and "Bearer "
            if (!authenticateHeader.StartsWith(Bearer, StringComparison.OrdinalIgnoreCase) ||
                authenticateHeader.Length < Bearer.Length + 2 ||
                !char.IsWhiteSpace(authenticateHeader[Bearer.Length]))
            {
                var ex = new ArgumentException(AdalErrorMessage.InvalidAuthenticateHeaderFormat, "authenticateHeader");
                PlatformPlugin.Logger.Error(null, ex);
                throw ex;
            }

            authenticateHeader = authenticateHeader.Substring(Bearer.Length).Trim();

            Dictionary <string, string> authenticateHeaderItems = EncodingHelper.ParseKeyValueList(authenticateHeader, ',', false, null);

            var    authParams = new AuthenticationParameters();
            string param;

            authenticateHeaderItems.TryGetValue(AuthorityKey, out param);
            authParams.Authority = param;
            authenticateHeaderItems.TryGetValue(ResourceKey, out param);
            authParams.Resource = param;

            return(authParams);
        }
        protected override void UpdateBrokerParameters(IDictionary <string, string> parameters)
        {
            Uri    uri   = new Uri(this.authorizationResult.Code);
            string query = EncodingHelper.UrlDecode(uri.Query);
            Dictionary <string, string> kvps = EncodingHelper.ParseKeyValueList(query, '&', false, this.CallState);

            parameters["username"] = kvps["username"];
        }
示例#4
0
            public override bool ShouldOverrideUrlLoading(WebView view, string url)
            {
                Uri uri = new Uri(url);

                if (url.StartsWith(BrokerConstants.BrowserExtPrefix))
                {
                    PlatformPlugin.Logger.Verbose(null, "It is browser launch request");
                    OpenLinkInBrowser(url, ((Activity)view.Context));
                    view.StopLoading();
                    ((Activity)view.Context).Finish();
                    return(true);
                }

                if (url.StartsWith(BrokerConstants.BrowserExtInstallPrefix))
                {
                    PlatformPlugin.Logger.Verbose(null, "It is an azure authenticator install request");
                    view.StopLoading();
                    this.Finish(view, url);
                    return(true);
                }

                if (url.StartsWith(BrokerConstants.ClientTlsRedirect, StringComparison.CurrentCultureIgnoreCase))
                {
                    string query = uri.Query;
                    if (query.StartsWith("?"))
                    {
                        query = query.Substring(1);
                    }

                    Dictionary <string, string> keyPair = EncodingHelper.ParseKeyValueList(query, '&', true, false, null);
                    string responseHeader = PlatformPlugin.DeviceAuthHelper.CreateDeviceAuthChallengeResponse(keyPair).Result;
                    Dictionary <string, string> pkeyAuthEmptyResponse = new Dictionary <string, string>();
                    pkeyAuthEmptyResponse[BrokerConstants.ChallangeResponseHeader] = responseHeader;
                    view.LoadUrl(keyPair["SubmitUrl"], pkeyAuthEmptyResponse);
                    return(true);
                }

                if (url.StartsWith(callback, StringComparison.OrdinalIgnoreCase))
                {
                    this.Finish(view, url);
                    return(true);
                }


                if (!url.Equals("about:blank", StringComparison.CurrentCultureIgnoreCase) && !uri.Scheme.Equals("https", StringComparison.CurrentCultureIgnoreCase))
                {
                    UriBuilder errorUri = new UriBuilder(callback);
                    errorUri.Query = string.Format("error={0}&error_description={1}",
                                                   AdalError.NonHttpsRedirectNotSupported, AdalErrorMessage.NonHttpsRedirectNotSupported);
                    this.Finish(view, errorUri.ToString());
                    return(true);
                }


                return(false);
            }
        private DictionaryRequestParameters CreateAuthorizationRequest(string loginHint)
        {
            var authorizationRequestParameters = new DictionaryRequestParameters(this.Resource, this.ClientKey);

            authorizationRequestParameters[OAuthParameter.ResponseType] = OAuthResponseType.Code;
            authorizationRequestParameters[OAuthParameter.HasChrome]    = "1";
            authorizationRequestParameters[OAuthParameter.RedirectUri]  = this.redirectUriRequestParameter;

            if (!string.IsNullOrWhiteSpace(loginHint))
            {
                authorizationRequestParameters[OAuthParameter.LoginHint] = loginHint;
            }

            if (this.CallState != null && this.CallState.CorrelationId != Guid.Empty)
            {
                authorizationRequestParameters[OAuthParameter.CorrelationId] = this.CallState.CorrelationId.ToString();
            }

            if (this.authorizationParameters != null)
            {
                PlatformPlugin.PlatformInformation.AddPromptBehaviorQueryParameter(this.authorizationParameters, authorizationRequestParameters);
            }

            if (PlatformPlugin.HttpClientFactory.AddAdditionalHeaders)
            {
                IDictionary <string, string> adalIdParameters = AdalIdHelper.GetAdalIdParameters();
                foreach (KeyValuePair <string, string> kvp in adalIdParameters)
                {
                    authorizationRequestParameters[kvp.Key] = kvp.Value;
                }
            }

            if (!string.IsNullOrWhiteSpace(extraQueryParameters))
            {
                // Checks for extraQueryParameters duplicating standard parameters
                Dictionary <string, string> kvps = EncodingHelper.ParseKeyValueList(extraQueryParameters, '&', false, this.CallState);
                foreach (KeyValuePair <string, string> kvp in kvps)
                {
                    if (authorizationRequestParameters.ContainsKey(kvp.Key))
                    {
                        throw new AdalException(AdalError.DuplicateQueryParameter, string.Format(CultureInfo.CurrentCulture, AdalErrorMessage.DuplicateQueryParameterTemplate, kvp.Key));
                    }
                }

                authorizationRequestParameters.ExtraQueryParameter = extraQueryParameters;
            }

            return(authorizationRequestParameters);
        }
        public void ParseAuthorizeResponse(string webAuthenticationResult)
        {
            var resultUri = new Uri(webAuthenticationResult);

            // NOTE: The Fragment property actually contains the leading '#' character and that must be dropped
            string resultData = resultUri.Query;

            if (!string.IsNullOrWhiteSpace(resultData))
            {
                // Remove the leading '?' first
                Dictionary <string, string> response = EncodingHelper.ParseKeyValueList(resultData.Substring(1), '&', true, null);

                if (response.ContainsKey(TokenResponseClaim.Code))
                {
                    this.Code = response[TokenResponseClaim.Code];
                }
                else if (webAuthenticationResult.StartsWith("msauth://", StringComparison.CurrentCultureIgnoreCase))
                {
                    this.Code = webAuthenticationResult;
                }
                else if (response.ContainsKey(TokenResponseClaim.Error))
                {
                    this.Error            = response[TokenResponseClaim.Error];
                    this.ErrorDescription = response.ContainsKey(TokenResponseClaim.ErrorDescription)
                        ? response[TokenResponseClaim.ErrorDescription]
                        : null;
                    this.Status = AuthorizationStatus.ProtocolError;
                }
                else
                {
                    this.Error            = AdalError.AuthenticationFailed;
                    this.ErrorDescription = AdalErrorMessage.AuthorizationServerInvalidResponse;
                    this.Status           = AuthorizationStatus.UnknownError;
                }
            }
            else
            {
                this.Error            = AdalError.AuthenticationFailed;
                this.ErrorDescription = AdalErrorMessage.AuthorizationServerInvalidResponse;
                this.Status           = AuthorizationStatus.UnknownError;
            }
        }
        public async Task <AuthenticationResultEx> AcquireTokenUsingBroker(IDictionary <string, string> brokerPayload)
        {
            if (brokerPayload.ContainsKey("silent_broker_flow"))
            {
                throw new AdalSilentTokenAcquisitionException();
            }

            brokerResponse      = null;
            brokerResponseReady = new SemaphoreSlim(0);

            //call broker
            string base64EncodedString = Base64UrlEncoder.Encode(BrokerKeyHelper.GetRawBrokerKey());

            brokerPayload["broker_key"]       = base64EncodedString;
            brokerPayload["max_protocol_ver"] = "2";

            if (brokerPayload.ContainsKey("broker_install_url"))
            {
                string url   = brokerPayload["broker_install_url"];
                Uri    uri   = new Uri(url);
                string query = uri.Query;
                if (query.StartsWith("?"))
                {
                    query = query.Substring(1);
                }

                Dictionary <string, string> keyPair = EncodingHelper.ParseKeyValueList(query, '&', true, false, null);

                DispatchQueue.MainQueue.DispatchAsync(() => UIApplication.SharedApplication.OpenUrl(new NSUrl(keyPair["app_link"])));

                throw new AdalException(AdalErrorIOSEx.BrokerApplicationRequired, AdalErrorMessageIOSEx.BrokerApplicationRequired);
            }
            else
            {
                NSUrl url = new NSUrl("msauth://broker?" + brokerPayload.ToQueryParameter());
                DispatchQueue.MainQueue.DispatchAsync(() => UIApplication.SharedApplication.OpenUrl(url));
            }

            await brokerResponseReady.WaitAsync();

            return(ProcessBrokerResponse());
        }
        private AuthenticationResultEx ResultFromBrokerResponse(IDictionary <string, string> responseDictionary)
        {
            TokenResponse response = new TokenResponse();

            if (responseDictionary.ContainsKey("error") || responseDictionary.ContainsKey("error_description"))
            {
                response = TokenResponse.CreateFromBrokerResponse(responseDictionary);
            }
            else
            {
                string expectedHash       = responseDictionary["hash"];
                string encryptedResponse  = responseDictionary["response"];
                string decryptedResponse  = BrokerKeyHelper.DecryptBrokerResponse(encryptedResponse);
                string responseActualHash = PlatformPlugin.CryptographyHelper.CreateSha256Hash(decryptedResponse);
                byte[] rawHash            = Convert.FromBase64String(responseActualHash);
                string hash = BitConverter.ToString(rawHash);
                if (expectedHash.Equals(hash.Replace("-", "")))
                {
                    responseDictionary = EncodingHelper.ParseKeyValueList(decryptedResponse, '&', false, null);
                    response           = TokenResponse.CreateFromBrokerResponse(responseDictionary);
                }
                else
                {
                    response = new TokenResponse
                    {
                        Error            = AdalError.BrokerReponseHashMismatch,
                        ErrorDescription = AdalErrorMessage.BrokerReponseHashMismatch
                    };
                }
            }

            var dateTimeOffset = new DateTimeOffset(new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc));

            dateTimeOffset = dateTimeOffset.AddSeconds(response.ExpiresOn);
            return(response.GetResult(dateTimeOffset));
        }
示例#9
0
        void DecidePolicyForNavigation(WebView webView, NSDictionary actionInformation, NSUrlRequest request, WebFrame frame, NSObject decisionToken)
        {
            if (request == null)
            {
                WebView.DecideUse(decisionToken);
                return;
            }

            string requestUrlString = request.Url.ToString();

            if (requestUrlString.StartsWith(BrokerConstants.BrowserExtPrefix, StringComparison.OrdinalIgnoreCase))
            {
                var result = new AuthorizationResult(AuthorizationStatus.ProtocolError)
                {
                    Error            = "Unsupported request",
                    ErrorDescription = "Server is redirecting client to browser. This behavior is not yet defined on Mac OS X."
                };
                callbackMethod(result);
                WebView.DecideIgnore(decisionToken);
                Close();
                return;
            }

            if (requestUrlString.ToLower(CultureInfo.InvariantCulture).StartsWith(callback.ToLower(CultureInfo.InvariantCulture), StringComparison.OrdinalIgnoreCase) ||
                requestUrlString.StartsWith(BrokerConstants.BrowserExtInstallPrefix, StringComparison.OrdinalIgnoreCase))
            {
                callbackMethod(new AuthorizationResult(AuthorizationStatus.Success, request.Url.ToString()));
                WebView.DecideIgnore(decisionToken);
                Close();
                return;
            }

            if (requestUrlString.StartsWith(BrokerConstants.DeviceAuthChallengeRedirect, StringComparison.CurrentCultureIgnoreCase))
            {
                var    uri   = new Uri(requestUrlString);
                string query = uri.Query;
                if (query.StartsWith("?", StringComparison.OrdinalIgnoreCase))
                {
                    query = query.Substring(1);
                }

                Dictionary <string, string> keyPair = EncodingHelper.ParseKeyValueList(query, '&', true, false, null);
                string responseHeader = PlatformPlugin.DeviceAuthHelper.CreateDeviceAuthChallengeResponse(keyPair).Result;

                var newRequest = (NSMutableUrlRequest)request.MutableCopy();
                newRequest.Url = new NSUrl(keyPair["SubmitUrl"]);
                newRequest[BrokerConstants.ChallengeResponseHeader] = responseHeader;
                webView.MainFrame.LoadRequest(newRequest);
                WebView.DecideIgnore(decisionToken);
                return;
            }

            if (!request.Url.AbsoluteString.Equals("about:blank", StringComparison.CurrentCultureIgnoreCase) && !request.Url.Scheme.Equals("https", StringComparison.CurrentCultureIgnoreCase))
            {
                var result = new AuthorizationResult(AuthorizationStatus.ErrorHttp);
                result.Error            = AdalError.NonHttpsRedirectNotSupported;
                result.ErrorDescription = AdalErrorMessage.NonHttpsRedirectNotSupported;
                callbackMethod(result);
                WebView.DecideIgnore(decisionToken);
                Close();
            }

            WebView.DecideUse(decisionToken);
        }
        void WebView_NavigateToUrl(object sender, NavigateToUrlEventArgs e)
        {
            /*Console.WriteLine(e.Uri);
             * if (e.Uri.ToString().StartsWith("urn:ietf:wg:oauth:2.0:oob", StringComparison.InvariantCultureIgnoreCase))
             * {
             *  Console.WriteLine("MAGICAL SPECIAL HANDLING");
             *  Application.Invoke(delegate { progressIndicator.Indeterminate = true; progressIndicator.Fraction = 0;});
             * }*/

            if (e == null)
            {
                return;
            }

            string requestUrlString = e.Uri.ToString();

            if (requestUrlString.StartsWith(BrokerConstants.BrowserExtPrefix, StringComparison.OrdinalIgnoreCase))
            {
                var result = new AuthorizationResult(AuthorizationStatus.ProtocolError)
                {
                    Error            = "Unsupported request",
                    ErrorDescription = "Server is redirecting client to browser. This behavior is not yet defined on Mac OS X."
                };
                callbackMethod(result);
                webView.StopLoading();
                Application.Invoke(delegate { Close(); });
                return;
            }

            if (requestUrlString.ToLower(CultureInfo.InvariantCulture).StartsWith(callback.ToLower(CultureInfo.InvariantCulture), StringComparison.OrdinalIgnoreCase) ||
                requestUrlString.StartsWith(BrokerConstants.BrowserExtInstallPrefix, StringComparison.OrdinalIgnoreCase))
            {
                callbackMethod(new AuthorizationResult(AuthorizationStatus.Success, requestUrlString));
                webView.StopLoading();
                Application.Invoke(delegate { Close(); });
                return;
            }

            if (requestUrlString.StartsWith(BrokerConstants.DeviceAuthChallengeRedirect, StringComparison.CurrentCultureIgnoreCase))
            {
                var    uri   = new Uri(requestUrlString);
                string query = uri.Query;
                if (query.StartsWith("?", StringComparison.OrdinalIgnoreCase))
                {
                    query = query.Substring(1);
                }

                Dictionary <string, string> keyPair = EncodingHelper.ParseKeyValueList(query, '&', true, false, null);
                string responseHeader = PlatformPlugin.DeviceAuthHelper.CreateDeviceAuthChallengeResponse(keyPair).Result;

                /*var newRequest = WebRequest.CreateHttp(keyPair["SubmitUrl"]);
                 * newRequest.Headers[BrokerConstants.ChallengeResponseHeader] = responseHeader;
                 * var newRequest = (NSMutableUrlRequest)request.MutableCopy();
                 * newRequest.Url = new NSUrl(keyPair["SubmitUrl"]);
                 * newRequest[BrokerConstants.ChallengeResponseHeader] = responseHeader;
                 * webView.MainFrame.LoadRequest(newRequest);
                 * WebView.DecideIgnore(decisionToken);*/
                return;
            }

            if (!e.Uri.AbsoluteUri.Equals("about:blank", StringComparison.CurrentCultureIgnoreCase) && !e.Uri.Scheme.Equals("https", StringComparison.CurrentCultureIgnoreCase))
            {
                var result = new AuthorizationResult(AuthorizationStatus.ErrorHttp);
                result.Error            = AdalError.NonHttpsRedirectNotSupported;
                result.ErrorDescription = AdalErrorMessage.NonHttpsRedirectNotSupported;
                callbackMethod(result);
                webView.StopLoading();
                Application.Invoke(delegate { Close(); });
            }
        }
示例#11
0
        public void AcquireToken(IDictionary <string, string> brokerPayload)
        {
            if (brokerPayload.ContainsKey("broker_install_url"))
            {
                string url   = brokerPayload["broker_install_url"];
                Uri    uri   = new Uri(url);
                string query = uri.Query;
                if (query.StartsWith("?"))
                {
                    query = query.Substring(1);
                }

                Dictionary <string, string> keyPair = EncodingHelper.ParseKeyValueList(query, '&', true, false, null);

                PlatformParameters pp = PlatformParameters as PlatformParameters;
                pp.CallerActivity.StartActivity(new Intent(Intent.ActionView, Android.Net.Uri.Parse(keyPair["app_link"])));

                throw new AdalException(AdalErrorAndroidEx.BrokerApplicationRequired, AdalErrorMessageAndroidEx.BrokerApplicationRequired);
            }

            Context mContext = Application.Context;
            AuthenticationRequest request        = new AuthenticationRequest(brokerPayload);
            PlatformParameters    platformParams = PlatformParameters as PlatformParameters;

            // BROKER flow intercepts here
            // cache and refresh call happens through the authenticator service
            if (mBrokerProxy.VerifyUser(request.LoginHint,
                                        request.UserId))
            {
                PlatformPlugin.Logger.Verbose(null, "It switched to broker for context: " + mContext.PackageName);
                request.BrokerAccountName = request.LoginHint;

                // Don't send background request, if prompt flag is always or
                // refresh_session
                if (!string.IsNullOrEmpty(request.BrokerAccountName) || !string.IsNullOrEmpty(request.UserId))
                {
                    PlatformPlugin.Logger.Verbose(null, "User is specified for background token request");
                    resultEx = mBrokerProxy.GetAuthTokenInBackground(request, platformParams.CallerActivity);
                }
                else
                {
                    PlatformPlugin.Logger.Verbose(null, "User is not specified for background token request");
                }

                if (resultEx != null && resultEx.Result != null && !string.IsNullOrEmpty(resultEx.Result.AccessToken))
                {
                    PlatformPlugin.Logger.Verbose(null, "Token is returned from background call ");
                    readyForResponse.Release();
                    return;
                }

                // Launch broker activity
                // if cache and refresh request is not handled.
                // Initial request to authenticator needs to launch activity to
                // record calling uid for the account. This happens for Prompt auto
                // or always behavior.
                PlatformPlugin.Logger.Verbose(null, "Token is not returned from backgroud call");

                // Only happens with callback since silent call does not show UI
                PlatformPlugin.Logger.Verbose(null, "Launch activity for Authenticator");
                PlatformPlugin.Logger.Verbose(null, "Starting Authentication Activity");
                if (resultEx == null)
                {
                    PlatformPlugin.Logger.Verbose(null, "Initial request to authenticator");
                    // Log the initial request but not force a prompt
                }

                if (brokerPayload.ContainsKey("silent_broker_flow"))
                {
                    throw new AdalSilentTokenAcquisitionException();
                }

                // onActivityResult will receive the response
                // Activity needs to launch to record calling app for this
                // account
                Intent brokerIntent = mBrokerProxy.GetIntentForBrokerActivity(request, platformParams.CallerActivity);
                if (brokerIntent != null)
                {
                    try
                    {
                        PlatformPlugin.Logger.Verbose(null, "Calling activity pid:" + Android.OS.Process.MyPid()
                                                      + " tid:" + Android.OS.Process.MyTid() + "uid:"
                                                      + Android.OS.Process.MyUid());
                        platformParams.CallerActivity.StartActivityForResult(brokerIntent, 1001);
                    }
                    catch (ActivityNotFoundException e)
                    {
                        PlatformPlugin.Logger.Error(null, e);
                    }
                }
            }
            else
            {
                throw new AdalException(AdalErrorAndroidEx.NoBrokerAccountFound, "Add requested account as a Workplace account via Settings->Accounts or set UseBroker=true.");
            }
        }
示例#12
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            View.BackgroundColor = UIColor.White;

            webView = new UIWebView((CGRect)View.Bounds);
            webView.ShouldStartLoad = (wView, request, navType) =>
            {
                if (request == null)
                {
                    return(true);
                }

                string requestUrlString = request.Url.ToString();

                if (requestUrlString.StartsWith(BrokerConstants.BrowserExtPrefix, StringComparison.OrdinalIgnoreCase))
                {
                    DispatchQueue.MainQueue.DispatchAsync(() => CancelAuthentication(null, null));
                    requestUrlString = requestUrlString.Replace(BrokerConstants.BrowserExtPrefix, "https://");
                    DispatchQueue.MainQueue.DispatchAsync(
                        () => UIApplication.SharedApplication.OpenUrl(new NSUrl(requestUrlString)));
                    this.DismissViewController(true, null);
                    return(false);
                }

                if (requestUrlString.ToLower(CultureInfo.InvariantCulture).StartsWith(callback.ToLower(CultureInfo.InvariantCulture), StringComparison.OrdinalIgnoreCase) ||
                    requestUrlString.StartsWith(BrokerConstants.BrowserExtInstallPrefix, StringComparison.OrdinalIgnoreCase))
                {
                    callbackMethod(new AuthorizationResult(AuthorizationStatus.Success, request.Url.ToString()));
                    this.DismissViewController(true, null);
                    return(false);
                }

                if (requestUrlString.StartsWith(BrokerConstants.DeviceAuthChallengeRedirect, StringComparison.CurrentCultureIgnoreCase))
                {
                    Uri    uri   = new Uri(requestUrlString);
                    string query = uri.Query;
                    if (query.StartsWith("?", StringComparison.OrdinalIgnoreCase))
                    {
                        query = query.Substring(1);
                    }

                    Dictionary <string, string> keyPair = EncodingHelper.ParseKeyValueList(query, '&', true, false, null);
                    string responseHeader = PlatformPlugin.DeviceAuthHelper.CreateDeviceAuthChallengeResponse(keyPair).Result;

                    NSMutableUrlRequest newRequest = (NSMutableUrlRequest)request.MutableCopy();
                    newRequest.Url = new NSUrl(keyPair["SubmitUrl"]);
                    newRequest[BrokerConstants.ChallengeResponseHeader] = responseHeader;
                    wView.LoadRequest(newRequest);
                    return(false);
                }

                if (!request.Url.AbsoluteString.Equals("about:blank", StringComparison.CurrentCultureIgnoreCase) && !request.Url.Scheme.Equals("https", StringComparison.CurrentCultureIgnoreCase))
                {
                    AuthorizationResult result = new AuthorizationResult(AuthorizationStatus.ErrorHttp);
                    result.Error            = AdalError.NonHttpsRedirectNotSupported;
                    result.ErrorDescription = AdalErrorMessage.NonHttpsRedirectNotSupported;
                    callbackMethod(result);
                    this.DismissViewController(true, null);
                    return(false);
                }

                return(true);
            };

            webView.LoadFinished += delegate
            {
                // If the title is too long, iOS automatically truncates it and adds ...
                this.Title = webView.EvaluateJavascript(@"document.title") ?? "Sign in";
            };

            View.AddSubview(webView);

            this.NavigationItem.LeftBarButtonItem = new UIBarButtonItem(UIBarButtonSystemItem.Cancel,
                                                                        this.CancelAuthentication);

            webView.LoadRequest(new NSUrlRequest(new NSUrl(this.url)));

            // if this is false, page will be 'zoomed in' to normal size
            //webView.ScalesPageToFit = true;
        }