GoogleWebAuthorizationBroker in MVC to access Google Drive

I am stuck trying to access a specific google drive account from an MVC application. All I need is an MVC web application to access my Google crawl for multiple files and modify the database based on the contents of the Google drive. The problem is that when starting up in IIS, the drive cannot be authenticated, since GoogleWebAuthorizationBroker tries to open the browser if its application is for Windows, but it seems it cannot do it through IIS, and even if it were, it would server side.

Ideally, I would not need to fully authenticate this application, but if that happens, then how do I get it to work in IIS?

UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync( new ClientSecrets { ClientId = "MY_ID", ClientSecret = "My_Secret" }, new[] { DriveService.Scope.Drive }, "user", CancellationToken.None, dataStore: new FileDataStore(Server.MapPath("~/app_data/googledata"))).Result; 
+6
source share
3 answers

I got this to work, I was able to enable the website to access Google Drive using my account, without asking users to log in or log in.

First of all, follow this link to get the Google API to work with MVC:

https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth#web_applications

The sample code has a problem in the HomeController

  public async Task IndexAsync(CancellationToken cancellationToken) 

Must be:

  public async Task<ActionResult> IndexAsync(CancellationToken cancellationToken) 

After that, I created a MemoryDataStore (see the code at the end), which is slightly modified from the MemoryDataStore posted here:

http://conficient.wordpress.com/2014/06/18/using-google-drive-api-with-c-part-2/

Once you do this, write down the update token of your account and replace the repository with this repository during authentication:

  private static readonly IAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer { ClientSecrets = new ClientSecrets { ClientId = clientID, ClientSecret = clientSecret }, Scopes = new[] { DriveService.Scope.Drive }, //DataStore = new FileDataStore("Drive.Api.Auth.Store") DataStore = new GDriveMemoryDataStore(commonUser, refreshToken) }); 

Here commonUser is the predefined user id of your chosen one. Remember to change the GetUserID () method to return the same common user:

  public override string GetUserId(Controller controller) { return commonUser; } 

Once this is done, the Google drive will stop asking the user to log in and authorize the application.

Here is my MemoryDataStore code:

  /// <summary> /// Handles internal token storage, bypassing filesystem /// </summary> internal class GDriveMemoryDataStore : IDataStore { private Dictionary<string, TokenResponse> _store; private Dictionary<string, string> _stringStore; //private key password: notasecret public GDriveMemoryDataStore() { _store = new Dictionary<string, TokenResponse>(); _stringStore = new Dictionary<string, string>(); } public GDriveMemoryDataStore(string key, string refreshToken) { if (string.IsNullOrEmpty(key)) throw new ArgumentNullException("key"); if (string.IsNullOrEmpty(refreshToken)) throw new ArgumentNullException("refreshToken"); _store = new Dictionary<string, TokenResponse>(); // add new entry StoreAsync<TokenResponse>(key, new TokenResponse() { RefreshToken = refreshToken, TokenType = "Bearer" }).Wait(); } /// <summary> /// Remove all items /// </summary> /// <returns></returns> public async Task ClearAsync() { await Task.Run(() => { _store.Clear(); _stringStore.Clear(); }); } /// <summary> /// Remove single entry /// </summary> /// <typeparam name="T"></typeparam> /// <param name="key"></param> /// <returns></returns> public async Task DeleteAsync<T>(string key) { await Task.Run(() => { // check type AssertCorrectType<T>(); if (typeof(T) == typeof(string)) { if (_stringStore.ContainsKey(key)) _stringStore.Remove(key); } else if (_store.ContainsKey(key)) { _store.Remove(key); } }); } /// <summary> /// Obtain object /// </summary> /// <typeparam name="T"></typeparam> /// <param name="key"></param> /// <returns></returns> public async Task<T> GetAsync<T>(string key) { // check type AssertCorrectType<T>(); if (typeof(T) == typeof(string)) { if (_stringStore.ContainsKey(key)) return await Task.Run(() => { return (T)(object)_stringStore[key]; }); } else if (_store.ContainsKey(key)) { return await Task.Run(() => { return (T)(object)_store[key]; }); } // key not found return default(T); } /// <summary> /// Add/update value for key/value /// </summary> /// <typeparam name="T"></typeparam> /// <param name="key"></param> /// <param name="value"></param> /// <returns></returns> public Task StoreAsync<T>(string key, T value) { return Task.Run(() => { if (typeof(T) == typeof(string)) { if (_stringStore.ContainsKey(key)) _stringStore[key] = (string)(object)value; else _stringStore.Add(key, (string)(object)value); } else { if (_store.ContainsKey(key)) _store[key] = (TokenResponse)(object)value; else _store.Add(key, (TokenResponse)(object)value); } }); } /// <summary> /// Validate we can store this type /// </summary> /// <typeparam name="T"></typeparam> private void AssertCorrectType<T>() { if (typeof(T) != typeof(TokenResponse) && typeof(T) != typeof(string)) throw new NotImplementedException(typeof(T).ToString()); } } 
+7
source

I am not familiar with C #, but OAuth's general answer is that you need to request an update token (only once, and you can do this on the OAuth playground), and then save / paste this token somewhere on your server , you can use it to request an access token when your server application needs to access Drive.

See How do I resolve an application (website or installed) without user intervention? (canonical?) for details on how to do this. Of course, you will also need to redesign how the C # library stores its markers, or creates / modifies an equivalent that uses the manually updated update token.

+2
source

I suspect you are looking for a service account . The service account allows you to configure the application to access your Google drive without the need for authentication.

The Google API also supports service accounts. Unlike the scenario in which the client application requests access to end-user data, service accounts provide access to the clientโ€™s own data.

The Google documentation on how to implement a service account can be found in the Google documentation. Google API Client Library for .NET: Service Account

0
source

All Articles