title: Access denied when trying to authenticate through oauth
body: <p>I can get access by getting auth token from browser and using "Fetch..." later.
  But I want to do it without user intervention.
  I decided to use Service account.
  But when i'm trying to get access,
  I always receive "access denied".
  I'm using </p>
  
  <pre><code>var oAuth2Provider =
                  (user.OAuthProvider as AdsOAuthProviderForServiceAccounts);
          oAuth2Provider.GenerateAccessTokenForServiceAccount();
  </code></pre>
  
  <p>The properties of oAuth2Provider are:</p>
  
  <blockquote>
    <p>JwtCertificatePassword    "notasecret"<br>
          JwtCertificatePath  "D://xxxxx-privatekey.p12"<br>
          PrnEmail    "jrusearchbroadtwomycc@gmail.com" //it's my mcc account with
    approved dev token<br>
          ServiceAccountEmail "22222222222-ckvf630rcccn3j7jjuf4fmujnbiotett@developer.gserviceaccount.com"</p>
  </blockquote>
  
  <p>Here are stack trace of error.</p>
  
  <pre><code>    at Google.Api.Ads.Common.Lib.OAuth2ProviderForServiceAccounts.GenerateAccessTokenForServiceAccount()
     at AdwordsStat.GetReports.DoAuth2Authorization(AdsUser user) in D:\Adwords_API\Jooble_Adwords\GetReports.cs:line 48
     at AdwordsStat.Form1.Form1_Shown(Object sender, EventArgs e) in D:\Adwords_API\Jooble_Adwords\Form1.cs:line 87
     at System.Windows.Forms.Form.OnShown(EventArgs e)
     at System.Windows.Forms.Form.CallShownEvent()
     at System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme)
     at System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)
     at System.Threading.ExecutionContext.runTryCode(Object userData)
     at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
     at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
     at System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme)
     at System.Windows.Forms.Control.InvokeMarshaledCallbacks()
     at System.Windows.Forms.Control.WndProc(Message&amp; m)
     at System.Windows.Forms.ScrollableControl.WndProc(Message&amp; m)
     at System.Windows.Forms.Form.WndProc(Message&amp; m)
     at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&amp; m)
     at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&amp; m)
     at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
     at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG&amp; msg)
     at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
     at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
     at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
     at System.Windows.Forms.Application.Run(Form mainForm)
     at AdwordsStat.Program.Main() in D:\Adwords_API\Jooble_Adwords\Program.cs:line 16
     at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
     at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
     at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
     at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
     at System.Threading.ThreadHelper.ThreadStart()
  </code></pre>
  
  <p>Then I've read about neediness of google apps account.
  I've registered,added to it's account cliend id from my service account that looks like</p>
  
  <blockquote>
    <p>2222222222222-ckvf630rcccn3j7jjuf4fmujnbiotett.apps.googleusercontent.com
    scope : <a href="https://adwords.google.com/api/adwords/" rel="nofollow">https://adwords.google.com/api/adwords/</a></p>
  </blockquote>
  
  <p>But I get access denied again.</p>
  
  <p>Then i've tried to use another lib which looks like 
  `</p>
  
  <pre><code>public static Dictionary&lt;string, string&gt; GetAccessToken(string clientIdEMail, string keyFilePath, string scope)
          {
              // certificate
              var certificate = new X509Certificate2(keyFilePath, "notasecret");
  
          // header
          var header = new { typ = "JWT", alg = "RS256" };
  
          // claimset
          var times = GetExpiryAndIssueDate();
          var claimset = new
          {
              iss = clientIdEMail,
              scope = scope,
              aud = "https://accounts.google.com/o/oauth2/token",
              iat = times[0],
              exp = times[1],
          };
  
          JavaScriptSerializer ser = new JavaScriptSerializer();
  
          // encoded header
          var headerSerialized = ser.Serialize(header);
          var headerBytes = Encoding.UTF8.GetBytes(headerSerialized);
          var headerEncoded = Convert.ToBase64String(headerBytes);
  
          // encoded claimset
          var claimsetSerialized = ser.Serialize(claimset);
          var claimsetBytes = Encoding.UTF8.GetBytes(claimsetSerialized);
          var claimsetEncoded = Convert.ToBase64String(claimsetBytes);
  
          // input
          var input = headerEncoded + "." + claimsetEncoded;
          var inputBytes = Encoding.UTF8.GetBytes(input);
  
          // signiture
          var rsa = certificate.PrivateKey as RSACryptoServiceProvider;
          var cspParam = new CspParameters
          {
              KeyContainerName = rsa.CspKeyContainerInfo.KeyContainerName,
              KeyNumber = rsa.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange ? 1 : 2
          };
          var aescsp = new RSACryptoServiceProvider(cspParam) { PersistKeyInCsp = false };
          var signatureBytes = aescsp.SignData(inputBytes, "SHA256");
          var signatureEncoded = Convert.ToBase64String(signatureBytes);
  
          // jwt
          var jwt = headerEncoded + "." + claimsetEncoded + "." + signatureEncoded;
  
          var client = new WebClient();
          client.Encoding = Encoding.UTF8;
          var uri = "https://accounts.google.com/o/oauth2/token";
          var content = new NameValueCollection();
  
          content["assertion"] = jwt;
          content["grant_type"] = "urn:ietf:params:oauth:grant-type:jwt-bearer";
  
          string response = Encoding.UTF8.GetString(client.UploadValues(uri, "POST", content));
  
          var result = ser.Deserialize&lt;Dictionary&lt;string, string&gt;&gt;(response);
  
          return result;
      }
  
      private static int[] GetExpiryAndIssueDate()
      {
          var utc0 = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
          var issueTime = DateTime.UtcNow;
  
          var iat = (int)issueTime.Subtract(utc0).TotalSeconds;
          var exp = (int)issueTime.AddMinutes(55).Subtract(utc0).TotalSeconds;
  
          return new[] { iat, exp };
      }`
  </code></pre>
  
  <p>And after that-i've receiving access token and expiry time.  </p>
  
  <pre><code>var result = GetAccessToken(SERVICE_ACCOUNT_EMAIL, SERVICE_ACCOUNT_PKCS12_FILE_PATH, SCOPE_ANALYTICS_READONLY);
              string access_token;
              result.TryGetValue("access_token", out access_token);
  </code></pre>
  
  <p>then I'm trying to  </p>
  
  <pre><code>oAuth2Provider.AccessToken = access_token;
  </code></pre>
  
  <p>But again receiving access denied  </p>
  
  <p>I've been trying to solve this problem for a week.</p>