0

I am trying to create an application that utilizes google authentication using WebAuthenticationBroker. I have written the following code to get code from google,

public void SignInUserAsync()
{
    var code = await AuthenticateUsingWebAuthenticationBroker();
    if (string.IsNullOrEmpty(code))
        return;
    var account = await ConvertCodeToAccount(code);
}

private async Task<string> AuthenticateUsingWebAuthenticationBroker()
{
    var googleUrl = Common.Constants.AuthorizeUrl + "?client_id=" + Common.Constants.GoogleClientId;
    googleUrl += "&redirect_uri=" + Common.Constants.GoogleCallbackUrl;
    googleUrl += "&response_type=code";
    googleUrl += "&scope=" + Common.Constants.Scope;

    var startUri = new Uri(googleUrl);

    string result = string.Empty;

    try
    {
        var webAuthenticationResult = await
                WebAuthenticationBroker.AuthenticateAsync(WebAuthenticationOptions.None, startUri,
                  new Uri(Common.Constants.GoogleCallbackUrl));

            switch (webAuthenticationResult.ResponseStatus)
            {
                case WebAuthenticationStatus.Success:
                    // Successful authentication
                    result = webAuthenticationResult.ResponseData.Substring(webAuthenticationResult.ResponseData.IndexOf('=') + 1);
                    break;
                case WebAuthenticationStatus.UserCancel:
                    break;
                case WebAuthenticationStatus.ErrorHttp:
                    // HTTP Error
                    result = webAuthenticationResult.ResponseErrorDetail.ToString();
                    result = string.Empty;
                    break;
                default:
                    break;
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex);
        }

        return result;
    }

After getting the code I use the following method to get user info from google.

private async Task<Account> ConvertCodeToAccount(string code)
    {
        var httpClient = new HttpClient();

        IHttpContent content = new HttpFormUrlEncodedContent(new Dictionary<string, string>
        {
            {"code", code },
            {"client_id", Common.Constants.GoogleClientId },
            {"client_secret", Common.Constants.GoogleClientSecret },
            {"redirect_uri", Common.Constants.GoogleCallbackUrl },
            {"grant_type", "authorization_code" }
        });

        var accessTokenResponse = await httpClient.PostAsync(new Uri(Common.Constants.AccessTokenUrl), content);
        var responseDict =
          JsonConvert.DeserializeObject<Dictionary<string, string>>(accessTokenResponse.Content.ToString());

        return new Account(null, responseDict);
    }


public static class Constants
{
    public static string Scope = "https://www.googleapis.com/auth/userinfo.email";
    public static string AuthorizeUrl = "https://accounts.google.com/o/oauth2/auth";
    public static string AccessTokenUrl = "https://www.googleapis.com/oauth2/v4/token";
    public static string UserInfoUrl = "https://www.googleapis.com/oauth2/v2/userinfo";

    public const string GoogleCallbackUrl = "<My-Callback-Url>";
    public const string GoogleClientId = "<My-Client-Id>";
    public const string GoogleClientSecret = "<My-Client-Secret>";
    public const string UwpAccessTokenUrl = "https://accounts.google.com/o/oauth2/token";
    public const string UwpScope = "email";
}

But when I try to get the data for user on Windows 10 desktop application it gives me following error Windows 10

On Windows Phone 10 it works fine and returns me a proper data. Please tell me how to fix it. Thanks.

Pedro Lamas
  • 7,185
  • 4
  • 27
  • 35
  • did you check this https://stackoverflow.com/questions/43948054/use-google-credentials-to-login-into-uwp-c-sharp-app – Emil Jun 09 '18 at 12:03

1 Answers1

0

First thing I notice is that you are missing the request content type for the token exchange.

See if this works:

IHttpContent content = new HttpFormUrlEncodedContent(new Dictionary<string, string>
{
    {"code", code },
    {"client_id", Common.Constants.GoogleClientId },
    {"client_secret", Common.Constants.GoogleClientSecret },
    {"redirect_uri", Common.Constants.GoogleCallbackUrl },
    {"grant_type", "authorization_code" }
});

// add this!
content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");

var accessTokenResponse = await httpClient.PostAsync(new Uri(Common.Constants.AccessTokenUrl), content);
Pedro Lamas
  • 7,185
  • 4
  • 27
  • 35