/// <summary>
        /// Event handler called when a new page is being loaded in the web browser.
        /// </summary>
        /// <param name='url'>
        /// The URL of the page.
        /// </param>
        /// <param name="formParams">
        /// The parsed form parameters from the HTTP message body.
        /// </param>
        public override void OnPageLoading(Uri url, IDictionary <string, string> formParams)
        {
            var query    = WebEx.FormDecode(url.Query);
            var fragment = WebEx.FormDecode(url.Fragment);

            OnPageEncountered(url, query, fragment, formParams);
        }
        /// <summary>
        /// Asynchronously makes a request to the access token URL with the given parameters.
        /// </summary>
        /// <param name="queryValues">The parameters to make the request with.</param>
        /// <returns>The data provided in the response to the access token request.</returns>
        protected async Task <IDictionary <string, string> > RequestAccessTokenAsync(IDictionary <string, string> queryValues)
        {
            var content = new FormUrlEncodedContent(queryValues);


            HttpClient          client   = new HttpClient();
            HttpResponseMessage response = await client.PostAsync(accessTokenUrl, content).ConfigureAwait(false);

            string text = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

            // Parse the response
            var data = text.Contains("{") ? WebEx.JsonDecode(text) : WebEx.FormDecode(text);

            if (data.ContainsKey("error"))
            {
                throw new AuthException("Error authenticating: " + data ["error"]);
            }
            else if (data.ContainsKey("access_token"))
            {
                return(data);
            }
            else
            {
                throw new AuthException("Expected access_token in access token response, but did not receive one.");
            }
        }
        public override Task <Uri> GetInitialUrlAsync()
        {
            var req = OAuth1.CreateRequest(
                "GET",
                requestTokenUrl,
                new Dictionary <string, string> (),
                consumerKey,
                consumerSecret,
                ""
                );

            return(req.GetResponseAsync().ContinueWith(respTask => {
                var content = respTask.Result.GetResponseText();

                var r = WebEx.FormDecode(content);

                token = r["oauth_token"];
                tokenSecret = r["oauth_token_secret"];

                string paramType = authorizeUrl.AbsoluteUri.IndexOf("?") >= 0 ? "&" : "?";

                var url = String.Format("{0}{1}oauth_token={2}&oauth_callback={3}",
                                        authorizeUrl.AbsoluteUri,
                                        paramType,
                                        Uri.EscapeDataString(token),
                                        Uri.EscapeDataString(callbackUrl.AbsoluteUri));

                return new Uri(url);
            }));
        }
        /// <summary>
        /// Gets the UI for this authenticator.
        /// </summary>
        /// <returns>
        /// The UI that needs to be presented.
        /// </returns>
        protected override AuthenticateUIType GetPlatformUI()
        {
            AuthenticateUIType ui = null;

            if (this.IsUsingNativeUI == true)
            {
                Uri uri = GetInitialUrlAsync().Result;
                IDictionary <string, string> query_parts = WebEx.FormDecode(uri.Query);
                if (query_parts.ContainsKey("redirect_uri"))
                {
                    Uri    redirect_uri = new Uri(query_parts["redirect_uri"]);
                    string scheme       = redirect_uri.Scheme;
                    if (scheme.StartsWith("http", StringComparison.InvariantCultureIgnoreCase))
                    {
                        StringBuilder sb = new StringBuilder();
                        sb.AppendLine("WARNING");
                        sb.AppendLine($"Scheme = {scheme}");
                        sb.AppendLine($"Native UI used with http[s] schema!");
                        sb.AppendLine($"Redirect URL will be loaded in Native UI!");
                        sb.AppendLine($"OAuth Data parsing might fail!");

                        ShowErrorForNativeUI(sb.ToString());
                    }
                }
                ui = GetPlatformUINative();
            }
            else
            {
                ui = GetPlatformUIEmbeddedBrowser();
            }

            return(ui);
        }
        /// <summary>
        /// Asynchronously makes a request to the access token URL with the given parameters.
        /// </summary>
        /// <param name="queryValues">The parameters to make the request with.</param>
        /// <returns>The data provided in the response to the access token request.</returns>
        protected Task <IDictionary <string, string> > RequestAccessTokenAsync(IDictionary <string, string> queryValues)
        {
            var query = queryValues.FormEncode();

            var req = WebRequest.Create(accessTokenUrl);

            req.Method = "POST";
            var body = Encoding.UTF8.GetBytes(query);

            req.ContentLength = body.Length;
            req.ContentType   = "application/x-www-form-urlencoded";
            using (var s = req.GetRequestStream())
            {
                s.Write(body, 0, body.Length);
            }
            return(req.GetResponseAsync().ContinueWith(task => {
                var text = task.Result.GetResponseText();

                // Parse the response
                var data = text.Contains("{") ? WebEx.JsonDecode(text) : WebEx.FormDecode(text);

                if (data.ContainsKey("error"))
                {
                    throw new AuthException("Error authenticating: " + data["error"]);
                }
                else if (data.ContainsKey("access_token"))
                {
                    return data;
                }
                else
                {
                    throw new AuthException("Expected access_token in access token response, but did not receive one.");
                }
            }));
        }
