Google OAuth2 Authorization On Linux Headless Server (.NET)

Viewed 562

I'm curious how authentication on a Linux headless server works without an internet browser in C# for their Sheetsv4 API. All the code snippets they have on their getting started page have reference to GoogleWebAuthorizationBroker, which doesn't work without a web-browser. I've seen references to GoogleAuthorizationCodeFlow, but I'm not sure if this is what I'm looking for - nor how you would be intended to use it. My current code is bellow-

UserCredential Credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
    GoogleClientSecrets.Load(Stream).Secrets,
    new string[1] { SheetsService.Scope.SpreadsheetsReadonly },
    "user",
    CancellationToken.None,
    new FileDataStore(GreetFurConfiguration.TokenFile, true)
).Result;

What I would want is for a link to be generated and, from there, to be able to paste the token into the console, as this is how other Google APIs handle this authentication (Go, NodeJS) which I have used before and seem to work well.

If there is any better way to handle this authentication though that is more suitable for a .NET workflow, that would be suitable as well. I can't manage to find any examples of how you'd get a OAuth2 token for the life of me though without having access to a web browser on the host machine.

EDIT: I'd be looking for https://github.com/googleapis/google-api-dotnet-client/blob/master/Src/Support/Google.Apis.Auth/OAuth2/PromptCodeReceiver.cs

However, I can't find any documentation on how to use this class.

1 Answers

The GoogleWebAuthorizationBroker.AuthorizeAsync allows you to send which code receiver you want The one you are looking for is PromptCodeReceiver.

    private const string PathToCredentialFile = "/home/linda/development/creds/client.json";
    
            static async Task Main(string[] args)
            {
                var scope = new[] {AnalyticsReportingService.Scope.AnalyticsReadonly};
                var credPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
                
                await using (var stream = new FileStream(PathToCredentialFile, FileMode.Open, FileAccess.Read))
                {
                    // Requesting Authentication or loading previously stored authentication for userName
                    var credential = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets,
                        scope,
                        "userName",
                        CancellationToken.None,
                        new FileDataStore(credPath, true),
                        new PromptCodeReceiver()).Result;
    
                    Console.WriteLine($"AccessToken: {credential.Token.AccessToken}");
                }

Output:

Please visit the following URL in a web browser, then enter the code shown after authorization:
https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&response_type=code&client_id=1XXXXX.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fanalytics.readonly

Please enter code: 
4/1AY0e-g6L3ASB0lEhWNkh4lDc4nl5k0xV177o38taWFzEzKBv3H24ZC4zQAM
Access toekn: ya29.a0AfH6SMB8ZhpZJgKkpMfbiflxeOF_o6Gzs6fxIuPI25Vewbp7NgVAfJp8EX6K5zgielRrYaSFjqwKIY8MoCuCDbPeF5-2w6_WRnauWqtpleqk2zjqmkHgpfNwbpO8n7VmHVSF9Mgn3YOZRl
Related