title: Google oAuth 2.0 (JWT token request) for Service Application
body: <p>I'm trying to implement Google oAuth 2 for service accounts described here: <a href="https://developers.google.com/accounts/docs/OAuth2ServiceAccount" rel="noreferrer">https://developers.google.com/accounts/docs/OAuth2ServiceAccount</a> on UnityScript (or C# - that doesn't matter because they both use the same Mono .NET classes).</p>
  
  <p>I've found similar topic here: <a href="https://stackoverflow.com/questions/10055158/is-there-a-json-">Is there a JSON Web Token (JWT) example in C#?</a>
  web-token-jwt-example-in-c but I still don't have a success.</p>
  
  <p>Fist of all, I have generated header and claimset (that are just like in google documentation)</p>
  
  
  
  <pre class="lang-js prettyprint-override"><code>var header: String = GetJWTHeader();
  var claimset: String = GetJWTClaimSet();
  </code></pre>
  
  <p>The result is (separated with new lines for clarity):</p>
  
  <blockquote>
    <p>{"alg":"RS256","typ":"JWT"}</p>
    
    <p>{"iss":"425466719070-1dg2rebp0a8fn9l02k9ntr6u5o4a8lp2.apps.googleusercontent.com",</p>
    
    <p>"scope":"<a href="https://www.googleapis.com/auth/prediction" rel="noreferrer">https://www.googleapis.com/auth/prediction</a>",</p>
    
    <p>"aud":"<a href="https://accounts.google.com/o/oauth2/token" rel="noreferrer">https://accounts.google.com/o/oauth2/token</a>",</p>
    
    <p>"exp":1340222315,</p>
    
    <p>"iat":1340218715}</p>
  </blockquote>
  
  <p>Base-64 encoding methods:</p>
  
  <pre class="lang-js prettyprint-override"><code>public static function Base64Encode(b: byte[]): String {
      var s: String = Convert.ToBase64String(b);
      s = s.Replace("+", "-");
      s = s.Replace("/", "_");
      s = s.Split("="[0])[0]; // Remove any trailing '='s
      return s;
  }
  
  public static function Base64Encode(s: String): String {    
      return Base64Encode(Encoding.UTF8.GetBytes(s));
  }
  </code></pre>
  
  <p>Then I'm making a signature.</p>
  
  <pre class="lang-js prettyprint-override"><code>var to_sign: byte[] = 
       Encoding.UTF8.GetBytes(Base64Encode(header) + "." + Base64Encode(claimset));
  var cert: X509Certificate2 = 
       new X509Certificate2(google_pvt_key.ToArray(), "notasecret");
  var rsa: RSACryptoServiceProvider = cert.PrivateKey;
  var sgn: String = Base64Encode(rsa.SignData(to_sign, "SHA256"));
  
  var jwt: String = Base64Encode(header) + "." + Base64Encode(claimset) + 
                       "." + sgn;
  </code></pre>
  
  <p>And then forming the request:</p>
  
  <pre class="lang-js prettyprint-override"><code>var url: String = "https://accounts.google.com/o/oauth2/token";
  var form: WWWForm = new WWWForm();
  form.AddField("grant_type", "assertion");
  form.AddField("assertion_type", "http://oauth.net/grant_type/jwt/1.0/bearer");
  form.AddField("assertion", jwt);
  var headers: Hashtable = form.headers;
  headers["Content-Type"] = "application/x-www-form-urlencoded";
  
  var www: WWW = new WWW(url, form.data, headers);
  </code></pre>
  
  <p>And all I get is "<strong>Error 400: Bad request</strong>".</p>
  
  <p>The encoded data looks like (line breaks added for clarity):</p>
  
  <blockquote>
    <p>eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.</p>
    
    <p>eyJpc3MiOiI0MjU0NjY3MTkwNzAtMWRnMnJlYnAwYThmbjlsMDJrOW50cjZ1NW80YThscDIuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTM0MDIyMjMxNSwiaWF0IjoxMzQwMjE4NzE1fQ.</p>
    
    <p>lIFg7-Og_BcC5qpICLt7USwGIHUOz-vV4ADNq0AWhuRtsvFrbZn5mxk4n9r5qU66q4reTVVAtuW06DeGsdcBMNgEdIMvN6VuYQybs64p9mqrfECBYxO1FWHbUG-2On1IpowybEsRRUjZfp0jFuEY7SLE3XRaXan0k5zmejcvLQo</p>
  </blockquote>
  
  <p>I've spent two days trying to figure out what is wrong but I can't see.</p>
  
  <p>Also, I couldn't find any suitable documentation and examples.</p>
  
  <p>I'm trying just to recieve a token.</p>
  
  <ol>
  <li>Am I signing the bytes the right way?</li>
  <li>What should "scope" parameter in claimset look like? I've tried "<a href="https://www.googleapis.com/auth/devstorage.readonly" rel="noreferrer">https://www.googleapis.com/auth/devstorage.readonly</a>" and "<a href="https://www.googleapis.com/auth/prediction" rel="noreferrer">https://www.googleapis.com/auth/prediction</a>".</li>
  <li>What "iss" parameter should be equal to? Client-id or e-mail address? (tried both)</li>
  <li>What are the ways to find out my mistake?</li>
  <li>Are there any C# libraries for Service Application (not for installed apps or client login)?</li>
  </ol>
  
  <p>I'm getting crazy... It has to work, but it doesn't... :-/</p>