Example #6
0
        /// <summary>
        /// Method that returns the initial URL to be displayed in the web browser.
        /// </summary>
        /// <returns>
        /// A task that will return the initial URL.
        /// </returns>
        public override Task <Uri> GetInitialUrlAsync()
        {
            var req = OAuth1.CreateRequest(
                "GET",
                requestTokenUrl,
                new Dictionary <string, string>()
            {
                { "oauth_callback", callbackUrl.AbsoluteUri },
            },
                consumerKey,
                consumerSecret,
                "");

            return(req.GetResponseAsync().ContinueWith(respTask => {
                var content = respTask.Result.GetResponseText();

                var r = WebEx.FormDecode(content);

                token = r["oauth_token"];
                tokenSecret = r["oauth_token_secret"];

                var url = authorizeUrl.AbsoluteUri + "?oauth_token=" + Uri.EscapeDataString(token);

                return new Uri(url);
            }));
        }
        /// <summary>
        /// Event handler called when a page has completed loading.
        /// </summary>
        /// <param name='url'>
        /// The URL of the page.
        /// </param>
        public override void OnPageLoaded(Uri url)
        {
            var query    = WebEx.FormDecode(url.Query);
            var fragment = WebEx.FormDecode(url.Fragment);

            OnPageEncountered(url, query, fragment);
        }
        /// <summary>
        /// Asynchronously makes a request to the access token URL with the given parameters.
        /// </summary>
        /// <param name="queryValues">The parameters to make the request with.</param>
        /// <returns>The data provided in the response to the access token request.</returns>
        protected async Task <IDictionary <string, string> > RequestAccessTokenAsync(IDictionary <string, string> queryValues)
        {
            var query = queryValues.FormEncode();

            HttpClient client = new HttpClient();
            //var response = await client.PostAsync(accessTokenUrl.AbsoluteUri, new StringContent(query, Encoding.UTF8, "application/x-www-form-urlencoded"));
            //var text = await response.Content.ReadAsStringAsync();

            //// Parse the response
            //var data = text.Contains("{") ? WebEx.JsonDecode(text) : WebEx.FormDecode(text);

            //if (data.ContainsKey("error"))
            //{
            //    throw new AuthException("Error authenticating: " + data["error"]);
            //}
            //else if (data.ContainsKey("access_token"))
            //{
            //    return data;
            //}
            //else
            //{
            //    throw new AuthException("Expected access_token in access token response, but did not receive one.");
            //}

            //var query = queryValues.FormEncode();

            //var req = WebRequest.Create(accessTokenUrl);
            //req.Method = "POST";
            //var body = Encoding.UTF8.GetBytes(query);
            //req.ContentLength = body.Length;
            //req.ContentType = "application/x-www-form-urlencoded";
            //using (var s = req.GetRequestStream())
            //{
            //    s.Write(body, 0, body.Length);
            //}
            var taskPost = client.PostAsync(accessTokenUrl.AbsoluteUri, new StringContent(query, Encoding.UTF8, "application/x-www-form-urlencoded"));

            taskPost.Wait();
            var taskReadResponse = taskPost.Result.Content.ReadAsStringAsync();

            taskReadResponse.Wait();

            var text = taskReadResponse.Result;

            // Parse the response
            var data = text.Contains("{") ? WebEx.JsonDecode(text) : WebEx.FormDecode(text);

            if (data.ContainsKey("error"))
            {
                throw new AuthException("Error authenticating: " + data["error"]);
            }
            else if (data.ContainsKey("access_token"))
            {
                return(data);
            }
            else
            {
                throw new AuthException("Expected access_token in access token response, but did not receive one.");
            }
        }
        protected async Task <IDictionary <string, string> > RequestAccessTokenAsync(CancellationToken cancellationToken)
        {
            var query = FieldsToFormUrlEncodedContent();

            using (var client = new HttpClient(new NativeMessageHandler()))
            {
                var response = await client.PostAsync(_accessTokenUrl, query, cancellationToken);

                var contentStream = await response.Content.ReadAsStringAsync();

                if (!response.IsSuccessStatusCode)
                {
                    if (response.Content.Headers.ContentType.MediaType.Contains("html"))
                    {
                        throw new AuthException($"{response.StatusCode}: {response.ReasonPhrase}");
                    }
                }

                var data = contentStream.Contains("{")
                        ? WebEx.JsonDecode(contentStream)
                        : WebEx.FormDecode(contentStream);

                if (data.ContainsKey("access_token") || data.ContainsKey("error"))
                {
                    return(data);
                }

                throw new AuthException("Expected an access_token or error header in the response message.");
            }
        }
            public override void DecidePolicy
            (
                WKWebView webView,
                WKNavigationAction navigationAction,
                Action <WKNavigationActionPolicy> decisionHandler
            )
            {
                #if DEBUG
                StringBuilder sb = new StringBuilder();
                sb.AppendLine($"WKWebViewNavigationDelegate.DecidePolicy ");
                sb.AppendLine($"        webView.Url.AbsoluteString = {webView.Url.AbsoluteString}");
                sb.AppendLine($"        navigationAction?.Request?.Url = {navigationAction?.Request?.Url}");
                sb.AppendLine($"        navigationAction?.NavigationType = {navigationAction?.NavigationType}");
                System.Diagnostics.Debug.WriteLine(sb.ToString());
                #endif

                Uri    uri      = new Uri(webView.Url.AbsoluteString);
                string fragment = uri.Fragment;

                if
                (
                    fragment.Contains("access_token")
                    ||
                    fragment.Contains("state")
                    ||
                    fragment.Contains("expires_in")
                    ||
                    fragment.Contains("error")
                )
                {
                    IDictionary <string, string> fragments = WebEx.FormDecode(uri.Fragment);

                    Account account = new Account
                                      (
                        "",
                        new Dictionary <string, string>(fragments)
                                      );
                    controller.authenticator.OnSucceeded(account);
                }
                else if
                (
                    fragment.Contains("code")
                )
                {
                    throw new NotImplementedException("code - Explicit/Server");
                }

                if (navigationAction.NavigationType == WKNavigationType.LinkActivated)
                {
                    UIApplication.SharedApplication.OpenUrl(navigationAction.Request.Url);
                    decisionHandler(WKNavigationActionPolicy.Cancel);
                    return;
                }

                // Navigation Allowed?
                // page will not load without this one!
                decisionHandler(WKNavigationActionPolicy.Allow);
            }
        /// <summary>
        /// Event handler called when a new page is being loaded in the web browser.
        /// </summary>
        /// <param name='url'>
        /// The URL of the page.
        /// </param>
        public override bool OnPageLoading(Uri url)
        {
            var query    = WebEx.FormDecode(url.Query);
            var fragment = WebEx.FormDecode(url.Fragment);

            OnPageEncountered(url, query, fragment);

            return(true);
        }
