Google oAuth 2.0 (запрос токена JWT) для приложения-службы

Я пытаюсь внедрить Google oAuth 2 для сервисных аккаунтов, описанных здесь: https://developers.google.com/accounts/docs/OAuth2ServiceAccountна UnityScript (или C# — это не имеет значения, потому что они оба используют одни и те же классы Mono .NET)

Я нашел похожую тему здесь: Есть ли пример JSON Web Token (JWT) в С#? web-token-jwt-example-in-c, но у меня все еще нет успеха.

Во-первых, я сгенерировал заголовок и набор утверждений (точно такие же, как в документации Google)

var header: String = GetJWTHeader();
var claimset: String = GetJWTClaimSet();

Результат (для ясности разделен новыми строками):

{"alg":"RS256"," type":"JWT"}

{"iss":"425466719070-1dg2rebp0a8fn9l02k9ntr6u5o4a8lp2.apps.googleusercontent.com",

"scope":" https://www.googleapis.com/auth/ предсказание ",

"aud":" https://accounts.google.com/o/oauth2/token",

"exp":1340222315,

" iat":1340218715}

Методы кодирования Base-64:

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));
}

Затем я делаю подпись.

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;

И затем формирование запроса:

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);

И все, что я получаю, это "Ошибка 400: Неверный запрос".

Закодированные данные выглядят так (для ясности добавлены разрывы строк):

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.

eyJpc3MiOiI0MjU0NjY3MTkwNzAtMWRnMnJlYnAwYThmbjlsMDJrOW50cjZ1NW80YThscDIuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTM0MDIyMjMxNSwiaWF0IjoxMzQwMjE4NzE1fQ.

lIFg7-Og_BcC5qpICLt7USwGIHUOz-vV4ADNq0AWhuRtsvFrbZn5mxk4n9r5qU66q4reTVVAtuW06DeGsdcBMNgEdIMvN6VuYQybs64p9mqrfECBYxO1FWHbUG-2On1IpowybEsRRUjZfp0jFuEY7SLE3XRaXan0k5zmejcvLQo

Я провел два дня, пытаясь выяснить, что это неправильно, но я не могу видеть.

Также я не смог найти подходящей документации и примеров.

Я просто пытаюсь получить токен.

  1. Правильно ли я подписываю байты?
  2. Как должен выглядеть параметр «область действия» в наборе утверждений? Я пробовал «https://www.googleapis.com/auth/devstorage.readonly» и «https://www.googleapis.com/auth/prediction».
  3. Чему должен быть равен параметр "iss"? Идентификатор клиента или адрес электронной почты? (пробовал оба)
  4. Какие есть способы узнать мою ошибку?
  5. Существуют ли какие-либо библиотеки C# для приложения-службы (не для установленных приложений или входа клиента)?

Я схожу с ума... Это должно работать, но не работает... :-/

15
задан Community 23 May 2017 в 10:27
поделиться