title: 401 Error using Google Drive API within Google Domain from ASP.NET
body: <p>I am currently trying to add functionality to our company's <code>ASP.NET</code> website which will allow end users to upload files generated from the website into their own <code>Google Drive</code> (within the same company).</p>
  
  <p>The company has it's own Google Domain which includes Mail, Drive, Contacts, Calendar (and pretty much everything else).  It uses SAML to authenticate with our Active Directory set up which links in to Google.  </p>
  
  <p>It should be noted that this code works OK with my <code>@gmail.com</code> account.  With the companies Google App Domain account, I get the invalid credentials error (shown at the bottom).  I have spoken with our Google Admin who claims that I have no restrictions on my account with regards to Drive API access.  Please also bear in mind that the API ID/Secret's were created with my company account rather than a Gmail account.</p>
  
  <pre><code>using System;
  using System.IO;
  using System.Text;
  using System.Web;
  using DotNetOpenAuth.Messaging;
  using DotNetOpenAuth.OAuth2;
  using Google.Apis.Authentication.OAuth2;
  using Google.Apis.Drive.v2;
  using Google.Apis.Util;
  
  namespace GoogleTesting
  {
      public partial class GoogleAuth : System.Web.UI.Page
      {
          private static readonly string CLIENTID = "xxxxxxxxx.apps.googleusercontent.com";
          private static readonly string CLIENTSECRET = "xxxxxxxxxxxxxxxxxxxxxx";
          private static readonly string APIKEY = "xxxxxxxxxxx";
          private static readonly string REDIRECTURI =  http://localhost:61111/default.aspx";
          private static readonly string[] SCOPES = new[] { DriveService.Scopes.Drive.GetStringValue() };
  
          private static DriveService driveService;
          private static OAuth2Authenticator&lt;WebServerClient&gt; authenticator;
          private static IAuthorizationState _state;
  
          private IAuthorizationState AuthState
          {
              get
              {
                  return _state ?? HttpContext.Current.Session["GoogleAuthState"] as IAuthorizationState;
              }
          }
  
          private OAuth2Authenticator&lt;WebServerClient&gt; CreateAuthenticator()
          {
              var provider = new WebServerClient(GoogleAuthenticationServer.Description, CLIENTID, CLIENTSECRET);
              var authenticator = new OAuth2Authenticator&lt;WebServerClient&gt;(provider, GetAuthorization);
              return authenticator;
          }
  
          private IAuthorizationState GetAuthorization(WebServerClient client)
          {
              IAuthorizationState state = AuthState;
              if (state != null)
              {
                  if (state.AccessTokenExpirationUtc.Value.CompareTo(DateTime.Now.ToUniversalTime()) &gt; 0)
                      return state;
                  else
                      state = null;
              }
              state = client.ProcessUserAuthorization(new HttpRequestInfo(HttpContext.Current.Request));
              if (state != null &amp;&amp; (!string.IsNullOrEmpty(state.AccessToken) || !string.IsNullOrEmpty(state.RefreshToken)))
              {
                  if (state.RefreshToken == null)
                      state.RefreshToken = "";
                  HttpContext.Current.Session["GoogleAuthState"] = _state = state;
                  return state;
              }
              client.RequestUserAuthorization(SCOPES, "", HttpContext.Current.Request.Url);
              return null;
          }
  
  
          protected void Page_Load(object sender, EventArgs e)
          {
              if(authenticator == null)
                  authenticator = CreateAuthenticator();
  
              if (driveService == null)
              {
                  driveService = new DriveService(authenticator);
                  driveService.Key = APIKEY;
              }
              //We should now be authenticated and ready to use Drive API.
              UploadFile();
          }
  
          private void UploadFile()
          {
              Google.Apis.Drive.v2.Data.File newFile = new Google.Apis.Drive.v2.Data.File { Title = "Test File", MimeType = "text/plain" };
              byte[] byteArray = Encoding.ASCII.GetBytes("Body of the document.");
              MemoryStream stream = new MemoryStream(byteArray);
              FilesResource.InsertMediaUpload request = driveService.Files.Insert(newFile, stream, newFile.MimeType);
              request.Convert = true;
              request.Upload(); 
          }
      }
  }
  </code></pre>
  
  <p>The problem occurs on the "request.Upload" line with the following exception.</p>
  
  <blockquote>
    <p>Exception Details: System.Exception: Invalid Credentials</p>
    
    <p>Source Error:  Line 85:             request.Upload();</p>
    
    <p>Source File: C:\TMGGoogle\TMGGoogle\TMGGoogle\GoogleAuth.aspx.cs<br>
    Line: 85 </p>
    
    <p>Stack Trace: </p>
    
    <p>[Exception: Invalid Credentials]<br>
    Google.Apis.Upload.ResumableUpload`1.Upload() +722<br>
    GoogleTesting.GoogleAuth.UploadFile()</p>
  </blockquote>
  
  <p>Any help is much appreciated.  Thanks.</p>