Example #12
0
        Task GetAccessTokenAsync()
        {
            var requestParams = new Dictionary <string, string> {
                { "oauth_token", token }
            };

            if (verifier != null)
            {
                requestParams["oauth_verifier"] = verifier;
            }

            var req = OAuth1.CreateRequest(
                "GET",
                accessTokenUrl,
                requestParams,
                consumerKey,
                consumerSecret,
                tokenSecret);

            if (this.HttpWebClientFrameworkType == HttpWebClientFrameworkType.WebRequest)
            {
                return(req.GetResponseAsync().ContinueWith(respTask =>
                {
                    var content = respTask.Result.GetResponseText();

                    var accountProperties = WebEx.FormDecode(content);
                    accountProperties["oauth_consumer_key"] = consumerKey;
                    accountProperties["oauth_consumer_secret"] = consumerSecret;

                    if (getUsernameAsync != null)
                    {
                        getUsernameAsync(accountProperties).ContinueWith(uTask =>
                        {
                            if (uTask.IsFaulted)
                            {
                                OnError(uTask.Exception);
                            }
                            else
                            {
                                OnSucceeded(uTask.Result, accountProperties);
                            }
                        });
                    }
                    else
                    {
                        OnSucceeded("", accountProperties);
                    }
                }));
            }
            else if (this.HttpWebClientFrameworkType == HttpWebClientFrameworkType.HttpClient)
            {
                throw new NotImplementedException("HttpClient implementation!");
            }

            return(null);
        }
        /// <summary>
        /// Method that returns the initial URL to be displayed in the web browser.
        /// </summary>
        /// <returns>
        /// A task that will return the initial URL.
        /// </returns>
        public override Task <Uri> GetInitialUrlAsync()
        {
            /*
             *                  mc++
             *                  OriginalString property of the Uri object should be used instead of AbsoluteUri
             *                  otherwise trailing slash is added.
             */
            string oauth_callback_uri_absolute = callbackUrl.AbsoluteUri;
            string oauth_callback_uri_original = callbackUrl.OriginalString;

            System.Diagnostics.Debug.WriteLine("GetInitialUrlAsync callbackUrl.AbsoluteUri    = " + oauth_callback_uri_absolute);
            System.Diagnostics.Debug.WriteLine("GetInitialUrlAsync callbackUrl.OriginalString = " + oauth_callback_uri_original);

            string oauth_callback_uri = oauth_callback_uri_absolute;

            var req = OAuth1.CreateRequest
                      (
                "GET",
                requestTokenUrl,
                new Dictionary <string, string>()
            {
                { "oauth_callback", oauth_callback_uri },
            },
                consumerKey,
                consumerSecret,
                ""
                      );

            if (this.HttpWebClientFrameworkType == HttpWebClientFrameworkType.WebRequest)
            {
                return(req.GetResponseAsync()
                       .ContinueWith
                       (
                           respTask =>
                {
                    var content = respTask.Result.GetResponseText();

                    var r = WebEx.FormDecode(content);

                    token = r["oauth_token"];
                    tokenSecret = r["oauth_token_secret"];

                    string paramType = authorizeUrl.AbsoluteUri.IndexOf("?") >= 0 ? "&" : "?";

                    var url = authorizeUrl.AbsoluteUri + paramType + "oauth_token=" + Uri.EscapeDataString(token);
                    return new Uri(url);
                }
                       ));
            }
            else if (this.HttpWebClientFrameworkType == HttpWebClientFrameworkType.HttpClient)
            {
                throw new NotImplementedException("HttpClient implementation!");
            }

            return(null);
        }
