Search code examples
c#oauthasp.net-mvc-5google-apigoogle-oauth

Access is denied after deploying while accessing Google Drive Api


Developing MVC application with Google OAuth to access drive API. While I was accessing Google API in the development environment it works just fine. But when I deploy it in IIS or Shared hosting it shows access denied with below exception.

[Win32Exception (0x80004005): Access is denied]


 System.Diagnostics.Process.StartWithShellExecuteEx(ProcessStartInfo startInfo) +602
   System.Diagnostics.Process.Start(ProcessStartInfo startInfo) +60
   Google.Apis.Auth.OAuth2.<ReceiveCodeAsync>d__14.MoveNext() +265

[NotSupportedException: Failed to launch browser with "https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&response_type=code&client_id=1062976495544-dg9ak1e6uovp7p6gmlf1vcqvvq6mnefv.apps.googleusercontent.com&redirect_uri=http:%2F%2Flocalhost:7862%2Fauthorize%2F&scope=https:%2F%2Fwww.googleapis.com%2Fauth%2Fdrive" for authorization. See inner exception for details.]
   Google.Apis.Auth.OAuth2.<ReceiveCodeAsync>d__14.MoveNext() +1029
   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() +31
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +60
   Google.Apis.Auth.OAuth2.<AuthorizeAsync>d__8.MoveNext() +730
   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() +31
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +60
   Google.Apis.Auth.OAuth2.<AuthorizeAsync>d__4.MoveNext() +571
   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() +31
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +60
   Google.Apis.Auth.OAuth2.<AuthorizeAsync>d__1.MoveNext() +438

Things I have tried :

  1. Verify Domain in google dev console.
  2. Change protocol from HTTP to https

Solution

  • This article helped me to resolve this issue: Implementing OAuth2.0 Authorization For Google In ASP.NET.

    How it works (by article):

      1. Create Web Server client_secret.json.
      1. GetAuthorizationUrl() - create url for get toke temporary token.
      1. Redirect to GoogleCallback() and get refresh and access tokens using ExchangeAuthorizationCode().
      1. Save them to the file "~/Resources/driveApiCredentials/drive-credentials.json/Google.Apis.Auth.OAuth2.Responses.TokenResponse-{account}".
      1. Use this saved tokens.

    After that just use google authentication for drive:

         // Client for requests
        private DriveService client;
        
        // Class constructor
        public GoogleDrive(string account)
        {
            UserCredential credential;
            Login = account;
            
            // Load Web Secret file
            using (var stream =
                new FileStream(System.Web.HttpContext.Current.Server.MapPath($"~/Resources/client_secret_{account}.json"), FileMode.Open, FileAccess.Read))
            {
                // Path to token folder 
                string credPath = System.Web.HttpContext.Current.Server.MapPath(Path.Combine("~/Resources/driveApiCredentials", "drive-credentials.json"));
    
                credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                    GoogleClientSecrets.Load(stream).Secrets,
                    Scopes,
                    account,
                    CancellationToken.None,
                    new FileDataStore(credPath, true)).Result;
                //Console.WriteLine("Credential file saved to folder: " + credPath);
            }
    
            // Create Drive API service.
            var service = new DriveService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = account,
            });
    
            client =  service;
        }
    

    This code use tokens loaded before for initialize DriveService.