Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GoogleWebAuthorizationBroker.AuthorizeAsync works locally but hangs on production IIS

Tags:

c#

adsense-api

I have a report application that uses the adsense api. I am using GoogleWebAuthorizationBroker.AuthorizeAsync for authentication. When i wun it locally it works fine, the request for permission window opens and after I grant access everything works My problem is when I deploy it to the production server and it runs on IIS the GoogleWebAuthorizationBroker.AuthorizeAsync hangs forever. My guess is that it's trying to open the authorization window on the server and is unable to do that. I did not write this implementation and it has been in production for a while now and it used to work fine. I'm not sure what happened and if somthing changed, but it doesn't work now. I surfed around and tryied different aproaches bot none worked. When I tried using GoogleAuthorizationCodeFlow with the AccessType set to "offline" and with the provided URI it still didn't work. I also tried using a Service Account but I later learned that they are not suported for adsense. Below is the codesample

    var credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                new ClientSecrets
                {
                    ClientId = ConfigurationManager.AppSettings["AdSenseClientId"],
                    ClientSecret = ConfigurationManager.AppSettings["AdSenseClientSecret"]
                },
                new string[] { AdSenseService.Scope.Adsense },
                "[email protected]",
                CancellationToken.None).Result;
            // Create the service.
            adSenseService = new AdSenseService(new BaseClientService.Initializer
            {
                HttpClientInitializer = credential,
                ApplicationName = "My API Project"
            });
    var adClientRequest = adSenseService.Adclients.List();
        var adClientResponse = adClientRequest.Execute();

I would be very greatfull for a sample code that solves this. I saw this post (ASP.NET MVC5 Google APIs GoogleWebAuthorizationBroker.AuthorizeAsync works locally but not deployed to IIS), but it doesn't have a code sample and it didn't help me.

Thank you in advance.

like image 790
Mihaii Bica Avatar asked Nov 09 '22 19:11

Mihaii Bica


1 Answers

We spent a few days trying to figure out why this method hangs in IIS and works fine in Visual Studio Dev Server. In the end we used another method which appears to do the job, hope this saves you some time.

The following code returns all uploaded videos:

using Google.Apis.Auth.OAuth2.Flows;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Util.Store;
using Google.Apis.YouTube.v3;
using Google.Apis.Auth.OAuth2.Web;
using Google.Apis.Services;
using Google.Apis.YouTube.v3.Data;
using System.Threading;

private void GetData()
{
    IAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow(
        new GoogleAuthorizationCodeFlow.Initializer
        {
            ClientSecrets = new ClientSecrets { ClientId = "[ClientID]", ClientSecret = "[ClientSecret]" },
            DataStore = new FileDataStore("C:\\Temp", true),
            Scopes = new[] { YouTubeService.Scope.YoutubeReadonly }
        });
    var userId = "[ACCOUNTNAME]";
    var uri = Request.Url.ToString();
    var code = Request["code"];
    if (code != null)
    {
        var token = flow.ExchangeCodeForTokenAsync(userId, code, uri.Substring(0, uri.IndexOf("?")), CancellationToken.None).Result;

        // Extract the right state.
        var oauthState = AuthWebUtility.ExtracRedirectFromState(flow.DataStore, userId, Request["state"]).Result;
        Response.Redirect(oauthState);
    }
    else
    {
        var result = new AuthorizationCodeWebApp(flow, uri, uri).AuthorizeAsync(userId, CancellationToken.None).Result;

        if (result.RedirectUri != null)
        {
            // Redirect the user to the authorization server.
            Response.Redirect(result.RedirectUri);
        }
        else
        {
            // The data store contains the user credential, so the user has been already authenticated.
            var youtubeService = new YouTubeService(new BaseClientService.Initializer
            {
                ApplicationName = "MyVideoApp",
                HttpClientInitializer = result.Credential
            });

            if (youtubeService != null)
            {
                var channelsListRequest = youtubeService.Channels.List("contentDetails");
                channelsListRequest.Mine = true;
                ChannelListResponse channelsListResponse = channelsListRequest.ExecuteAsync().Result;
                foreach (var channel in channelsListResponse.Items)
                {
                    var playlistItemsListRequest = youtubeService.PlaylistItems.List("snippet, status");
                    playlistItemsListRequest.PlaylistId = channel.ContentDetails.RelatedPlaylists.Uploads;
                    var playlistItemsListResponse = playlistItemsListRequest.ExecuteAsync().Result;
                }
            }
        }
    }
}

The code will prompt you to sign in to Google but after signing in you should receive a redirect error initially. You will need to configure redirect URLs for your project at http://Console.developers.google.com.

The Url redirect setting is under APIs & Auth > Credentials. You need to click the "Edit settings" button and specify the following Authorized redirect URIs adapted for your domain name and port number:

http://localhost:1234/Default.aspx http://localhost:1234/Options.aspx

like image 64
StackExchanger Avatar answered Nov 15 '22 07:11

StackExchanger