Example #14
0
        /// <summary>
        /// Event handler that watches for the callback URL to be loaded.
        /// </summary>
        /// <param name='url'>
        /// The URL of the loaded page.
        /// </param>
        public override void OnPageLoaded(Uri url)
        {
            if (url.Host == callbackUrl.Host && url.AbsolutePath == callbackUrl.AbsolutePath)
            {
                var query = url.Query;
                var r     = WebEx.FormDecode(query);

                verifier = r["oauth_verifier"];

                GetAccessTokenAsync();
            }
        }
Example #15
0
        /// <summary>
        /// Event handler called when a page has completed loading.
        /// </summary>
        /// <param name='url'>
        /// The URL of the page.
        /// </param>
        public override void OnPageLoaded(Uri url)
        {
            IDictionary <string, string> query    = WebEx.FormDecode(url.Query);
            IDictionary <string, string> fragment = WebEx.FormDecode(url.Fragment);

            this.Query    = query;
            this.Fragment = fragment;

            OnPageEncountered(url, query, fragment);

            return;
        }
        /// <summary>
        /// Asynchronously makes a request to the access token URL with the given parameters.
        /// </summary>
        /// <param name="queryValues">The parameters to make the request with.</param>
        /// <returns>The data provided in the response to the access token request.</returns>
        public async Task <IDictionary <string, string> > RequestAccessTokenAsync(IDictionary <string, string> queryValues)
        {
            // mc++ changed protected to public for extension methods RefreshToken (Adrian Stevens)
            var content = new FormUrlEncodedContent(queryValues);


            HttpClient client = new HttpClient();

            //If client secret is set, use HTTP BASIC auth to authenticate to the token endpoint
            if (!string.IsNullOrEmpty(this.ClientSecret))
            {
                client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("basic", Convert.ToBase64String(UTF8Encoding.UTF8.GetBytes($"{this.ClientId}:{this.ClientSecret}")));
            }

            HttpResponseMessage response = await client.PostAsync(accessTokenUrl, content).ConfigureAwait(false);

            string text = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

            // Parse the response
            var data = text.Contains("{") ? WebEx.JsonDecode(text) : WebEx.FormDecode(text);

            if (data.ContainsKey("error"))
            {
                throw new AuthException("Error authenticating: " + data["error"]);
            }
            #region
            //---------------------------------------------------------------------------------------
            /// Pull Request - manually added/fixed
            ///		OAuth2Authenticator changes to work with joind.in OAuth #91
            ///		https://github.com/xamarin/Xamarin.Auth/pull/91
            ///
            //else if (data.ContainsKey("access_token"))
            else if (data.ContainsKey(AccessTokenName))
            //---------------------------------------------------------------------------------------
            #endregion
            {
            }
            else
            {
                #region
                //---------------------------------------------------------------------------------------
                /// Pull Request - manually added/fixed
                ///		OAuth2Authenticator changes to work with joind.in OAuth #91
                ///		https://github.com/xamarin/Xamarin.Auth/pull/91
                ///
                //throw new AuthException ("Expected access_token in access token response, but did not receive one.");
                throw new AuthException("Expected " + AccessTokenName + " in access token response, but did not receive one.");
                //---------------------------------------------------------------------------------------
                #endregion
            }

            return(data);
        }
        /// <summary>
        /// Asynchronously makes a request to the access token URL with the given parameters.
        /// </summary>
        /// <param name="queryValues">The parameters to make the request with.</param>
        /// <returns>The data provided in the response to the access token request.</returns>
        public async Task <IDictionary <string, string> > RequestAccessTokenAsync(IDictionary <string, string> queryValues)
        {
            // mc++ changed protected to public for extension methods RefreshToken (Adrian Stevens)
            var content = new FormUrlEncodedContent(queryValues);

            HttpClient         client  = new HttpClient();
            HttpRequestMessage Message = new HttpRequestMessage(HttpMethod.Post, this.accessTokenUrl);

            Message.Content = content;
            if (this.UserAgent != null)
            {
                Message.Headers.Add(@"User-Agent", this.UserAgent);
            }
            HttpResponseMessage response = await client.SendAsync(Message).ConfigureAwait(false);

            string text = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

            // Parse the response
            var data = text.Contains("{") ? WebEx.JsonDecode(text) : WebEx.FormDecode(text);

            if (data.ContainsKey("error"))
            {
                throw new AuthException("Error authenticating: " + data["error"]);
            }
            #region
            //---------------------------------------------------------------------------------------
            /// Pull Request - manually added/fixed
            ///		OAuth2Authenticator changes to work with joind.in OAuth #91
            ///		https://github.com/xamarin/Xamarin.Auth/pull/91
            ///
            //else if (data.ContainsKey("access_token"))
            else if (data.ContainsKey(AccessTokenName))
            //---------------------------------------------------------------------------------------
            #endregion
            {
            }
            else
            {
                #region
                //---------------------------------------------------------------------------------------
                /// Pull Request - manually added/fixed
                ///		OAuth2Authenticator changes to work with joind.in OAuth #91
                ///		https://github.com/xamarin/Xamarin.Auth/pull/91
                ///
                //throw new AuthException ("Expected access_token in access token response, but did not receive one.");
                throw new AuthException("Expected " + AccessTokenName + " in access token response, but did not receive one.");
                //---------------------------------------------------------------------------------------
                #endregion
            }

            return(data);
        }
