GoogleSmarthome JWT Создание - PullRequest
       67

GoogleSmarthome JWT Создание

0 голосов
/ 06 апреля 2020

Документация находится на Использование OAuth 2.0 для серверных приложений В документации вы заметите заявление об отказе от ответственности "не делайте этого, но используйте библиотеки". К сожалению, похоже, что нет. Net Core библиотек, и я предложил руководителям программ Smarthome, что поддержка. Net Core должна быть такой же, как и для Java, node.js и Python.

Тем не менее, я села на корточки, социально отстранена и у меня есть немного свободного времени, поэтому я попробовала. Здесь много движущихся частей, но для начала я скачал файл p12 вместо файла JSON (как указано в документации) для консоли Google для учетной записи.

Код:

using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace MakeJWTTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string token = MakeJwt();
            Console.WriteLine();
            Console.WriteLine("The Final JWT: " + token );

        }

        public static string MakeJwt()
        {
            string jwt = string.Empty;
            string iss = "XXXXXXXXXXXXXXX-v2.iam.gserviceaccount.com";
            string scope = "https://www.googleapis.com/auth/homegraph";
            string aud = "https://oauth2.googleapis.com/token";
            string exp = EpochExpiration();
            string iat = EpochCurrentTime();
            string jwtHeader = "{\"alg\":\"RS256\",\"typ\":\"JWT\"}";

            Console.WriteLine("iss: " + iss);
            Console.WriteLine("scope: " + scope);
            Console.WriteLine("aud: " + aud);
            Console.WriteLine("exp: " + exp);
            Console.WriteLine("iat: " + iat);
            Console.WriteLine("JWT Header: " + jwtHeader);


            string claim = "{\"iss\": \"" + iss + "\",\"scope\": \"" + scope + "\",\"aud\": \"" + aud + "\",\"exp\": " +
                exp + ",\"iat\": " + iat + "}";



            var encodedHeader = Base64UrlEncoder.Encode(jwtHeader);
            Console.WriteLine("Encoded JWT Header: " + encodedHeader);
            var encodedClaim = Base64UrlEncoder.Encode(claim);

            string claimSet = encodedHeader + "." + encodedClaim;
            string sig = Sign(claimSet);
            jwt = claimSet + '.' + sig;
            return jwt;
        }

        public static string EpochExpiration()
        {
            DateTime epoch = DateTime.UnixEpoch;
            DateTime now = DateTime.UtcNow;
            DateTime expiration = now.AddMinutes(60);
            TimeSpan secondsSinceEpoch = expiration.Subtract(epoch);
            return secondsSinceEpoch.TotalSeconds.ToString().Substring(0, 10);
        }

        public static string EpochCurrentTime()
        {
            DateTime epoch = DateTime.UnixEpoch;
            DateTime now = DateTime.UtcNow;          
            TimeSpan secondsSinceEpoch = now.Subtract(epoch);
            return secondsSinceEpoch.TotalSeconds.ToString().Substring(0, 10);
        }

        public static string Sign( string toSHA256)
        {
            try
            {

                byte[] data = Encoding.ASCII.GetBytes(toSHA256);

               var certificate = new X509Certificate2(@"XXXXXXXXXXXXXXX-v2-6790af22aa27.p12", "notasecret", X509KeyStorageFlags.Exportable);


                RSACryptoServiceProvider key = new RSACryptoServiceProvider();
                //  byte[] key = certificate.PrivateKey.ExportPkcs8PrivateKey();
                key.FromXmlString(certificate.PrivateKey.ToXmlString(true));



                //Sign the data
                byte[] sig = key.SignData(data, CryptoConfig.MapNameToOID("SHA256"));

                return Base64UrlEncoder.Encode(sig);

            }
            catch { Exception e;  return null; }
        }

    }  
}

Запустите эту программу, и я получу:

scope: https://www.googleapis.com/auth/homegraph
aud: https://oauth2.googleapis.com/token
exp: 1586193162
iat: 1586189562
JWT Header: {"alg":"RS256","typ":"JWT"}
Encoded JWT Header: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9

The Final JWT: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiAibGltaXRlZG1vYmlsaXR5djJAbGltaXRlZC1tb2JpbGl0eS1zb2x1dGlvbnMtdjIuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iICJzY29wZSI6ICJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9hdXRoL2hvbWVncmFwaCJhdWQiOiAiaHR0cHM6Ly9vYXV0aDIuZ29vZ2xlYXBpcy5jb20vdG9rZW4iZXhwIjogIjE1ODYxOTMxNjIiaWF0IjogMTU4NjE4OTU2Mg.ZOX93iUhirtH2tf95XzLYrGIbTK8kABipfVa6DnD-sAe3WcRfLmLVIAybtHTHxC8frCuZtCeS4XMT-EC69kLy-ks5BWFTnaRwm0TfIeNzIVrGfJUVRchvaJLFM9-wX6svVa4fGHMp8pKttO22BI3sIEisxXx2tw6Ge_8QRZXjSCXD0rg5P-0S-pnd8omkgPv_PhhALqcwd9RTUpcAqcMDoyP7ZxpBSMt1EwySixctKz2y4sRCGC8xaxp5E5VnH3liz3xTNMY5QRNX-tMxVIunh0Qp9v7bkuuvnhrwbcjRPq9qTKlhfIQBmZvaA5-9hzJZOiWWHmCunMec1pZp0bAgQ

Press any key to close this window . . . 

Затем я запускаю это из Powershell, используя curl:

.\curl -d 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.RZVpzWygMLuL-n3GwjW1_yhQhrqDacyvaXkuf8HcJl8EtXYjGjMaW5oiM5cgAaIorrqgYlp4DPF_GuncFqg9uDZrx7pMmCZ_yHfxhSCXru3gbXrZvAIicNQZMFxrEEn4REVuq7DjkTMyCMGCY1dpMa8aWfTQFt3Eh7smLchaZsU' https://oauth2.googleapis.com/token

, который возвращает:

{"error":"invalid_grant","error_description":"Invalid grant: account not found"}

Здесь может быть что-то не так. Любые мысли приветствуются.

1 Ответ

0 голосов
/ 07 апреля 2020

В коде было две ошибки:

  1. Строка JSON
                       claim = "{\"iss\": \"" + iss + "\",\"scope\": \"" + scope + 
                               "\",\"aud\": \"" + aud + "\",\"exp\": " +
                               exp + ",\"iat\": " + iat + "}";
DateTime должен быть UT C

И теперь он работает.

...