Google oAuth 2.0 (запрос токена JWT) для приложения-службы
Я пытаюсь реализовать Google oAuth 2 для учетных записей служб, описанных здесь: https://developers.google.com/accounts/docs/OAuth2ServiceAccount на UnityScript (или С# - это doesn ' что они оба используют одни и те же классы Mono.NET).
Я нашел аналогичную тему здесь: Есть ли пример JSON Web Token (JWT) на С#?
web-token-jwt-example-in-c, но я до сих пор не добился успеха.
Кулак всего, я создал заголовок и требование (это точно так же, как в документации Google)
var header: String = GetJWTHeader();
var claimset: String = GetJWTClaimSet();
Результат (для ясности выделены новыми строками):
{ "ALG": "RS256", "тип": "JWT" }
{ "ИСС": "425466719070-1dg2rebp0a8fn9l02k9ntr6u5o4a8lp2.apps.googleusercontent.com",
"scope": " https://www.googleapis.com/auth/prediction",
"aud": " https://accounts.google.com/o/oauth2/token",
"ехр": 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
Решение заключалось в том, что в коде запроса все косые черты должны быть обратно сбрасываться
НЕПРАВИЛЬНО:
"scope":"https://www.googleapis.com/auth/prediction",
"aud":"https://accounts.google.com/o/oauth2/token",
ПРАВИЛЬНО:
"scope":"https:\\/\\/www.googleapis.com\\/auth\\/prediction",
"aud":"https:\\/\\/accounts.google.com\\/o\\/oauth2\\/token",
Ответ 2
Я ответил на аналогичный вопрос с предложением очень простой, но рабочей реализации с .NET API OAuth API здесь
Ответ 3
Попробуйте использовать system.identitymodel.tokens.jwt.Net library
Вы можете установить его из NuGet.
См. Пример в моем сообщении здесь (я использовал его для аутентификации сервера websockets, но обработка JWT является общей)
http://mydevtricks.blogspot.co.il/2014/10/xsocketsnet-authentication-with-jwt.html