Example #18
0
        /// <summary>
        /// Asynchronously makes a request to the access token URL with the given parameters.
        /// </summary>
        /// <param name="queryValues">The parameters to make the request with.</param>
        /// <returns>The data provided in the response to the access token request.</returns>
        public async Task <IDictionary <string, string> > CustomRequestAccessTokenAsync(IDictionary <string, string> queryValues)
        {
            // mc++ changed protected to public for extension methods RefreshToken (Adrian Stevens)
            var content = new FormUrlEncodedContent(queryValues);


            HttpClient          client   = new HttpClient();
            HttpResponseMessage response = await client.PostAsync(_accessTokenUrl, content).ConfigureAwait(false);

            string text = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

            try
            {
                if (response.StatusCode != System.Net.HttpStatusCode.OK)
                {
                    LogUtils.LogMessage(LogSeverity.WARNING, "CustomOAuth2Authenticator failed to refresh token.", "Error from service: " + text);
                    System.Diagnostics.Debug.Print("Error from service: " + text);
                }
            }
            catch { }

            // Parse the response
            var data = text.Contains("{") ? WebEx.JsonDecode(text) : WebEx.FormDecode(text);

            if (data.ContainsKey("error"))
            {
                throw new AuthException("Error authenticating: " + data["error"]);
            }
            //---------------------------------------------------------------------------------------
            /// Pull Request - manually added/fixed
            ///		OAuth2Authenticator changes to work with joind.in OAuth #91
            ///		https://github.com/xamarin/Xamarin.Auth/pull/91
            ///
            else if (data.ContainsKey(AccessTokenName))
            //---------------------------------------------------------------------------------------
            {
            }
            else
            {
                //---------------------------------------------------------------------------------------
                /// Pull Request - manually added/fixed
                ///		OAuth2Authenticator changes to work with joind.in OAuth #91
                ///		https://github.com/xamarin/Xamarin.Auth/pull/91
                ///
                //throw new AuthException ("Expected access_token in access token response, but did not receive one.");
                throw new AuthException("Expected " + AccessTokenName + " in access token response, but did not receive one.");
                //---------------------------------------------------------------------------------------
            }

            return(data);
        }
        /// <summary>
        /// Event handler that watches for the callback URL to be loaded.
        /// </summary>
        /// <param name='url'>
        /// The URL of the loaded page.
        /// </param>
        public override void OnPageLoaded(Uri url)
        {
            if (
                url.Authority == callbackUrl.Authority
                //url.Host == callbackUrl.Host
                &&
                url.AbsolutePath == callbackUrl.AbsolutePath
                )
            {
                var query = url.Query;
                var r     = WebEx.FormDecode(query);

                r.TryGetValue("oauth_verifier", out verifier);

                #if DEBUG
                StringBuilder sb = new StringBuilder();
                sb.AppendLine($"OAuth1Authenticator.OnPageLoaded ");
                sb.AppendLine($"        url = {url.AbsoluteUri}");
                sb.AppendLine($"        oauth_verifier = {verifier}");
                System.Diagnostics.Debug.WriteLine(sb.ToString());
                #endif

                GetAccessTokenAsync().ContinueWith(getTokenTask =>
                {
                    if (getTokenTask.IsCanceled)
                    {
                        OnCancelled();
                    }
                    else if (getTokenTask.IsFaulted)
                    {
                        OnError(getTokenTask.Exception);
                    }
                }, TaskContinuationOptions.NotOnRanToCompletion);
            }
            else
            {
                // http[s]://www.xamarin.com != http[s]://xamarin.com
                #if DEBUG
                StringBuilder sb = new StringBuilder();
                sb.AppendLine($"OAuth1Authenticator.OnPageLoaded ");
                sb.AppendLine($"        mc++ fix");
                sb.AppendLine($"        url         = {url.AbsoluteUri}");
                sb.AppendLine($"        callbackUrl = {callbackUrl.AbsoluteUri}");
                sb.AppendLine($"        oauth_verifier = {verifier}");
                System.Diagnostics.Debug.WriteLine(sb.ToString());
                #endif
            }

            return;
        }
Example #20
0
        public static async Task <string> GetRefreshTokenAsync()
        {
            byte[] buffer = new byte[32];
            Randomizer.NextBytes(buffer);
            var codeVerifier = Convert.ToBase64String(buffer).Replace('+', '-').Replace('/', '_').Replace("=", "");

            byte[] hash          = HashProvider.ComputeHash(Encoding.UTF8.GetBytes(codeVerifier));
            var    codeChallenge = Convert.ToBase64String(hash).Replace('+', '-').Replace('/', '_').Replace("=", "");

            var redirectUri = new Uri(ProdRedirectUrl);

            string scope    = $"{OfflineAccessScope} {WNSScope} {CCSScope} {UserNotificationsScope} {UserActivitiesScope} {DdsScope}";
            var    startUri = new Uri($"{ProdAuthorizeUrl}?client_id={Secrets.MSA_CLIENT_ID}&response_type=code&code_challenge_method=S256&code_challenge={codeChallenge}&redirect_uri={ProdRedirectUrl}&scope={scope}");

            var webAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(
                WebAuthenticationOptions.None,
                startUri,
                redirectUri);

            if (webAuthenticationResult.ResponseStatus == WebAuthenticationStatus.Success)
            {
                var codeResponseUri = new Uri(webAuthenticationResult.ResponseData);
                IDictionary <string, string> queryParams = WebEx.FormDecode(codeResponseUri.Query);
                if (!queryParams.ContainsKey("code"))
                {
                    return(string.Empty);
                }

                string authCode = queryParams["code"];
                Dictionary <string, string> refreshTokenQuery = new Dictionary <string, string>
                {
                    { "client_id", Secrets.MSA_CLIENT_ID },
                    { "redirect_uri", redirectUri.AbsoluteUri },
                    { "grant_type", "authorization_code" },
                    { "code", authCode },
                    { "code_verifier", codeVerifier },
                    { "scope", WNSScope }
                };

                IDictionary <string, string> refreshTokenResponse = await RequestAccessTokenAsync(ProdAccessTokenUrl, refreshTokenQuery);

                if (refreshTokenResponse.ContainsKey("refresh_token"))
                {
                    return(refreshTokenResponse["refresh_token"]);
                }
            }

            return(string.Empty);
        }
Example #21
0
        /// <summary>
        /// Asynchronously makes a request to the access token URL with the given parameters.
        /// </summary>
        /// <param name="queryValues">The parameters to make the request with.</param>
        /// <returns>The data provided in the response to the access token request.</returns>
        public async Task <IDictionary <string, string> > RequestAccessTokenAsync(IDictionary <string, string> queryValues)
        {
            // mc++ changed protected to public for extension methods RefreshToken (Adrian Stevens)
            var content = new FormUrlEncodedContent(queryValues);


            HttpClient          client   = new HttpClient();
            HttpResponseMessage response = await client.PostAsync(accessTokenUrl, content).ConfigureAwait(false);

            string text = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

            // Parse the response
            var data = text.Contains("{") ? WebEx.JsonDecode(text) : WebEx.FormDecode(text);

            if (data.ContainsKey("error"))
            {
                System.Diagnostics.Debug.WriteLine($"RequestAccessTokenAsync exception {text}");//log actual response from server
                throw new AuthException("Error authenticating: " + data["error"]);
            }
            #region
            //---------------------------------------------------------------------------------------
            /// Pull Request - manually added/fixed
            ///		OAuth2Authenticator changes to work with joind.in OAuth #91
            ///		https://github.com/xamarin/Xamarin.Auth/pull/91
            ///
            //else if (data.ContainsKey("access_token"))
            else if (data.ContainsKey(AccessTokenName))
            //---------------------------------------------------------------------------------------
            #endregion
            {
            }
            else
            {
                #region
                //---------------------------------------------------------------------------------------
                /// Pull Request - manually added/fixed
                ///		OAuth2Authenticator changes to work with joind.in OAuth #91
                ///		https://github.com/xamarin/Xamarin.Auth/pull/91
                ///
                //throw new AuthException ("Expected access_token in access token response, but did not receive one.");
                throw new AuthException("Expected " + AccessTokenName + " in access token response, but did not receive one.");
                //---------------------------------------------------------------------------------------
                #endregion
            }

            return(data);
        }
        Task GetAccessTokenAsync()
        {
            var requestparams = new Dictionary <string, string> {
                { "oauth_token", token },
            };

            if (verifier != null)
            {
                requestparams["oauth_verifier"] = verifier;
            }

            var req = OAuth1.CreateRequest(
                "GET",
                accessTokenUrl,
                requestparams,
                consumerKey,
                consumerSecret,
                tokenSecret);

            return(req.GetResponseAsync().ContinueWith(respTask => {
                var content = respTask.Result.GetResponseText();

                var accountProperties = WebEx.FormDecode(content);
                accountProperties["oauth_consumer_key"] = consumerKey;
                accountProperties["oauth_consumer_secret"] = consumerSecret;

                if (getUsernameAsync != null)
                {
                    getUsernameAsync(accountProperties).ContinueWith(uTask => {
                        if (uTask.IsFaulted)
                        {
                            OnError(uTask.Exception);
                        }
                        else
                        {
                            OnSucceeded(uTask.Result, accountProperties);
                        }
                    });
                }
                else
                {
                    OnSucceeded("", accountProperties);
                }
            }));
        }
Example #23
0
        /// <summary>
        /// Event handler called when a new page is being loaded in the web browser.
        /// </summary>
        /// <param name='url'>
        /// The URL of the page.
        /// </param>
        public override void OnPageLoading(Uri url)
        {
            #if DEBUG
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            sb.AppendLine("WebRedirectAuthenticator OnPageLoading Called");
            sb.AppendLine("     AbsoluteUri  = ").AppendLine(url.AbsoluteUri);
            sb.AppendLine("     AbsolutePath = ").AppendLine(url.AbsolutePath);
            System.Diagnostics.Debug.WriteLine(sb.ToString());
            #endif

            var query    = WebEx.FormDecode(url.Query);
            var fragment = WebEx.FormDecode(url.Fragment);

            // mc++
            // TODO: schemas
            OnPageEncountered(url, query, fragment);

            return;
        }
Example #24
0
        public virtual async void OnSsoLoginLogoutRedirectCompleted(Uri url)
        {
            Dictionary <string, string> query = (Dictionary <string, string>)WebEx.FormDecode(url.Fragment);

            if (CurrentAction == "Logout")
            {
                CurrentLogoutTaskCompletionSource.SetResult(null);
            }
            else
            {
                Token token = query;

                Account account = Token.FromTokenToAccount(token);

                await _accountStore.SaveAsync(account, _clientAppProfile.AppName).ConfigureAwait(false);

                CurrentLoginTaskCompletionSource.SetResult(query);
            }
        }
Example #25
0
        /// <summary>
        /// Implements: http://tools.ietf.org/html/rfc6749#section-4.1
        /// </summary>
        /// <returns>
        /// The access token async.
        /// </returns>
        /// <param name='code'>
        /// Code.
        /// </param>
        Task <Dictionary <string, string> > RequestAccessTokenAsync(string code)
        {
            var queryValues = new Dictionary <string, string> {
                { "grant_type", "authorization_code" },
                { "code", code },
                { "redirect_uri", redirectUrl.AbsoluteUri },
                { "client_id", clientId },
            };

            if (!string.IsNullOrEmpty(clientSecret))
            {
                queryValues ["client_secret"] = clientSecret;
            }
            var query = queryValues.FormEncode();

            var req = WebRequest.Create(accessTokenUrl);

            req.Method = "POST";
            req.Proxy  = WebAuthenticator.Proxy;
            var body = Encoding.UTF8.GetBytes(query);

            req.ContentLength = body.Length;
            req.ContentType   = "application/x-www-form-urlencoded";
            using (var s = req.GetRequestStream()) {
                s.Write(body, 0, body.Length);
            }
            return(req.GetResponseAsync().ContinueWith(task => {
                var text = task.Result.GetResponseText();
                var data = WebEx.FormDecode(text);
                if (data.ContainsKey("error"))
                {
                    throw new AuthException("Error authenticating: " + data ["error"]);
                }
                else if (data.ContainsKey("access_token"))
                {
                    return data;
                }
                else
                {
                    throw new AuthException("Expected access_token in access token response, but did not receive one.");
                }
            }));
        }
Example #26
0
        /// <summary>
        /// Event handler that watches for the callback URL to be loaded.
        /// </summary>
        /// <param name='url'>
        /// The URL of the loaded page.
        /// </param>
        public override void OnPageLoaded(Uri url)
        {
            if (url.Host == callbackUrl.Host && url.AbsolutePath == callbackUrl.AbsolutePath)
            {
                var query = url.Query;
                var r     = WebEx.FormDecode(query);

                r.TryGetValue("oauth_verifier", out verifier);

                GetAccessTokenAsync().ContinueWith(getTokenTask => {
                    if (getTokenTask.IsCanceled)
                    {
                        OnCancelled();
                    }
                    else if (getTokenTask.IsFaulted)
                    {
                        OnError(getTokenTask.Exception);
                    }
                }, TaskContinuationOptions.NotOnRanToCompletion);
            }
        }
        protected override void OnRedirectPageLoaded(Uri url, IDictionary <string, string> query, IDictionary <string, string> fragment)
        {
            if (query.ContainsKey("code"))
            {
                var autorizationCode = query["code"];
                var tokenUrl         = GetTokenUrl();
                try
                {
                    using (var client = new HttpClient())
                    {
                        var postBody = new Dictionary <string, string>();
                        postBody.Add("grant_type", "authorization_code");
                        postBody.Add("client_id", this.ClientId);
                        postBody.Add("code_verifier", this.verifier);
                        postBody.Add("redirect_uri", this.RedirectUrl.AbsoluteUri);
                        postBody.Add("code", autorizationCode);
                        var request = new HttpRequestMessage(HttpMethod.Post, tokenUrl);
                        request.Content = new FormUrlEncodedContent(postBody);
                        request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");

                        var response = client.SendAsync(request).Result;
                        OnTokenReceived(new EventArgs());
                        response.EnsureSuccessStatusCode();
                        var res  = response.Content.ReadAsStringAsync().Result;
                        var data = res.Contains("{") ? WebEx.JsonDecode(res) : WebEx.FormDecode(res);
                        OnSucceeded(string.Empty, data);
                    }
                }
                catch
                {
                    OnError("An unexpected error occured while getting access token.");
                }
            }
            else
            {
                OnError("The expected authorization code not received");
            }

            base.OnRedirectPageLoaded(url, query, fragment);
        }
            public override void DidFailProvisionalNavigation
            (
                WKWebView webView,
                WKNavigation navigation,
                NSError error
            )
            {
                // Provisional Navigation Failed? WAT?

                if  // loading custom url scheme will result in unsupported URL
                (
                    error.Code == -1002
                    ||
                    error.LocalizedDescription == "unsupported URL"
                )
                {
                    //custom url schema
                    // NSUrl url_ios = webView.Url; // old URL
                    string     url_redirect = error.UserInfo[new NSString("NSErrorFailingURLKey")].ToString();
                    System.Uri uri          = new Uri(url_redirect);
                    IDictionary <string, string> fragment = WebEx.FormDecode(uri.Fragment);

                    Account account = new Account
                                      (
                        "",
                        new Dictionary <string, string>(fragment)
                                      );
                    controller.authenticator.OnSucceeded(account);
                }

                #if DEBUG
                StringBuilder sb = new StringBuilder();
                sb.AppendLine($"WKWebViewNavigationDelegate.DidFailProvisionalNavigation ");
                sb.AppendLine($"        error.LocalizedDescription = {error.LocalizedDescription}");
                sb.AppendLine($"        webView.Url.AbsoluteString = {webView.Url.AbsoluteString}");
                System.Diagnostics.Debug.WriteLine(sb.ToString());
                #endif

                return;
            }
Example #29
0
        public override Task <IDictionary <string, string> > GetAccessTokenAsync(Account acc, CancellationToken token)
        {
            if (string.IsNullOrEmpty(ConsumerKey) || string.IsNullOrEmpty(ConsumerSecret))
            {
                throw new InvalidOperationException("Cannot perform Twitter Reverse Auth without ConsumerKey and ConsumerSecret set.");
            }

            return(new ReverseAuthRequest(acc, ConsumerKey, ConsumerSecret)
                   .GetResponseAsync(token)
                   .ContinueWith(t => {
                var parameters = new Dictionary <string, string> {
                    { "x_reverse_auth_target", ConsumerKey },
                    { "x_reverse_auth_parameters", t.Result.GetResponseText() }
                };

                return this.CreateRequest("POST", new Uri("https://api.twitter.com/oauth/access_token"), parameters, acc)
                .GetResponseAsync(token)
                .ContinueWith(tokenTask => {
                    return WebEx.FormDecode(tokenTask.Result.GetResponseText());
                }, token);
            }, token).Unwrap());
        }
Example #30
0
        /// <summary>
        /// Method that returns the initial URL to be displayed in the web browser.
        /// </summary>
        /// <returns>
        /// A task that will return the initial URL.
        /// </returns>
        public override Task <Uri> GetInitialUrlAsync()
        {
            var req = OAuth1.CreateRequest(
                "GET",
                requestTokenUrl,
                new Dictionary <string, string>()
            {
                { "oauth_callback", callbackUrl.AbsoluteUri },
            },
                consumerKey,
                consumerSecret,
                "");

            if (this.HttpWebClientFrameworkType == HttpWebClientFrameworkType.WebRequest)
            {
                return(req.GetResponseAsync().ContinueWith(respTask =>
                {
                    var content = respTask.Result.GetResponseText();

                    var r = WebEx.FormDecode(content);

                    token = r["oauth_token"];
                    tokenSecret = r["oauth_token_secret"];

                    string paramType = authorizeUrl.AbsoluteUri.IndexOf("?") >= 0 ? "&" : "?";

                    var url = authorizeUrl.AbsoluteUri + paramType + "oauth_token=" + Uri.EscapeDataString(token);
                    return new Uri(url);
                }));
            }
            else if (this.HttpWebClientFrameworkType == HttpWebClientFrameworkType.HttpClient)
            {
                throw new NotImplementedException("HttpClient implementation!");
            }

            return(null);
        }